ref: 9c00c613885deba1ed19e905604571ef432cab11
parent: 0a0c16460f953250153a4f12d4b6cb267c34a377
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Jan 8 17:19:23 EST 2026
Various fixes to wait, notes
--- a/include/user.h
+++ b/include/user.h
@@ -18,6 +18,7 @@
#define rfork sysrfork
#define seek sysseek
#define stat sysstat
+#define await sysawait
#define wait syswait
#define write syswrite
#define wstat syswstat
@@ -63,6 +64,7 @@
extern int wstat(char*, uchar*, int);
extern void werrstr(char* ,...);
extern Waitmsg* wait(void);
+extern int await(char*, int);
extern Dir *dirstat(char*);
extern Dir *dirfstat(int);
extern int dirwstat(char*, Dir*);
--- a/kern/Makefile
+++ b/kern/Makefile
@@ -6,7 +6,6 @@
alloc.$O\
allocb.$O\
arm.$O\
- await.$O\
chan.$O\
data.$O\
dev.$O\
@@ -36,7 +35,6 @@
pgrp.$O\
postnote.$O\
procinit.$O\
- notify.$O\
rwlock.$O\
seg.$O\
sema.$O\
--- a/kern/await.c
+++ /dev/null
@@ -1,90 +1,0 @@
-#include "u.h"
-#include <signal.h>
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "error.h"
-#include "user.h"
-#include "sys.h"
-#include "proc.h"
-
-#define long int
-
-#ifndef WCOREDUMP /* not on Mac OS X Tiger */
-#define WCOREDUMP(status) 0
-#endif
-
-static struct {- int sig;
- char *str;
-} tab[] = {- SIGHUP, "hangup",
- SIGINT, "interrupt",
- SIGQUIT, "quit",
- SIGILL, "sys: illegal instruction",
- SIGTRAP, "sys: breakpoint",
- SIGABRT, "sys: abort",
-#ifdef SIGEMT
- SIGEMT, "sys: emulate instruction executed",
-#endif
- SIGFPE, "sys: fp: trap",
- SIGKILL, "sys: kill",
- SIGBUS, "sys: bus error",
- SIGSEGV, "sys: segmentation violation",
- SIGALRM, "alarm",
- SIGTERM, "kill",
- SIGURG, "sys: urgent condition on socket",
- SIGSTOP, "sys: stop",
- SIGTSTP, "sys: tstp",
- SIGCONT, "sys: cont",
- SIGCHLD, "sys: child",
- SIGTTIN, "sys: ttin",
- SIGTTOU, "sys: ttou",
-#ifdef SIGIO /* not on Mac OS X Tiger */
- SIGIO, "sys: i/o possible on fd",
-#endif
- SIGXCPU, "sys: cpu time limit exceeded",
- SIGXFSZ, "sys: file size limit exceeded",
- SIGVTALRM, "sys: virtual time alarm",
- SIGPROF, "sys: profiling timer alarm",
-#ifdef SIGWINCH /* not on Mac OS X Tiger */
- SIGWINCH, "sys: window size change",
-#endif
-#ifdef SIGINFO
- SIGINFO, "sys: status request",
-#endif
- SIGUSR1, "sys: usr1",
- SIGUSR2, "sys: usr2",
- SIGPIPE, "sys: write on closed pipe",
-};
-
-char*
-_p9sigstr(int sig, char *tmp)
-{- int i;
-
- for(i=0; i<nelem(tab); i++)
- if(tab[i].sig == sig)
- return tab[i].str;
- if(tmp == nil)
- return nil;
- sprint(tmp, "sys: signal %d", sig);
- return tmp;
-}
-
-int
-_p9strsig(char *s)
-{- int i;
-
- for(i=0; i<nelem(tab); i++)
- if(strcmp(s, tab[i].str) == 0)
- return tab[i].sig;
- return 0;
-}
-
-int
-await(char *p, int n)
-{- return osawait(up, p, n);
-}
--- a/kern/chan.c
+++ b/kern/chan.c
@@ -414,11 +414,8 @@
void
cclose(Chan *c)
{- if(c == nil)
- return;
-
- if(c->ref.ref < 1 || c->flag&CFREE)
- panic("cclose %#p", getcallerpc(&c));+ if(c == nil || c->ref.ref < 1 || c->flag&CFREE)
+ panic("cclose %#p, %ux, pid=%d", getcallerpc(&c), up->R[15], up->pid);if(decref(&c->ref))
return;
--- a/kern/fns.h
+++ b/kern/fns.h
@@ -55,6 +55,7 @@
Walkqid* devwalk(Chan*, Chan*, char**, int, Dirtab*, int, Devgen*);
int devwstat(Chan*, uchar*, int);
Dir* dirchanstat(Chan*);
+int donotify(Ureg*);
void dump(void);
Fgrp* dupfgrp(Fgrp*);
Segment* dupseg(Segment**, int, int);
@@ -143,6 +144,7 @@
Cmdbuf* parsecmd(char *a, int n);
void pathclose(Path*);
void pexit(char*, int);
+char *popnote(Ureg*);
void printinit(void);
int procindex(ulong);
void procinterrupt(Proc*);
--- a/kern/fpa.c
+++ b/kern/fpa.c
@@ -96,7 +96,9 @@
case 18: res = fabs(op2); break;
case 19: res = (vlong) op2; break;
case 20: res = sqrt(op2); break;
- default: sysfatal("unimplemented FPA operation %#x @ %8ux", opc, up->R[15] - 4);+ default:
+ panic("unimplemented FPA operation %#x @ %8ux", opc, up->R[15] - 4);+ return;
}
switch(prec) {case 0: *Fd = (float) res; break;
--- a/kern/notify.c
+++ /dev/null
@@ -1,274 +1,0 @@
-/*
- * Signal handling for Plan 9 programs.
- * We stubbornly use the strings from Plan 9 instead
- * of the enumerated Unix constants.
- * There are some weird translations. In particular,
- * a "kill" note is the same as SIGTERM in Unix.
- * There is no equivalent note to Unix's SIGKILL, since
- * it's not a deliverable signal anyway.
- *
- * We do not handle SIGABRT or SIGSEGV, mainly because
- * the thread library queues its notes for later, and we want
- * to dump core with the state at time of delivery.
- *
- * We have to add some extra entry points to provide the
- * ability to tweak which signals are deliverable and which
- * are acted upon. Notifydisable and notifyenable play with
- * the process signal mask. Notifyignore enables the signal
- * but will not call notifyf when it comes in. This is occasionally
- * useful.
- */
-
-
- /* TODO: This goes away
- * The notes here are for taking host notes and delivering to
- * the kernel. We will be going the other way, from the
- * rc + kernelspace to the running processes.
- */
-#include <u.h>
-#include <signal.h>
-#include <lib.h>
-
-extern char *_p9sigstr(int, char*);
-extern int _p9strsig(char*);
-
-typedef struct Sig Sig;
-struct Sig
-{- int sig; /* signal number */
- int flags;
-};
-
-enum
-{- Restart = 1<<0,
- Ignore = 1<<1,
- NoNotify = 1<<2,
-};
-
-static Sig sigs[] = {- SIGHUP, 0,
- SIGINT, 0,
- SIGQUIT, 0,
- SIGILL, 0,
- SIGTRAP, 0,
-/* SIGABRT, 0, */
-#ifdef SIGEMT
- SIGEMT, 0,
-#endif
- SIGFPE, 0,
- SIGBUS, 0,
-/* SIGSEGV, 0, */
- SIGCHLD, Restart|Ignore,
- SIGSYS, 0,
- SIGPIPE, Ignore,
- SIGALRM, 0,
- SIGTERM, 0,
- SIGTSTP, Restart|Ignore|NoNotify,
-/* SIGTTIN, Restart|Ignore, */
-/* SIGTTOU, Restart|Ignore, */
- SIGXCPU, 0,
- SIGXFSZ, 0,
- SIGVTALRM, 0,
- SIGUSR1, 0,
- SIGUSR2, 0,
-#ifdef SIGWINCH
- SIGWINCH, Restart|Ignore|NoNotify,
-#endif
-#ifdef SIGINFO
- SIGINFO, Restart|Ignore|NoNotify,
-#endif
-};
-
-static Sig*
-findsig(int s)
-{- int i;
-
- for(i=0; i<nelem(sigs); i++)
- if(sigs[i].sig == s)
- return &sigs[i];
- return nil;
-}
-
-// for now
-typedef long p9jmp_buf[sizeof(sigjmp_buf)/(sizeof(long))];
-typedef struct Jmp Jmp;
-struct Jmp
-{- p9jmp_buf b;
-};
-
-static Jmp onejmp;
-
-static Jmp*
-getonejmp(void)
-{- return &onejmp;
-}
-
-Jmp *(*_notejmpbuf)(void) = getonejmp;
-static void noteinit(void);
-
-/*
- * Actual signal handler.
- */
-
-static void (*notifyf)(void*, char*); /* Plan 9 handler */
-
-static void
-signotify(int sig)
-{- char tmp[64];
- Jmp *j;
- Sig *s;
-
- j = (*_notejmpbuf)();
- switch(sigsetjmp((void*)j->b, 1)){- case 0:
- if(notifyf)
- // probaby not p9sigstr
- (*notifyf)(nil, _p9sigstr(sig, tmp));
- /* fall through */
- case 1: /* noted(NDFLT) */
- if(0)print("DEFAULT %d\n", sig);- s = findsig(sig);
- if(s && (s->flags&Ignore))
- return;
- signal(sig, SIG_DFL);
- raise(sig);
- _exit(1);
- case 2: /* noted(NCONT) */
- if(0)print("HANDLED %d\n", sig);- return;
- }
-}
-
-static void
-signonotify(int sig)
-{- USED(sig);
-}
-
-int
-noted(int v)
-{- siglongjmp((*_notejmpbuf)()->b, v==NCONT ? 2 : 1);
- abort();
- return 0;
-}
-
-int
-notify(void (*f)(void*, char*))
-{- static int init;
-
- notifyf = f;
- if(!init){- init = 1;
- noteinit();
- }
- return 0;
-}
-
-/*
- * Nonsense about enabling and disabling signals.
- */
-typedef void Sighandler(int);
-static Sighandler*
-handler(int s)
-{- struct sigaction sa;
-
- sigaction(s, nil, &sa);
- return sa.sa_handler;
-}
-
-static int
-notesetenable(int sig, int enabled)
-{- sigset_t mask, omask;
-
- if(sig == 0)
- return -1;
-
- sigemptyset(&mask);
- sigaddset(&mask, sig);
- sigprocmask(enabled ? SIG_UNBLOCK : SIG_BLOCK, &mask, &omask);
- return !sigismember(&omask, sig);
-}
-
-int
-noteenable(char *msg)
-{- return notesetenable(_p9strsig(msg), 1);
-}
-
-int
-notedisable(char *msg)
-{- return notesetenable(_p9strsig(msg), 0);
-}
-
-static int
-notifyseton(int s, int on)
-{- Sig *sig;
- struct sigaction sa, osa;
-
- sig = findsig(s);
- if(sig == nil)
- return -1;
- memset(&sa, 0, sizeof sa);
- sa.sa_handler = on ? signotify : signonotify;
- if(sig->flags&Restart)
- sa.sa_flags |= SA_RESTART;
-
- /*
- * We can't allow signals within signals because there's
- * only one jump buffer.
- */
- sigfillset(&sa.sa_mask);
-
- /*
- * Install handler.
- */
- sigaction(sig->sig, &sa, &osa);
- return osa.sa_handler == signotify;
-}
-
-int
-notifyon(char *msg)
-{- return notifyseton(_p9strsig(msg), 1);
-}
-
-int
-notifyoff(char *msg)
-{- return notifyseton(_p9strsig(msg), 0);
-}
-
-/*
- * Initialization follows sigs table.
- */
-static void
-noteinit(void)
-{- int i;
- Sig *sig;
-
- for(i=0; i<nelem(sigs); i++){- sig = &sigs[i];
- /*
- * If someone has already installed a handler,
- * It's probably some ld preload nonsense,
- * like pct (a SIGVTALRM-based profiler).
- * Or maybe someone has already called notifyon/notifyoff.
- * Leave it alone.
- */
- if(handler(sig->sig) != SIG_DFL)
- continue;
- notifyseton(sig->sig, !(sig->flags&NoNotify));
- }
-}
--- a/kern/pgrp.c
+++ b/kern/pgrp.c
@@ -140,11 +140,11 @@
Chan *c;
int i;
- new = malloc(sizeof(Fgrp));
+ new = smalloc(sizeof(Fgrp));
if(new == nil)
error(Enomem);
- new->ref.ref = 1;
if(f == nil){+ new->ref.ref = 1;
new->nfd = DELTAFD;
new->fd = malloc(DELTAFD*sizeof(new->fd[0]));
if(new->fd == nil){@@ -156,6 +156,7 @@
}
lock(&f->lk);
+ new->ref = f->ref;
/* Make new fd list shorter if possible, preserving quantization */
new->nfd = f->maxfd+1;
i = new->nfd%DELTAFD;
--- a/kern/postnote.c
+++ b/kern/postnote.c
@@ -21,6 +21,44 @@
}
}
+/*
+ * pop a note from the calling process or suicide if theres
+ * no note handler or notify during note handling.
+ * Called from notify() with up->debug lock held.
+ */
+char*
+popnote(Ureg *u)
+{+ up->notepending = 0;
+ if(up->nnote == 0)
+ return nil;
+
+ /* hold off user notes during note handling */
+ if(up->notified && up->note[0]->flag == NUser)
+ return nil;
+
+ freenote(up->lastnote);
+ up->lastnote = up->note[0];
+ if(--up->nnote > 0)
+ memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note*));
+ up->note[up->nnote] = nil;
+
+ if(u != nil && up->lastnote->ref.ref == 1 && strncmp(up->lastnote->msg, "sys:", 4) == 0){+ int l = strlen(up->lastnote->msg);
+ snprint(up->lastnote->msg+l, ERRMAX-l, " pc=%#p", u->pc);
+ }
+
+ if(up->notify == nil || up->notified){+ qunlock(&up->debug);
+ if(up->lastnote->flag == NDebug)
+ pprint("suicide: %s\n", up->lastnote->msg);+ pexit(up->lastnote->msg, up->lastnote->flag!=NDebug);
+ }
+ up->notified = 1;
+
+ return up->lastnote->msg;
+}
+
static Note*
mknote(char *msg, int flag)
{--- a/kern/sleep.c
+++ b/kern/sleep.c
@@ -162,13 +162,3 @@
break;
}
}
-
-int
-postnote(Proc *p, int x, char *msg, int flag)
-{- USED(x);
- USED(msg);
- USED(flag);
- procinterrupt(p);
- return 0;
-}
--- a/kern/syscall.c
+++ b/kern/syscall.c
@@ -327,7 +327,7 @@
Segment *s;
v = arg(0);
- v = v + 7 & -8;
+ v = (v + 7) & -8;
#ifdef DSYSCALL
print("sysbrk: pid=%d v=%#lux\n", up->pid, v);#endif
@@ -409,6 +409,33 @@
segunlock(s);
}
+int
+donotify(Ureg *ureg)
+{+ char *msg;
+
+ //if(up->procctl)
+ // procctl();
+ if(up->nnote == 0)
+ return 0;
+
+ qlock(&up->debug);
+ msg = popnote(ureg);
+ if(msg == nil){+ qunlock(&up->debug);
+ return 0;
+ }
+ qunlock(&up->debug);
+
+ if(up->notify == nil){+ if(up->lastnote->flag == NDebug)
+ pprint("suicide: %s\n", msg);+ pexit(msg, up->lastnote->flag!=NDebug);
+ }
+
+ return 1;
+}
+
static void
_sysnoted(void)
{@@ -601,7 +628,7 @@
#ifdef DSYSCALL
print("sysawait: pid=%d\n", up->pid);#endif
- up->R[0] = noteerr(await(st, n), 0);
+ up->R[0] = noteerr(sysawait(st, n), 0);
if(buffered)
copyback(s, up->R[0], st);
}
@@ -644,7 +671,10 @@
#ifdef DSYSCALL
print("syssleep: pid=%d nsec=%.8ux\n", up->pid, n);#endif
- osmsleep(n);
+ if(n <= 0)
+ osyield();
+ else
+ osmsleep(n*1000);
up->R[0] = 0;
}
@@ -787,6 +817,7 @@
}
afd = newfd(ac);
+ print("afd: %d\n", afd);up->R[0] = afd;
poperror(); /* ac */
}
--- a/kern/sysfile.c
+++ b/kern/sysfile.c
@@ -542,7 +542,7 @@
long
_syspwrite(int fd, void *buf, long n, vlong off)
{- if(off == ((uvlong) ~0))
+ if(off <= 0)
return kwrite(fd, buf, n, nil);
return kwrite(fd, buf, n, &off);
}
@@ -1171,7 +1171,7 @@
_syserror();
return -1;
}
- n = _syspwrite(fd, buf, n, (uvlong) ~0);
+ n = _syspwrite(fd, buf, n, 0);
enderror();
return n;
}
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -130,36 +130,6 @@
}
static void
-donote(void)
-{- Note *n;
- char msg[ERRMAX];
-
- if(up->nnote == 0)
- return;
-
- n = up->note[0];
- strncpy(msg, n->msg, ERRMAX-1);
- msg[ERRMAX-1] = 0;
-
- memmove(up->note, up->note+1, (up->nnote-1)*sizeof(Note));
- up->nnote--;
-
- up->notepending = (up->nnote > 0);
-
- if(up->notify == nil){- /* Default action: die on interrupt, ignore others */
- if(strncmp(msg, "interrupt", 9) == 0)
- pexit(msg, 1);
- return;
- }
-
- /* Call user handler */
- (*up->notify)(up, msg);
-
-}
-
-static void
initstack(int argc, char **argv)
{ulong tos, sp, ap, size, i, len;
@@ -315,6 +285,7 @@
void
procrun(void *v)
{+ Ureg ureg;
USED(v);
for(;;) {#ifdef DREGS
@@ -321,7 +292,7 @@
dump();
#endif
if(up->notepending)
- donote();
+ donotify(&ureg);
step();
}
}
@@ -471,6 +442,7 @@
}
p->fn = procrun;
p->parent = up;
+ up->child = p;
p->arg = 0;
poperror();
@@ -479,7 +451,6 @@
devmask(p->pgrp, 1, devs);
if((flag&RFNOWAIT) == 0){- p->parent = up;
lock(&up->exl);
up->nchild++;
unlock(&up->exl);
--- a/kern/wait.c
+++ b/kern/wait.c
@@ -1,5 +1,8 @@
-#include <u.h>
-#include <libc.h>
+#include "u.h"
+#include "lib.h"
+#include "dat.h"
+#include "fns.h"
+#include "user.h"
static Waitmsg*
_wait(int n, char *buf)
@@ -12,7 +15,7 @@
return nil;
buf[n] = '\0';
if(tokenize(buf, fld, nelem(fld)) != nelem(fld)){- werrstr("couldn't parse wait message");+ panic("couldn't parse wait message");return nil;
}
l = strlen(fld[4])+1;
@@ -34,4 +37,10 @@
char buf[256];
return _wait(await(buf, sizeof buf-1), buf);
+}
+
+int
+sysawait(char *p, int n)
+{+ return osawait(up, p, n);
}
--- a/main.c
+++ b/main.c
@@ -70,7 +70,8 @@
fs = auth = nil;
kerndate = seconds();
eve = getuser();
-
+ sysname = "drawcpu";
+
ARGBEGIN {case 'a':
auth = EARGF(usage());
@@ -104,7 +105,6 @@
chandevreset();
chandevinit();
quotefmtinstall();
- notify(notehandler);
/* This ordering is based on /lib/namespace
* - Our host fs connection lives in /srv/boot
@@ -145,6 +145,7 @@
panic("bind bin: %r"); loadtext("/bin/rc", 1, argv);+ ksetenv("home", smprint("/usr/%s", eve), 0); ksetenv("cputype", "arm", 0); // cputype being anything but arm should fail for now ksetenv("objtype", "arm", 0); ksetenv("rootdir", "/root", 0);--
⑨