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:
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