M port/devcons.c => port/devcons.c +25 -20
@@ 325,50 325,52 @@ consactive(void)
}
enum{
- Qdir,
+ Qchal,
+ Qclock,
Qcons,
Qconsctl,
Qcputime,
+ Qcrypt,
+ Qdir,
+ Qkey,
+ Qklog,
Qlights,
+ Qmsec,
Qnoise,
+ Qnoteid,
Qnull,
Qpgrpid,
Qpid,
Qppid,
- Qtime,
- Quser,
- Qklog,
- Qmsec,
- Qclock,
- Qsysstat,
Qswap,
- Qcrypt,
- Qkey,
- Qchal,
Qsysname,
+ Qsysstat,
+ Qtime,
+ Quser,
};
Dirtab consdir[]={
+ "chal", {Qchal}, 8, 0666,
+ "clock", {Qclock}, 2*NUMSIZE, 0444,
"cons", {Qcons}, 0, 0660,
"consctl", {Qconsctl}, 0, 0220,
"cputime", {Qcputime}, 6*NUMSIZE, 0444,
- "time", {Qtime}, NUMSIZE, 0664,
- "clock", {Qclock}, 2*NUMSIZE, 0444,
- "msec", {Qmsec}, NUMSIZE, 0444,
+ "crypt", {Qcrypt}, 0, 0666,
+ "key", {Qkey}, DESKEYLEN, 0622,
+ "klog", {Qklog}, 0, 0444,
"lights", {Qlights}, 0, 0220,
+ "msec", {Qmsec}, NUMSIZE, 0444,
"noise", {Qnoise}, 0, 0220,
+ "noteid", {Qnoteid}, NUMSIZE, 0444,
"null", {Qnull}, 0, 0666,
"pgrpid", {Qpgrpid}, NUMSIZE, 0444,
"pid", {Qpid}, NUMSIZE, 0444,
"ppid", {Qppid}, NUMSIZE, 0444,
- "user", {Quser}, 0, 0666,
- "chal", {Qchal}, 8, 0666,
- "crypt", {Qcrypt}, 0, 0666,
- "key", {Qkey}, DESKEYLEN, 0622,
- "klog", {Qklog}, 0, 0444,
- "sysstat", {Qsysstat}, 0, 0666,
- "sysname", {Qsysname}, 0, 0664,
"swap", {Qswap}, 0, 0664,
+ "sysname", {Qsysname}, 0, 0664,
+ "sysstat", {Qsysstat}, 0, 0666,
+ "time", {Qtime}, NUMSIZE, 0664,
+ "user", {Quser}, 0, 0666,
};
#define NCONS (sizeof consdir/sizeof(Dirtab))
@@ 570,6 572,9 @@ consread(Chan *c, void *buf, long n, ulong offset)
case Qpgrpid:
return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE);
+ case Qnoteid:
+ return readnum(offset, buf, n, u->p->noteid, NUMSIZE);
+
case Qpid:
return readnum(offset, buf, n, u->p->pid, NUMSIZE);
M port/devproc.c => port/devproc.c +10 -29
@@ 42,17 42,18 @@ char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys" };
* 23 bits of process slot number + 1
* in vers,
* 32 bits of pid, for consistency checking
- * If notepg, c->pgrpid.path is pgrp slot, .vers is pgrpid.
+ * If notepg, c->pgrpid.path is pgrp slot, .vers is noteid.
*/
#define NPROC (sizeof procdir/sizeof(Dirtab))
#define QSHIFT 4 /* location in qid of proc slot # */
-#define QID(q) (((q).path&0x0000000F)>>0)
-#define SLOT(q) ((((q).path&0x07FFFFFF0)>>QSHIFT)-1)
-#define PID(q) ((q).vers)
+
+#define QID(q) (((q).path&0x0000000F)>>0)
+#define SLOT(q) ((((q).path&0x07FFFFFF0)>>QSHIFT)-1)
+#define PID(q) ((q).vers)
+#define NOTEID(q) ((q).vers)
void procctlreq(Proc*, char*, int);
int procctlmemio(Proc*, ulong, int, void*, int);
-Chan *procctlnotepg(Chan*, void*, int);
Chan *proctext(Chan*, Proc*);
Segment *txt2data(Proc*, Segment*);
int procstopped(void*);
@@ 171,7 172,7 @@ procopen(Chan *c, int omode)
if(omode!=OWRITE || pg->pgrpid==1) /* easy to do by mistake */
error(Eperm);
c->pgrpid.path = pg->index+1;
- c->pgrpid.vers = pg->pgrpid;
+ c->pgrpid.vers = p->noteid;
break;
default:
pprint("procopen %lux\n", c->qid);
@@ 386,9 387,9 @@ procwrite(Chan *c, void *va, long n, ulong offset)
p = proctab(SLOT(c->qid));
- /* Use the remembered pgrp id in the channel rather than the process pgrpid */
- if(QID(c->qid) == Qnotepg){
- procctlnotepg(c, va, n);
+ /* Use the remembered noteid in the channel rather than the process pgrpid */
+ if(QID(c->qid) == Qnotepg) {
+ pgrpnote(NOTEID(c->pgrpid), va, n, NUser);
return n;
}
@@ 509,26 510,6 @@ proctext(Chan *c, Proc *p)
return tc;
}
-Chan *
-procctlnotepg(Chan *c, void *va, int n)
-{
- Pgrp *pg;
-
- pg = pgrptab(c->pgrpid.path-1);
- qlock(&pg->debug);
- if(waserror()){
- qunlock(&pg->debug);
- nexterror();
- }
- if(pg->pgrpid != c->pgrpid.vers){
- qunlock(&pg->debug);
- error(Eprocdied);
- }
- pgrpnote(pg, va, n, NUser);
- poperror();
- qunlock(&pg->debug);
-}
-
void
procstopwait(Proc *p, int ctl)
{
M port/pgrp.c => port/pgrp.c +9 -6
@@ 74,21 74,24 @@ pgrptab(int i)
}
void
-pgrpnote(Pgrp *pg, char *a, long n, int flag)
+pgrpnote(ulong noteid, char *a, long n, int flag)
{
- int i;
- Proc *p;
+ Proc *p, *ep;
char buf[ERRLEN];
if(n >= ERRLEN-1)
error(Etoobig);
+
memmove(buf, a, n);
buf[n] = 0;
p = proctab(0);
- for(i=0; i<conf.nproc; i++, p++) {
- if(p->pgrp == pg && p->kp == 0) {
+ ep = p+conf.nproc;
+ for(; p < ep; p++) {
+ if(p->state == Dead)
+ continue;
+ if(p->noteid == noteid && p->kp == 0) {
qlock(&p->debug);
- if(p->pid==0 || p->pgrp!=pg){
+ if(p->pid==0 || p->noteid != noteid){
qunlock(&p->debug);
continue;
}
M port/portdat.h => port/portdat.h +12 -4
@@ 458,9 458,15 @@ enum /* Argument to forkpgrp call */
enum
{
- Forkpg = 1,
- Forkeg = 2,
- Forkfd = 4,
+ FORKNSG = (1<<0),
+ FORKEVG = (1<<1),
+ FORKFDG = (1<<2),
+ FORKNTG = (1<<3),
+ FORKPCS = (1<<4),
+ FORKMEM = (1<<5),
+ FORKCNSG = (1<<10),
+ FORKCEVG = (1<<11),
+ FORKCFDG = (1<<12)
};
/*
@@ 522,10 528,11 @@ struct Proc
QLock *qlock; /* address of qlock being queued for DEBUG */
ulong qlockpc; /* pc of last call to qlock */
int state;
- char *psstate; /* What /proc/???/status reports */
+ char *psstate; /* What /proc/#/status reports */
Page *upage; /* BUG: should be unlinked from page list */
Segment *seg[NSEG];
ulong pid;
+ ulong noteid; /* Equivalent of note group */
Lock exl; /* Lock count and waitq */
Waitq *waitq; /* Exited processes wait children */
@@ 696,6 703,7 @@ extern char eve[];
extern int nrdy;
extern char sysname[NAMELEN];
extern int cpuserver;
+extern Ref noteidalloc;
#define CHDIR 0x80000000L
#define CHAPPEND 0x40000000L
M port/portfns.h => port/portfns.h +1 -1
@@ 155,7 155,7 @@ void pageinit(void);
void panic(char*, ...);
void pexit(char*, int);
void pgrpcpy(Pgrp*, Pgrp*);
-void pgrpnote(Pgrp*, char*, long, int);
+void pgrpnote(ulong, char*, long, int);
Pgrp* pgrptab(int);
void pio(Segment *, ulong, ulong, Page **);
#define poperror() u->nerrlab--
M port/proc.c => port/proc.c +3 -1
@@ 6,6 6,7 @@
#include "../port/error.h"
Ref pidalloc;
+Ref noteidalloc;
struct
{
@@ 229,7 230,8 @@ newproc(void)
p->notepending = 0;
memset(p->seg, 0, sizeof p->seg);
p->pid = incref(&pidalloc);
- if(p->pid == 0)
+ p->noteid = incref(¬eidalloc);
+ if(p->pid==0 || p->noteid==0)
panic("pidalloc");
return p;
}
M port/sysproc.c => port/sysproc.c +86 -13
@@ 21,7 21,13 @@ long
sysfork(ulong *arg)
{
USED(arg);
- return rfork(Forkfd);
+ return rfork(FORKFDG|FORKPCS);
+}
+
+long
+sys__rfork__(ulong *arg)
+{
+ return rfork(arg[0]|FORKPCS);
}
/* This call will obsolete fork */
@@ 40,11 46,48 @@ rfork(ulong flag)
int n, on, i;
Chan *c;
KMap *k;
+ Pgrp *opg;
+ Egrp *oeg;
+ Fgrp *ofg;
/*
* used to compute last valid system stack address for copy
*/
int lastvar;
+ p = u->p;
+ if((flag&FORKPCS) == 0) {
+ if(flag & (FORKNSG|FORKCNSG)) {
+ if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
+ error(Ebadarg);
+ opg = p->pgrp;
+ p->pgrp = newpgrp();
+ if(flag & FORKNSG)
+ pgrpcpy(p->pgrp, opg);
+ closepgrp(opg);
+ }
+ if(flag & (FORKEVG|FORKCEVG)) {
+ if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
+ error(Ebadarg);
+ oeg = p->egrp;
+ p->egrp = newegrp();
+ if(flag & FORKEVG)
+ envcpy(p->egrp, oeg);
+ closeegrp(oeg);
+ }
+ if(flag & FORKFDG)
+ error(Ebadarg);
+ if(flag & FORKCFDG) {
+ ofg = p->fgrp;
+ p->fgrp = newfgrp();
+ closefgrp(ofg);
+ }
+ if(flag & FORKNTG)
+ p->noteid = incref(¬eidalloc);
+ if(flag & FORKMEM)
+ error(Ebadarg);
+ return 0;
+ }
+
p = newproc();
/* Page va of upage used as check in mapstack */
@@ 66,30 109,57 @@ rfork(ulong flag)
p->seg[i] = dupseg(u->p->seg[i]);
/* Refs */
- incref(u->dot); /* File descriptors etc. */
+ incref(u->dot);
+
+ if(flag & FORKMEM)
+ error(Egreg);
- if(flag & Forkfd)
- p->fgrp = dupfgrp(u->p->fgrp);
- else{
+ /* File descriptors */
+ if(flag & (FORKFDG|FORKCFDG)) {
+ if((flag & (FORKFDG|FORKCFDG)) == (FORKFDG|FORKCFDG))
+ error(Ebadarg);
+ if(flag & FORKFDG)
+ p->fgrp = dupfgrp(u->p->fgrp);
+ else
+ if(flag & FORKCFDG)
+ p->fgrp = newfgrp();
+ }
+ else {
p->fgrp = u->p->fgrp;
incref(p->fgrp);
}
- if(flag & Forkpg) {
- p->pgrp = newpgrp();
- pgrpcpy(p->pgrp, u->p->pgrp);
+ /* Process groups */
+ if(flag & (FORKNSG|FORKCNSG)) {
+ if((flag & (FORKNSG|FORKCNSG)) == (FORKNSG|FORKCNSG))
+ error(Ebadarg);
+ if(flag & FORKNSG) {
+ p->pgrp = newpgrp();
+ pgrpcpy(p->pgrp, u->p->pgrp);
+ }
+ else
+ if(flag & FORKCNSG)
+ p->pgrp = newpgrp();
}
else {
- p->pgrp = u->p->pgrp; /* Process groups */
+ p->pgrp = u->p->pgrp;
incref(p->pgrp);
}
- if(flag & Forkeg) {
- p->egrp = newegrp();
- envcpy(p->egrp, u->p->egrp);
+ /* Environment group */
+ if(flag & (FORKEVG|FORKCEVG)) {
+ if((flag & (FORKEVG|FORKCEVG)) == (FORKEVG|FORKCEVG))
+ error(Ebadarg);
+ if(flag & FORKEVG) {
+ p->egrp = newegrp();
+ envcpy(p->egrp, u->p->egrp);
+ }
+ else
+ if(flag & FORKCEVG)
+ p->egrp = newegrp();
}
else {
- p->egrp = u->p->egrp; /* Environment group */
+ p->egrp = u->p->egrp;
incref(p->egrp);
}
@@ 111,6 181,8 @@ rfork(ulong flag)
p->parent = u->p;
p->parentpid = u->p->pid;
+ if((flag&FORKNTG) == 0)
+ p->noteid = u->p->noteid;
p->fpstate = u->p->fpstate;
lock(&u->p->exl);
@@ 513,6 585,7 @@ sysforkpgrp(ulong *arg)
u->notified = 0;
memset(u->note, 0, sizeof(u->note));
}
+ u->p->noteid = incref(¬eidalloc);
poperror();
closepgrp(u->p->pgrp);
M port/systab.h => port/systab.h +6 -6
@@ 22,11 22,11 @@ Syscall sysread;
Syscall sysseek;
Syscall syssleep;
Syscall sysstat;
-Syscall sys__wait__;
+Syscall sysrfork;
Syscall syswrite;
Syscall syspipe;
Syscall syscreate;
-Syscall sysrfork;
+Syscall sys__rfork__;
Syscall sysbrk_;
Syscall sysremove;
Syscall syswstat;
@@ 61,11 61,11 @@ Syscall *systab[]={
[SEEK] sysseek,
[SLEEP] syssleep,
[STAT] sysstat,
- [__WAIT__] sys__wait__,
+ [RFORK] sysrfork,
[WRITE] syswrite,
[PIPE] syspipe,
[CREATE] syscreate,
- [RFORK] sysrfork,
+ [__RFORK__] sys__rfork__,
[BRK_] sysbrk_,
[REMOVE] sysremove,
[WSTAT] syswstat,
@@ 101,11 101,11 @@ char *sysctab[]={
[SEEK] "Seek",
[SLEEP] "Sleep",
[STAT] "Stat",
- [__WAIT__] "__wait_",
+ [RFORK] "Rfork",
[WRITE] "Write",
[PIPE] "Pipe",
[CREATE] "Create",
- [RFORK] "Rfork",
+ [__RFORK__] "__rfork_",
[BRK_] "Brk",
[REMOVE] "Remove",
[WSTAT] "Wstat",
M port/taslock.c => port/taslock.c +4 -1
@@ 13,7 13,10 @@ lock(Lock *l)
ulong pc;
pc = getcallerpc(((uchar*)&l) - sizeof(l));
-
+if(l == 0){
+print("pc= %lux", pc);
+for(;;);
+}
for(i = 0; i < 1000000; i++){
if (tas(&ll->key) == 0){
if(u)
M power/devhotrod.c => power/devhotrod.c +1 -0
@@ 55,6 55,7 @@ Hotmsg**
hotsend(Commrod *h, Hotmsg *m)
{
Hotmsg **mp;
+int i;
lock(h);
mp = (Hotmsg**)&h->addr->reqstq[h->wi];