code: purgatorio

Download patch

ref: 866d74c0c4bb50e85e9e8bb95140c10d409e53be
parent: 82b046f36f8084a22bbb5d71edd0edd9179561eb
author: henesy <devnull@localhost>
date: Sat Feb 29 11:19:18 EST 2020

merge 8a003973f13c53f37de48c6c635500b5a0988cfb

--- a/NetBSD/386/include/emu.h
+++ b/NetBSD/386/include/emu.h
@@ -15,16 +15,8 @@
 
 #define KSTACK (32 * 1024)
 
-static __inline Proc *getup(void) {
-	Proc *p;
-	__asm__(	"movl	%%esp, %%eax\n\t"
-			: "=a" (p)
-	);
-	return *(Proc **)((unsigned long)p & ~(KSTACK - 1));
-};
-
+extern	Proc*	getup(void);
 #define	up	(getup())
 
 typedef sigjmp_buf osjmpbuf;
 #define	ossetjmp(buf)	sigsetjmp(buf, 1)
-
--- a/NetBSD/power/include/emu.h
+++ b/NetBSD/power/include/emu.h
@@ -15,14 +15,8 @@
 
 #define KSTACK (32 * 1024)
 
-static __inline Proc *getup(void) {
-	Proc *p;
-	__asm__(	"mr	%0, 1" : "=r" (p));
-	return *(Proc **)((unsigned long)p & ~(KSTACK - 1));
-};
-
+extern	Proc*	getup(void);
 #define	up	(getup())
 
 typedef sigjmp_buf osjmpbuf;
 #define	ossetjmp(buf)	sigsetjmp(buf, 1)
-
--- a/emu/NetBSD/asm-386.S
+++ b/emu/NetBSD/asm-386.S
@@ -2,56 +2,6 @@
 #include <sys/syscall.h>
 
 /*
- * executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg)
- */
-
-	.type	executeonnewstack,@function
-	.global	executeonnewstack
-executeonnewstack:
-	pushl	%ebp
-	movl	%esp, %ebp
-	pushl	%esi
-
-	movl	8(%ebp), %esi	/* get tos */
-	subl	$4, %esi
-	movl	16(%ebp), %eax
-	movl	%eax, (%esi)	/* stash arg on new stack */
-	subl	$4, %esi
-	movl	12(%ebp), %eax
-	movl	%eax, (%esi)	/* stash tramp on new stack */
-	mov	%esi, %esp	/* swap stacks pronto */
-	popl	%eax		/* recover the tramp address */
-	call	*%eax		/* and jump to it (ho ho) */
-
-	/* if we return here, tramp didn't do its job */
-
-	addl	$8, %esp	/* clean up for pose value */
-
-	leal	SYS_exit, %eax
-	int	$0x80
-
-/*
- * unlockandexit(int *key)
- *
- * NB: the return status may be rubbish if the stack is reused
- *	between the unlock and the system call, but this should
- *	not matter since no task is waiting for the result
- */
-
-	.type	unlockandexit,@function
-	.global	unlockandexit
-unlockandexit:
-	pushl	%ebp
-	movl	%esp, %ebp
-
-	movl	8(%ebp), %esi		/* get the key address */
-	pushl	$0			/* exit status 0 */
-	movl	$0, %eax		/* unlock the stack allocator */
-	movl	%eax, (%esi)
-	leal	SYS_exit, %eax		/* call exit */
-	int	$0x80
-
-/*
  * umult(ulong m1, ulong m2, ulong *hi)
  */
 
--- a/emu/NetBSD/asm-power.S
+++ b/emu/NetBSD/asm-power.S
@@ -58,34 +58,3 @@
 	sync
 	blr
 	END(_tas)
-
-/*
- * void
- * executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg)
- */
-ENTRY_NOPROFILE(executeonnewstack)
-	mr	%r1,%r3		/* change stacks */
-	stwu 	%lr,-16(%r1)	/* save lr to aid the traceback */
-	li	%r0,0
-	stw 	%r0,20(%r1)
-	mr	%r3,%r5
-	mtctr 	%r4
-	bctrl	/* tramp(arg) */
-	br
-	END(executeonnewstack)
-
-/*
- * void unlockandexit(int *key)
- *
- * NB: the return status may be garbaged if the stack is reused
- *	between the unlock and the system call, but this should
- *	not matter since no task is waiting for the result
- */
-ENTRY_NOPROFILE(unlockandexit)
-	li	%r0,0x0
-	stw	%r0,0(%r3)	/* unlock */
-	li	%r0,1		/* sys exit; 234 is exit group */
-	li	%r3,0		/* exit status */
-	sc
-	br
-	END(unlockandexit)
--- a/emu/NetBSD/mkfile
+++ b/emu/NetBSD/mkfile
@@ -20,6 +20,8 @@
 OBJ=\
 	asm-$OBJTYPE.$O\
 	os.$O\
