shithub: drawcpu

Download patch

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);
--