9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit e6db1423cfee218ed5284e98ee5f0a58d88fe6f1
parent e5d4466e176adf5273a24d660c10d5b36aad4893
Author: Roberto E. Vargas Caballero <roberto.vargas@midokura.com>
Date:   Thu, 17 Nov 2022 18:13:39 +0100

os9: keep proc always locked

Proc has to be accessed continously and it does not make sense
to try to keep it unlocked because we will have to lock it
everywhere.
os9: Remove global namespace

At the beginning we have only a global namespace
but we want to have a namespace per process, so
we have to remove the global variables from dev.c

Diffstat:
Minclude/os9/os9.h | 24+++++++++++++++++-------
Msrc/os9/dev/dev.c | 18+++++++++++-------
Msrc/os9/dev/devproc.c | 4++--
Msrc/os9/proc.c | 186++++++++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/os9/sys.c | 2+-
5 files changed, 120 insertions(+), 114 deletions(-)

diff --git a/include/os9/os9.h b/include/os9/os9.h @@ -157,6 +157,19 @@ struct mpoint { mutex_t m; }; + +struct nspace { + Ref ref; + mutex_t m; + struct mpoint mpoints[NR_MPOINTS]; +}; + +struct fdset { + Ref ref; + mutex_t m; + Chan fdset[NR_CHANS]; +}; + /** * @entry: Entry point for the task. * @prio: @@ -215,19 +228,14 @@ struct task { Map *data; Map stack; Map kstack; + Nspace *ns; Fdset *fds; + Chan slash; Task *next; }; -struct win { - int wid; - long offset; - long duration; - int pid; -}; - /* proc.c */ extern void iproc(void); extern void initref(Ref *); @@ -239,6 +247,8 @@ extern int mapseg(Map *); extern Task *kproc(void *); extern Map *newstack(Task *); extern void sched(void); +extern void locktask(Task *); +extern void unlocktask(Task *); /* alloc.c */ extern void *alloc(size_t); diff --git a/src/os9/dev/dev.c b/src/os9/dev/dev.c @@ -19,9 +19,6 @@ * The use of mutexes is then transparent for the drivers. */ -static Chan fdset[NR_CHANS]; -static Chan slash; -static struct mpoint mpoints[NR_MPOINTS]; int sameqid(Qid q1, Qid q2) @@ -32,8 +29,9 @@ sameqid(Qid q1, Qid q2) Chan * newchan(unsigned char type) { - Chan *c = NULL; int i; + Chan *c = NULL; + Chan *fdset = proc->fds->fdset; for (i = 0; i < NR_CHANS; i++) { c = &fdset[i]; @@ -66,13 +64,14 @@ static Chan * fd2chan(int fd) { Chan *c; + Chan *fdset = proc->fds->fdset; if (fd < 0 || fd >= NR_CHANS) goto badfd; c = &fdset[fd]; lock(&c->mutex); - if (fdset[fd].type == NODEV) + if (c->type == NODEV) goto ubadfd; return c; @@ -86,6 +85,8 @@ badfd: static int chan2fd(Chan *c) { + Chan *fdset = proc->fds->fdset; + return (c == NULL) ? -1 : (c - fdset); } @@ -168,6 +169,7 @@ mntpoint(int type, Qid qid) { Chan *cn; struct mpoint *mp; + struct mpoint *mpoints = proc->ns->mpoints; for (mp = mpoints; mp < &mpoints[NR_MPOINTS]; mp++) { lock(&mp->m); @@ -223,7 +225,7 @@ namec(char *name, int mode) c = NULL; switch (name[0]) { case '/': - c = clone(&slash, NULL); + c = clone(&proc->slash, NULL); s = name; break; case '#': @@ -646,6 +648,7 @@ addmntpoint(Chan *c, char *new) int i; Chan *cn; struct mpoint *mp; + struct mpoint *mpoints = proc->ns->mpoints; if ((cn = namec(new, O_READ)) == NULL) goto err0; @@ -726,6 +729,7 @@ void idev(void) { Chan *c; + Chan *fdset = proc->fds->fdset; for (c = fdset; c < &fdset[NR_CHANS]; c++) c->type = NODEV; @@ -733,7 +737,7 @@ idev(void) if ((c = attach('/', 0)) == NULL) panic("idev:attach"); - if (!clone(c, &slash)) + if (!clone(c, &proc->slash)) panic("idev:clone"); delchan(c); diff --git a/src/os9/dev/devproc.c b/src/os9/dev/devproc.c @@ -50,7 +50,7 @@ procfsgen(Chan *c, int n, Dir *dir) nam, 0, QID(CHDIR, 0, PATH(Qtaskdir, tp->pid)), O_READ); - unlock(&tp->m); + unlocktask(tp); return 1; } } @@ -110,7 +110,7 @@ taskattrread(Chan *c, void *buf, int n) tp->period, tp->capacity, tp->deadline); - unlock(&tp->m); + unlocktask(tp); if (len == sizeof(tmp)) panic("temporary buffer too short"); diff --git a/src/os9/proc.c b/src/os9/proc.c @@ -5,18 +5,6 @@ #include <libk.h> -struct nspace { - Ref ref; - mutex_t m; - struct mpoint mpoints[NR_MPOINTS]; -}; - -struct fdset { - Ref ref; - mutex_t m; - Chan fdset[NR_CHANS]; -}; - static Task tasktab[NR_TASKS]; static mutex_t procm; @@ -25,27 +13,6 @@ Task *proc; long long now; int cpuid; -static void -initfn(void) -{ - debug(); -} - -void -iproc(void) -{ - Task *tp; - - for (tp = tasktab; tp < &tasktab[NR_TASKS]; ++tp) { - tp->pid = tp->ppid = -1; - tp->state = TFREE; - } - - if ((tp = kproc(initfn)) == NULL) - panic("init task failed"); - proc = tp; -} - void initref(Ref *rp) { @@ -73,6 +40,20 @@ decref(Ref *rp) return r; } +void +locktask(Task *tp) +{ + if (tp != proc) + lock(&tp->m); +} + +void +unlocktask(Task *tp) +{ + if (tp != proc) + unlock(&tp->m); +} + int getntask(int n, Task **tpp) { @@ -84,9 +65,9 @@ getntask(int n, Task **tpp) } tp = &tasktab[n]; - lock(&tp->m); + locktask(tp); if (tp->state == TFREE) { - unlock(&tp->m); + unlocktask(tp); return 0; } @@ -102,12 +83,12 @@ gettask(int pid) tp = NULL; lock(&procm); for (p = tasktab; p < &tasktab[NR_TASKS]; ++p) { - lock(&p->m); + locktask(p); if (p->pid == pid && p->state != TFREE) { tp = p; break; } - unlock(&p->m); + unlocktask(p); } unlock(&procm); @@ -200,10 +181,10 @@ newslot(void) lock(&procm); for (tp = tasktab; tp < &tasktab[NR_TASKS]; tp++) { - lock(&tp->m); + locktask(tp); if (tp->state == TFREE) break; - unlock(&tp->m); + unlocktask(tp); } unlock(&procm); @@ -237,7 +218,7 @@ newtask(void) goto err; if ((tp = gettask(pid)) == NULL) break; - unlock(&tp->m); + unlocktask(tp); } if ((tp = newslot()) == NULL) @@ -337,8 +318,6 @@ clone(Task *parent) if (!initptable(tp) || !newstack(tp)) goto err; - lock(&parent->m); - tp->ppid = parent->pid; tp->entry = parent->entry; @@ -377,12 +356,10 @@ clone(Task *parent) if (tp->fds) incref(&parent->fds->ref); - unlock(&parent->m); - return tp; err: - unlock(&tp->m); + unlocktask(tp); deltask(tp); return NULL; } @@ -417,13 +394,6 @@ rfork(int flags) if (dupctx(tp) == 0) return 0; } - - /* - * TODO: We cannot lock proc before clone because it calls - * newtask that cannot be called with locked tasks. If we - * create a list of free tasks then we can simplify it. - */ - lock(&proc->m); if ((flags & RFCNAMEG) != 0) { if ((ns = newspace(NULL)) == NULL) goto err; @@ -461,9 +431,8 @@ rfork(int flags) tp->data = data; } - unlock(&proc->m); if (flags & RFPROC) - unlock(&tp->m); + unlocktask(tp); return 0; @@ -476,7 +445,7 @@ err: freespace(ns); if (flags & RFPROC) { - unlock(&tp->m); + unlocktask(tp); deltask(tp); } @@ -486,40 +455,7 @@ err: Task * kproc(void *fn) { - Task *tp; - - if ((tp = newtask()) == NULL) - return NULL; - - tp->text = NULL; - tp->data = NULL; - tp->fds = NULL; - tp->ns = NULL; - - tp->entry = fn; - - tp->prio = 0; - tp->baseprio = 0; - tp->retainprio = 0; - - tp->wait = 0; - tp->locklevel = 0; - tp->affinity = -1; - - tp->period = 0; - tp->duration = 0; - tp->capacity = 0; - - tp->deadline = 0; - tp->deadtime = 0; - - tp->flags = 0; - tp->state = TREADY; - - ictx(tp, fn); - unlock(&tp->m); - - return tp; + return NULL; } void @@ -529,22 +465,20 @@ sched(void) int prio; long long wait, mask; - lock(&proc->m); if (proc->state == TRUNNING) { - if (proc->flags&TLOCK_PREEMP) { - unlock(&proc->m); + if (proc->flags&TLOCK_PREEMP) swtch(&proc->ctx); - } proc->state = TREADY; } unlock(&proc->m); repeat: - lock(&procm); new = NULL; prio = -1; wait = -1; mask = 1ul << cpuid; + + lock(&procm); for (tp = tasktab; tp < &tasktab[NR_TASKS]; ++tp) { lock(&tp->m); @@ -568,10 +502,68 @@ repeat: proc = new; lock(&proc->m); - unlock(&procm); - proc->state = TRUNNING; - unlock(&proc->m); + unlock(&procm); swtch(&proc->ctx); } + +static void +initfn(void) +{ + debug(); +} + +static Task * +inittask(void) +{ + Task *tp; + + if ((tp = newtask()) == NULL) + return NULL; + tp->pid = 0; + + tp->text = NULL; + tp->data = NULL; + tp->fds = newfds(NULL); + tp->ns = newspace(NULL); + + tp->entry = initfn; + + tp->prio = 0; + tp->baseprio = 0; + tp->retainprio = 0; + + tp->wait = 0; + tp->locklevel = 0; + tp->affinity = -1; + + tp->period = 0; + tp->duration = 0; + tp->capacity = 0; + + tp->deadline = 0; + tp->deadtime = 0; + + tp->flags = 0; + tp->state = TREADY; + + ictx(tp, initfn); + + return tp; +} + +void +iproc(void) +{ + Task *tp; + + for (tp = tasktab; tp < &tasktab[NR_TASKS]; ++tp) { + tp->pid = tp->ppid = -1; + tp->state = TFREE; + } + + if ((tp = inittask()) == NULL) + panic("init task failed"); + proc = tp; +} diff --git a/src/os9/sys.c b/src/os9/sys.c @@ -114,9 +114,9 @@ info(void) void isys(void) { + iproc(); idev(); iconf(); icons(); - iproc(); sched(); }