9os

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

commit 55f6f3f74765b79a4fba792c4aa762492cc5d3b0
parent 095df6c445c490f1b6f0af2f0e91b58bece9c1a8
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 20 Oct 2020 22:29:24 +0200

os9: Unify Proc and task

The difference between a process and a task was creating different
problems and it is much better to unify them.

Change-Id: I70f2c3288d56120dfa834c8674c7c9d6c875e454

Diffstat:
Minclude/os9/os9.h | 44+++++++++++++++++---------------------------
Msrc/os9/dev/dev.c | 12+++++++++---
Msrc/os9/dev/devar.c | 2+-
Msrc/os9/dev/devproc.c | 139+++++--------------------------------------------------------------------------
Msrc/os9/sched.c | 154++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
5 files changed, 133 insertions(+), 218 deletions(-)

diff --git a/include/os9/os9.h b/include/os9/os9.h @@ -131,6 +131,7 @@ struct dir { struct chan { long offset; + int index; Qid qid; unsigned char type; unsigned char dev; @@ -142,56 +143,47 @@ struct task { int tid; int pid; - mutex_t m; char *name; void *entry; + int prio; int baseprio; int retainprio; + int wait; + int locklevel; + unsigned long affinity; long period; + long duration; long capacity; long deadline; long deadtime; int state; - unsigned long affinity; int flags; - Map text; - Map data; - Map stack; - Context ctx; -}; + int mode; + int start; -struct proc { - int pid; + mutex_t m; - char *name; - /* memory requirements */ - long period; - long duration; /* communication ports */ /* healt monitor table */ - unsigned long affinity; + /* Task *errhdl; */ - void *entry; - long flags; - int locklevel; - int mode; - int start; - - Task tasks[NR_TASKS]; - Task *errhdl; + Map text; + Map data; + Map stack; + Context ctx; }; struct win { int wid; long offset; long duration; - Proc *proc; + int pid; }; /* alloc.c */ @@ -231,10 +223,8 @@ extern int devread(Chan *c, void *buf, int n); extern int devclose(Chan *c); /* sched.c */ -extern Proc *getproc(int); -extern Proc *getnproc(int); -extern Task *getntask(Proc *, int); -extern Task *gettask(Proc *, int); +extern int getntask(int n, Task **tpp); +extern Task *gettask(int tid); extern void sched(void); /* globals */ diff --git a/src/os9/dev/dev.c b/src/os9/dev/dev.c @@ -65,6 +65,7 @@ delchan(Chan *c) c->qid = QID(0, 0, 0); c->dev = 0; c->offset = 0; + c->index = 0; c->type = NODEV; unlock(&c->mutex); } @@ -307,8 +308,9 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) for (i = 0; ; i++) { switch ((*gen)(c, tab, ntab, i, &dir)) { case 0: - errno = ENOENT; + continue; case -1: + errno = ENOENT; return -1; case 1: if (strcmp(name, dir.name)) @@ -329,15 +331,19 @@ dirread(Chan *c, Dir dir; cnt = 0; - for (i = c->offset/DIRLEN; nbytes >= DIRLEN; i++) { + for (i = c->index; nbytes >= DIRLEN; i++) { switch ((*gen)(c, tab, ntab, i, &dir)) { case 0: - return cnt; + continue; case -1: return (cnt > 0) ? cnt : -1; case 1: c->offset += DIRLEN; n = dirtop9(&dir, buf + cnt, nbytes); + if (n < 0) { + errno = EINVAL; + return (cnt > 0) ? cnt : -1; + } nbytes -= n; cnt += n; } diff --git a/src/os9/dev/devar.c b/src/os9/dev/devar.c @@ -74,7 +74,7 @@ argen(Chan *c, Dirtab *tab, int ntab, int n, Dir *dir) for (i = 0; i <= n; i++) { if (ar->offset[i] == -1) - return 0; + return -1; off = ar->offset[i]; if (devtab[c->type]->seek(&nc, off, SEEK_SET) < 0) return -1; diff --git a/src/os9/dev/devproc.c b/src/os9/dev/devproc.c @@ -3,32 +3,21 @@ #include "dev.h" -#define PATH(b, p, t) \ +#define PATH(b, t) \ ((unsigned long long) (b) << 32 | \ - (unsigned long long) (p) << 16 | \ (unsigned long long) (t)) #define TYPE(q) (((q.path) >> 32) & 0xFF) -#define PROC(q) (((q.path) >> 16) & 0xFFFF) -#define TASK(q) ((q.path) & 0xFFFF) +#define TASK(q) ((q.path) & 0xFFFFFFFF) enum procqid { Qprocfs, - Qprocdir, Qtaskdir, - Qprocattr, - Qprocstatus, - Qproctask, Qtaskattr, Qtaskstatus, }; -static Dirtab procdirtab[] = { - {"attr", QID(CHFILE, 0, Qprocattr), 0, O_READ}, - {"status", QID(CHFILE, 0, Qprocstatus), 0, O_READ}, -}; - static Dirtab tasktab[] = { {"attr", QID(CHFILE, 0, Qtaskattr), 0, O_READ}, {"status", QID(CHFILE, 0, Qtaskstatus), 0, O_READ}, @@ -37,46 +26,17 @@ static Dirtab tasktab[] = { static int procfsgen(Chan *c, Dirtab *tab, int ntab, int n, Dir *dir) { - Proc *p; - char nam[NAMELEN]; - - if ((p = getnproc(n)) == NULL) - return 0; - - ksnprint(nam, NAMELEN, "%d", p->pid); - mkentry(c, dir, - nam, 0, - QID(CHDIR, 0, PATH(Qprocdir, p->pid, 0)), - O_READ); - - return 1; -} - -static int -procdirgen(Chan *c, Dirtab *tab, int ntab, int n, Dir *dir) -{ - Proc *pp; Task *tp; - int r; char nam[NAMELEN]; - if ((pp = getproc(PROC(c->qid))) == NULL) - panic("procdirgen"); - - r = devgen(c, procdirtab, NELEM(procdirtab), n, dir); - if (r) { - dir->qid.path = PATH(dir->qid.path, pp->pid, 0); - return 1; - } - - n -= NELEM(procdirtab); - if ((tp = getntask(pp, n)) == NULL) + n = getntask(n, &tp); + if (n <= 0) return 0; ksnprint(nam, NAMELEN, "%d", tp->tid); mkentry(c, dir, nam, 0, - QID(CHDIR, 0, PATH(Qtaskdir, pp->pid, tp->tid)), + QID(CHDIR, 0, PATH(Qtaskdir, tp->tid)), O_READ); return 1; @@ -85,12 +45,11 @@ procdirgen(Chan *c, Dirtab *tab, int ntab, int n, Dir *dir) static int taskgen(Chan *c, Dirtab *tab, int ntab, int n, Dir *dir) { - int pid = PROC(c->qid); int tid = TASK(c->qid); if (!devgen(c, tasktab, NELEM(tasktab), n, dir)) return 0; - dir->qid.path = PATH(dir->qid.path, pid, tid); + dir->qid.path = PATH(dir->qid.path, tid); return 1; } @@ -101,8 +60,6 @@ procgen(Chan *c, Dirtab *tab, int ntab, int n, Dir *dir) switch (TYPE(c->qid)) { case Qprocfs: return procfsgen(c, tab, ntab, n, dir); - case Qprocdir: - return procdirgen(c, tab, ntab, n, dir); case Qtaskdir: return taskgen(c, tab, ntab, n, dir); default: @@ -117,84 +74,13 @@ procwalk(Chan *c, char *name) } static int -procattrread(Chan *c, void *buf, int n) -{ - int len; - Proc *pp; - char tmp[1024]; - - if ((pp = getproc(PROC(c->qid))) == NULL) - panic("procattrread:getproc"); - - len = ksnprint(tmp, - sizeof(tmp), - "name: %s\n" - "pid: %d\n" - "period: %ld\n" - "duration: %ld\n" - "affinity: %lx\n" - "entry: %p\n" - "system: %s\n", - pp->name, - pp->pid, - pp->period, - pp->duration, - pp->affinity, - pp->entry, - (pp->flags & PSYSTEM) ? "yes" : "no"); - - if (len == sizeof(tmp)) - panic("procattrread:len"); - return buf2chan(c, buf, tmp, n, len); -} - -static int -procstatusread(Chan *c, void *buf, int n) -{ - int len; - Proc *pp; - static char *modes[] = { - [PDISABLED] = "disabled", - [PCOLD_START] = "cold_start", - [PWARM_START] = "warm_boot", - [PIDLE] = "idle", - [PNORMAL] = "normal", - }; - static char *starts[] = { - [SNORMAL] = "normal", - }; - char tmp[1024]; - - if ((pp = getproc(PROC(c->qid))) == NULL) - panic("procstatusread:getproc"); - - len = ksnprint(tmp, - sizeof(tmp), - "locklevel: %d\n" - "mode: %s\n" - "start: %s\n" - "ehandler: %p\n", - pp->locklevel, - modes[pp->mode], - starts[pp->start], - pp->errhdl); - - if (len == sizeof(tmp)) - panic("procstatusread:len"); - return buf2chan(c, buf, tmp, n, len); -} - -static int taskattrread(Chan *c, void *buf, int n) { int len; - Proc *pp; Task *tp; char tmp[1024]; - if ((pp = getproc(PROC(c->qid))) == NULL) - panic("bad process"); - if ((tp = gettask(pp, TASK(c->qid))) == NULL) + if ((tp = gettask(TASK(c->qid))) == NULL) panic(""); len = ksnprint(tmp, @@ -225,7 +111,6 @@ static int taskstatusread(Chan *c, void *buf, int n) { int len; - Proc *pp; Task *tp; char tmp[1024]; static char *states[] = { @@ -236,10 +121,7 @@ taskstatusread(Chan *c, void *buf, int n) [FAULTED] = "faulted", }; - if ((pp = getproc(PROC(c->qid))) == NULL) - panic("taskstatusread:getproc"); - - if ((tp = gettask(pp, TASK(c->qid))) == NULL) + if ((tp = gettask(TASK(c->qid))) == NULL) panic("taskstatusread:gettask"); len = ksnprint(tmp, @@ -267,13 +149,8 @@ procread(Chan *c, void *buf, int n) { switch (TYPE(c->qid)) { case Qprocfs: - case Qprocdir: case Qtaskdir: return dirread(c, buf, n, NULL, 0, procgen); - case Qprocattr: - return procattrread(c, buf, n); - case Qprocstatus: - return procstatusread(c, buf, n); case Qtaskattr: return taskattrread(c, buf, n); case Qtaskstatus: diff --git a/src/os9/sched.c b/src/os9/sched.c @@ -1,88 +1,130 @@ #include <os9/os9.h> -Proc proctab[NR_PROCS] = { - [0] = { - .pid = 1, - .name = "init", - .period = 20, - .duration = 4, - .affinity = -1, - .mode = PCOLD_START, - }, - [1] = { - .pid = 2, - .name = "/bin/sh", - .period = 20, - .duration = 4, - .affinity = -1, - .mode = PCOLD_START, - }, -}; +#include <errno.h> -Win wintab[NR_WINS]; +static Task tasktab[NR_TASKS]; +static Win wintab[NR_WINS]; /* per cpu globals */ -Proc *proc; Task *task; long long now; int cpuid; -Proc * -getnproc(int n) +int +getntask(int n, Task **tpp) { - Proc *pp; + Task *tp; - for (pp = proctab; pp < &proctab[NR_PROCS]; ++pp) { - if (pp->mode == PDISABLED) - continue; - if (n == 0) - return pp; - n--; - } + if (n >= NR_TASKS) + return -1; + tp = &tasktab[n]; - return NULL; + if (tp->mode == PDISABLED) + return 0; + + *tpp = tp; + return 1; } -Proc * -getproc(int pid) +Task * +gettask(int tid) { - Proc *pp; + Task *tp; - for (pp = proctab; pp < &proctab[NR_PROCS]; ++pp) { - if (pp->mode != PDISABLED && pp->pid == pid) - return pp; + for (tp = tasktab; tp < &tasktab[NR_PROCS]; ++tp) { + if (tp->mode != PDISABLED && tp->tid == tid) + return tp; } return NULL; } -Task * -getntask(Proc *pp, int n) +#if 0 + +enum rforkflags { + RFPROC = 1 << 0, +}; + +int +rfork(int flags) { - Task *tp, *tasks = pp->tasks; + Proc *p = proc; - for (tp = tasks; tp < &tasks[NR_TASKS]; ++tp) { - if ((tp->flags & TENABLED) == 0) - continue; - if (n == 0) - return tp; - n--; - } + if ((flags & RFPROC) == 0) { + p = proc; + } else { + for (p = tasktab; p < &tasktab[NR_PROCS]; ++p) { + if (p->mode == PDISABLED) + break; + } - return NULL; + if (p == &tasktab[NR_PROCS]) { + errno = ENOMEM; + return -1; + } + } } -Task * -gettask(Proc *pp, int tid) + +void +sched(void) { - Task *tp, *tasks = pp->tasks; + Task *new, *tp, **p, **tasks; + int prio; + long long wait, mask; + static mutex_t m; + + lock(&m); + new = proc->errhdl; + if (new && new->state == READY) + goto found; + + new = task; + if (task->mode == RUNNING && task->flags&LOCK_PREEMP) + goto found; - for (tp = tasks; tp < &tasks[NR_TASKS]; ++tp) { - if ((tp->flags & TENABLED) != 0) + tasks = proc->tasks; + prio = -1; + wait = -1; + mask = 1ul << cpuid; + for (p = tasks; p < &tasks[NR_TASKS]; ++p) { + tp = p; + + if (tp->mode != READY + || (tp->affinity & mask) == 0 + || tp->prio < prio + || tp->prio == prio && new->wait <= wait) { continue; - if (tp->tid == tid) - return tp; + } + + new = tp; + prio = tp->prio; + wait = tp->wait; } - return NULL; +found: + if (cur->mode == RUNNIG) + cur->mode = READY; + cur->wait = now; + cur = new; + cur->mode = RUNNING; + unlock(&m); + + swtch(&cur->ctx); +} + +void +minframe(void) +{ + static Win *wp = &wintab[0]; + + if (++wp == &wintab[nr_wins]) + wp = wintab; + + proc = wp->proc; + cur = idle; + mmap(proc); + + sched(); } +#endif