+	segflush-$OBJTYPE.$O\
+	kproc-pthreads.$O\
 	$CONF.root.$O\
 	lock.$O\
 	$DEVS\
@@ -28,7 +30,7 @@
 HFILES=\
 
 CFLAGS='-DROOT="'$ROOT'"' -DEMU -I. -I../port -I$ROOT/$SYSTARG/$OBJTYPE/include -I$ROOT/include -I$ROOT/libinterp $CTHREADFLAGS $CFLAGS $EMUOPTIONS
-SYSLIBS= ${X11LIBS} -lossaudio -lm
+SYSLIBS= ${X11LIBS} -lossaudio -lm -lpthread
 KERNDATE=`{$NDATE}
 
 default:V:	$O.$CONF
--- a/emu/NetBSD/os.c
+++ b/emu/NetBSD/os.c
@@ -13,6 +13,8 @@
 #include	"fns.h"
 #include	"error.h"
 
+#include	"raise.h"
+
 /* For dynamic linking init/fini code that needs malloc */
 void (*coherence)(void) = nofence;
 
@@ -21,17 +23,10 @@
 {
 	DELETE	= 0x7f,
 	CTRLC	= 'C'-'@',
-	NSTACKSPERALLOC = 16,
-	X11STACK=	256*1024
 };
 char *hosttype = "NetBSD";
 
-static void *stackalloc(Proc *p, void **tos);
-static void stackfreeandexit(void *stack);
 
-void executeonnewstack(void *tos, void (*tramp)(void *arg), void *arg);
-void unlockandexit(ulong *key);
-
 extern int dflag;
 
 int	gidnobody = -1;
@@ -38,163 +33,49 @@
 int	uidnobody = -1;
 static struct 	termios tinit;
 
-void
-pexit(char *msg, int t)
-{
-	Osenv *e;
-	void *kstack;
-
-	lock(&procs.l);
-	if(up->prev)
-		up->prev->next = up->next;
-	else
-		procs.head = up->next;
-
-	if(up->next)
-		up->next->prev = up->prev;
-	else
-		procs.tail = up->prev;
-	unlock(&procs.l);
-
-	if(0)
-		print("pexit: %s: %s\n", up->text, msg);
-
-	e = up->env;
-	if(e != nil) {
-		closefgrp(e->fgrp);
-		closepgrp(e->pgrp);
-		closeegrp(e->egrp);
-		closesigs(e->sigs);
-	}
-	kstack = up->kstack;
-	free(up->prog);
-	free(up);
-	if(kstack != nil)
-		stackfreeandexit(kstack);
-}
-
-int
-tramp(void *arg)
-{
-	Proc *p;
-	p = arg;
-	p->pid = p->sigid = getpid();
-	(*p->func)(p->arg);
-	pexit("{Tramp}", 0);
-	return 0;
-}
-
-void
-kproc(char *name, void (*func)(void*), void *arg, int flags)
-{
-	int pid;
-	Proc *p;
-	Pgrp *pg;
-	Fgrp *fg;
-	Egrp *eg;
-	void *tos;
-
-	p = newproc();
-	if(0)
-		print("start %s:%.8lx\n", name, p);
-	if(p == nil) {
-		print("kproc(%s): no memory", name);
-		panic("kproc: no memory");
-	}
-
-	if(flags & KPDUPPG) {
-		pg = up->env->pgrp;
-		incref(&pg->r);
-		p->env->pgrp = pg;
-	}
-	if(flags & KPDUPFDG) {
-		fg = up->env->fgrp;
-		incref(&fg->r);
-		p->env->fgrp = fg;
-	}
-	if(flags & KPDUPENVG) {
-		eg = up->env->egrp;
-		incref(&eg->r);
-		p->env->egrp = eg;
-	}
-
-	p->env->uid = up->env->uid;
-	p->env->gid = up->env->gid;
-	kstrdup(&p->env->user, up->env->user);
-
-	strcpy(p->text, name);
-
-	p->func = func;
-	p->arg = arg;
-
-	if(flags & KPX11){
-		p->kstack = nil;	/* never freed; also up not defined */
-		tos = (char*)mallocz(X11STACK, 0) + X11STACK - sizeof(void*);
-	}else
-		p->kstack = stackalloc(p, &tos);
-
-	lock(&procs.l);
-	if(procs.tail != nil) {
-		p->prev = procs.tail;
-		procs.tail->next = p;
-	}
-	else {
-		procs.head = p;
-		p->prev = nil;
-	}
-	procs.tail = p;
-	unlock(&procs.l);
-
-	if (__clone(tramp, tos, /*CLONE_PTRACE|*/CLONE_VM|CLONE_FS|CLONE_FILES|SIGCHLD, p) <= 0) {
-		fprint(2, "emu: clone failed: %s\n", strerror(errno));
-		panic("kproc: clone failed");
-	}
-}
-
-/*
- * TO DO:
- * To get pc on trap, use sigaction instead of signal and
- * examine its siginfo structure
- */
-
-/*
 static void
-diserr(char *s, int pc)
+sysfault(char *what, void *addr)
 {
-	char buf[ERRMAX];
+	char buf[64];
 
-	snprint(buf, sizeof(buf), "%s: pc=0x%lux", s, pc);
+	snprint(buf, sizeof(buf), "sys: %s%#p", what, addr);
 	disfault(nil, buf);
 }
-*/
 
 static void
-trapILL(int signo)
+trapILL(int signo, siginfo_t *si, void *a)
 {
 	USED(signo);
-	disfault(nil, "Illegal instruction");
+	USED(a);
+	sysfault("illegal instruction pc=", si->si_addr);
 }
 
-static void
-trapBUS(int signo)
+static int
+isnilref(siginfo_t *si)
 {
-	USED(signo);
-	disfault(nil, "Bus error");
+	return si != 0 && (si->si_addr == (void*)~(uintptr_t)0 || (uintptr_t)si->si_addr < 512);
 }
 
 static void
-trapSEGV(int signo)
+trapmemref(int signo, siginfo_t *si, void *a)
 {
-	USED(signo);
-	disfault(nil, "Segmentation violation");
+	USED(a);	/* ucontext_t*, could fetch pc in machine-dependent way */
+	if(isnilref(si))
+		disfault(nil, exNilref);
+	else if(signo == SIGBUS)
+		sysfault("bad address addr=", si->si_addr);	/* eg, misaligned */
+	else
+		sysfault("segmentation violation addr=", si->si_addr);
 }
 
 static void
-trapFPE(int signo)
+trapFPE(int signo, siginfo_t *si, void *a)
 {
 	char buf[64];
+
 	USED(signo);
-	snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux", getfsr());
+	USED(a);
+	snprint(buf, sizeof(buf), "sys: fp: exception status=%.4lux pc=%#p", getfsr(), si->si_addr);
 	disfault(nil, buf);
 }
 
@@ -215,38 +96,7 @@
 		disfault(nil, Eintr);	/* Should never happen */
 }
 
-/* called to wake up kproc blocked on a syscall */
 void
-oshostintr(Proc *p)
-{
-	kill(p->sigid, SIGUSR1);
-}
-
-static void
-trapUSR2(int signo)
-{
-	USED(signo);
-	/* we've done our work of interrupting sigsuspend */
-}
-
-void
-osblock(void)
-{
-	sigset_t mask;
-
-	sigprocmask(SIG_SETMASK, NULL, &mask);
-	sigdelset(&mask, SIGUSR2);
-	sigsuspend(&mask);
-}
-
-void
-osready(Proc *p)
-{
-	if(kill(p->sigid, SIGUSR2) < 0)
-		fprint(2, "emu: osready failed: pid %d: %s\n", p->sigid, strerror(errno));
-}
-
-void
 oslongjmp(void *regs, osjmpbuf env, int val)
 {
 	USED(regs);
@@ -301,12 +151,9 @@
 void
 libinit(char *imod)
 {
-	struct termios t;
 	struct sigaction act;
-	sigset_t mask;
 	struct passwd *pw;
 	Proc *p;
-	void *tos;
 	char sys[64];
 
 	setsid();
@@ -323,18 +170,10 @@
 	if(dflag == 0)
 		termset();
 
-	memset(&act, 0 , sizeof(act));
+	memset(&act, 0, sizeof(act));
 	act.sa_handler = trapUSR1;
 	sigaction(SIGUSR1, &act, nil);
 
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGUSR2);
-	sigprocmask(SIG_BLOCK, &mask, NULL);
-
-	memset(&act, 0 , sizeof(act));
-	act.sa_handler = trapUSR2;
-	sigaction(SIGUSR2, &act, nil);
-
 	act.sa_handler = SIG_IGN;
 	sigaction(SIGCHLD, &act, nil);
 
@@ -349,18 +188,23 @@
 		signal(SIGINT, cleanexit);
 
 	if(sflag == 0) {
-		act.sa_handler = trapBUS;
-		sigaction(SIGBUS, &act, nil);
-		act.sa_handler = trapILL;
+		act.sa_flags = SA_SIGINFO;
+
+		act.sa_sigaction = trapILL;
 		sigaction(SIGILL, &act, nil);
-		act.sa_handler = trapSEGV;
-		sigaction(SIGSEGV, &act, nil);
-		act.sa_handler = trapFPE;
+
+		act.sa_sigaction = trapFPE;
 		sigaction(SIGFPE, &act, nil);
+
+		act.sa_sigaction = trapmemref;
+		sigaction(SIGBUS, &act, nil);
+		sigaction(SIGSEGV, &act, nil);
+
+		act.sa_flags = 0;
 	}
 
 	p = newproc();
-	p->kstack = stackalloc(p, &tos);
+	kprocinit(p);
 
 	pw = getpwuid(getuid());
 	if(pw != nil)
@@ -371,7 +215,7 @@
 	p->env->uid = getuid();
 	p->env->gid = getgid();
 
-	executeonnewstack(tos, emuinit, imod);
+	emuinit(imod);
 }
 
 int
@@ -456,74 +300,4 @@
 limbosleep(ulong milsec)
 {
 	return osmillisleep(milsec);
-}
-
-void
-osyield(void)
-{
-	sched_yield();
-}
-
-void
-ospause(void)
-{
-	for(;;)
-		pause();
-}
-
-void
-oslopri(void)
-{
-	setpriority(PRIO_PROCESS, 0, getpriority(PRIO_PROCESS,0)+4);
-}
-
-static struct {
-	Lock l;
-	void *free;
-} stacklist;
-
-static void
-_stackfree(void *stack)
-{
-	*((void **)stack) = stacklist.free;
-	stacklist.free = stack;
-}
-
-static void
-stackfreeandexit(void *stack)
-{
-	lock(&stacklist.l);
-	_stackfree(stack);
-	unlockandexit(&stacklist.l.val);
-}
-
-static void *
-stackalloc(Proc *p, void **tos)
-{
-	void *rv;
-	lock(&stacklist.l);
-	if (stacklist.free == 0) {
-		int x;
-		/*
-		 * obtain some more by using sbrk()
-		 */
-		void *more = sbrk(KSTACK * (NSTACKSPERALLOC + 1));
-		if (more == 0)
-			panic("stackalloc: no more stacks");
-		/*
-		 * align to KSTACK
-		 */
-		more = (void *)((((unsigned long)more) + (KSTACK - 1)) & ~(KSTACK - 1));
-		/*
-		 * free all the new stacks onto the freelist
-		 */
-		for (x = 0; x < NSTACKSPERALLOC; x++)
-			_stackfree((char *)more + KSTACK * x);
-	}
-	rv = stacklist.free;
-	stacklist.free = *(void **)rv;
-	unlock(&stacklist.l);
-	*tos = rv + KSTACK - sizeof(void *);
-	*(Proc **)rv = p;
-	return rv;
 }
--- a/emu/port/alloc.c
+++ b/emu/port/alloc.c
@@ -75,7 +75,11 @@
 
 /* tracing */
 enum {
+#ifdef __NetBSD__
+	Npadlong	= 4,	/* XXX: preserve 16-byte alignment */
+#else
 	Npadlong	= 2,
+#endif
 	MallocOffset = 0,
 	ReallocOffset = 1
 };
--- a/emu/port/kproc-pthreads.c
+++ b/emu/port/kproc-pthreads.c
@@ -12,6 +12,13 @@
 #include	<errno.h>
 #include	<semaphore.h>
 
+#ifdef __NetBSD__
+#include	<sched.h>
+#define pthread_yield() (sched_yield())
+#define PTHREAD_STACK_MIN ((size_t)sysconf(_SC_THREAD_STACK_MIN))
+#endif
+
+
 typedef struct Osdep Osdep;
 struct Osdep {
 	sem_t	sem;
@@ -115,6 +122,12 @@
 		panic("kproc: no memory");
 	os->self = 0;	/* set by tramp */
 	sem_init(&os->sem, 0, 0);
+#if defined(__NetBSD__) && defined(__powerpc__)
+	{ /* XXX: Work around a problem on macppc with kernel semaphores. */
+		int val;
+		sem_getvalue(&os->sem, &val);
+	}
+#endif
 	p->os = os;
 
 	if(flags & KPDUPPG) {
--- a/emu/port/mkdevc
+++ b/emu/port/mkdevc
@@ -10,7 +10,7 @@
 /^#/{
 		next;
 }
-collect && /^[^	\t]/{
+collect && /^[^ \t]/{
 		collect = 0;
 }
 collect && section ~ "dev"{