Subject: getting rid of sigcontext and adding siginfo support to libpthread
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 09/11/2003 17:55:35
Is this patch ok?

christos

Index: pthread_int.h
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_int.h,v
retrieving revision 1.18
diff -u -u -r1.18 pthread_int.h
--- pthread_int.h	2003/09/07 14:47:44	1.18
+++ pthread_int.h	2003/09/11 21:51:30
@@ -295,6 +295,7 @@
 	} while (/*CONSTCOND*/0)
 
 #ifdef __PTHREAD_SIGNAL_PRIVATE
+#ifndef __HAVE_SIGINFO
 
 /*
  * Macros for converting from ucontext to sigcontext and vice-versa.
@@ -340,6 +341,8 @@
 	    ucontext_t *);
 #endif /* PTHREAD_UCONTEXT_TO_SIGCONTEXT */
 
+#endif /* __HAVE_SIGINFO */
+
 #endif /* __PTHREAD_SIGNAL_PRIVATE */
 
 #ifdef PTHREAD_MACHINE_HAS_ID_REGISTER
@@ -379,8 +382,8 @@
 
 void	pthread__signal_init(void);
 
-void	pthread__signal(pthread_t self, pthread_t t, int sig, int code);
-void	pthread__deliver_signal(pthread_t self, pthread_t t, int sig, int code);
+void	pthread__signal(pthread_t self, pthread_t t, siginfo_t *si);
+void	pthread__deliver_signal(pthread_t self, pthread_t t, siginfo_t *si);
 void	pthread__signal_deferred(pthread_t self, pthread_t t);
 
 void	pthread__destroy_tsd(pthread_t self);
Index: pthread_sa.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_sa.c,v
retrieving revision 1.14
diff -u -u -r1.14 pthread_sa.c
--- pthread_sa.c	2003/09/07 14:47:45	1.14
+++ pthread_sa.c	2003/09/11 21:51:31
@@ -182,10 +182,9 @@
 		 */
 		si = arg;
 		if (ev)
-			pthread__signal(self, pthread__sa_id(sas[1]),
-			    si->si_signo, si->si_code);
+			pthread__signal(self, pthread__sa_id(sas[1]), si);
 		else
-			pthread__signal(self, NULL, si->si_signo, si->si_code);
+			pthread__signal(self, NULL, si);
 		break;
 	case SA_UPCALL_SIGEV:
 		PTHREADD_ADD(PTHREADD_UP_SIGEV);
Index: pthread_sig.c
===================================================================
RCS file: /cvsroot/src/lib/libpthread/pthread_sig.c,v
retrieving revision 1.17
diff -u -u -r1.17 pthread_sig.c
--- pthread_sig.c	2003/08/22 17:35:52	1.17
+++ pthread_sig.c	2003/09/11 21:51:31
@@ -95,12 +95,13 @@
 static pthread_t pt_sigwmaster;
 static pthread_cond_t pt_sigwaiting_cond = PTHREAD_COND_INITIALIZER;
 
-static void pthread__kill(pthread_t, pthread_t, int, int);
-static void pthread__kill_self(pthread_t, int, int);
+static void pthread__make_siginfo(siginfo_t *, int);
+static void pthread__kill(pthread_t, pthread_t, siginfo_t *);
+static void pthread__kill_self(pthread_t, siginfo_t *);
 
 static void 
-pthread__signal_tramp(int, int, void (*)(int, int, struct sigcontext *),
-    ucontext_t *, sigset_t *);
+pthread__signal_tramp(void (*)(int, siginfo_t *, void *),
+    siginfo_t *, ucontext_t *);
 
 static int firstsig(const sigset_t *);
 
@@ -119,6 +120,16 @@
 	PTQ_INIT(&pt_sigwaiting);
 }
 
+static void
+pthread__make_siginfo(siginfo_t *si, int sig)
+{
+	(void)memset(&si, 0, sizeof(si));
+	si->si_signo = sig;
+	si->si_code = SI_USER;
+	si->si_uid = getuid();
+	si->si_pid = getpid();
+}
+
 int
 pthread_kill(pthread_t thread, int sig)
 {
@@ -152,8 +163,10 @@
 		SDPRINTF(("(pthread_kill %p) kernel kill\n", self, thread, sig));
 		kill(getpid(), sig);
 	} else {
+		siginfo_t si;
+		pthread__make_siginfo(&si, sig);
 		pthread_spinlock(self, &thread->pt_siglock);
-		pthread__kill(self, thread, sig, 0);
+		pthread__kill(self, thread, &si);
 		pthread_spinunlock(self, &thread->pt_siglock);
 	}
 
@@ -466,8 +479,7 @@
 				 * 'their' signal arrives before the master
 				 * thread would be scheduled after _lwp_wakeup().
 				 */
-				pthread__signal(self, NULL, info->si_signo,
-					info->si_code);
+				pthread__signal(self, NULL, info);
 			} else {
 				/*
 				 * Signal waiter removed, adjust our wait set.
@@ -534,6 +546,7 @@
 	sigset_t tmp, takelist;
 	pthread_t self;
 	int i;
+	siginfo_t si;
 
 	self = pthread__self();
 	/*
@@ -589,11 +602,13 @@
 	}
 	pthread_spinunlock(self, &pt_process_siglock);
 
+	pthread__make_siginfo(&si, 0);
 	while ((i = firstsig(&takelist)) != 0) {
 		/* Take the signal */	
 		SDPRINTF(("(pt_sigmask %p) taking unblocked signal %d\n",
 		    self, i));
-		pthread__kill_self(self, i, 0);
+		si.si_signo = i;
+		pthread__kill_self(self, &si);
 		__sigdelset14(&takelist, i);
 	}
 
@@ -608,7 +623,7 @@
  * willing thread, if t is null.
  */
 void
-pthread__signal(pthread_t self, pthread_t t, int sig, int code)
+pthread__signal(pthread_t self, pthread_t t, siginfo_t *si)
 {
 	pthread_t target, good, okay;
 
@@ -635,7 +650,8 @@
 			SDPRINTF((
 				"(pt_signal %p) target %p: state %d, mask %08x\n", 
 				self, target, target->pt_state, target->pt_sigmask.__bits[0]));
-			if (!__sigismember14(&target->pt_sigmask, sig)) {
+			if (!__sigismember14(&target->pt_sigmask,
+			    si->si_signo)) {
 				if (target->pt_state != PT_STATE_BLOCKED_SYS) {
 					good = target;
 					/* Leave target locked */
@@ -664,11 +680,11 @@
 			 * for later unblocking.  
 			 */
 			pthread_spinlock(self, &pt_process_siglock);
-			__sigaddset14(&pt_process_sigmask, sig);
+			__sigaddset14(&pt_process_sigmask, si->si_signo);
 			SDPRINTF(("(pt_signal %p) lazily setting proc sigmask to "
 			    "%08x\n", self, pt_process_sigmask.__bits[0]));
 			__sigprocmask14(SIG_SETMASK, &pt_process_sigmask, NULL);
-			__sigaddset14(&pt_process_siglist, sig);
+			__sigaddset14(&pt_process_siglist, si->si_signo);
 			pthread_spinunlock(self, &pt_process_siglock);
 			return;
 		}
@@ -692,7 +708,7 @@
 	__sigprocmask14(SIG_SETMASK, &pt_process_sigmask, NULL);
 	pthread_spinunlock(self, &pt_process_siglock);
 
-	pthread__kill(self, target, sig, code);
+	pthread__kill(self, target, si);
 	pthread_spinunlock(self, &target->pt_siglock);
 }
 
@@ -702,28 +718,38 @@
  * Must be called with target's siglock held.
  */
 static void
-pthread__kill_self(pthread_t self, int sig, int code)
+pthread__kill_self(pthread_t self, siginfo_t *si)
 {
-	struct sigcontext xxxsc;
 	sigset_t oldmask;
 	struct sigaction act;
-	void (*handler)(int, int, struct sigcontext *);
 
 	pthread_spinlock(self, &pt_sigacts_lock);
-	act = pt_sigacts[sig];
+	act = pt_sigacts[si->si_signo];
 	pthread_spinunlock(self, &pt_sigacts_lock);
 
-	SDPRINTF(("(pthread__kill_self %p) sig %d code %d\n", self, sig, code));
+	SDPRINTF(("(pthread__kill_self %p) sig %d\n", self, si->si_signo));
 
 	oldmask = self->pt_sigmask;
 	__sigplusset(&self->pt_sigmask, &act.sa_mask);
 	if ((act.sa_flags & SA_NODEFER) == 0)
-		__sigaddset14(&self->pt_sigmask, sig);
+		__sigaddset14(&self->pt_sigmask, si->si_signo);
 
-	handler = (void (*)(int, int, struct sigcontext *)) act.sa_handler;
 
 	pthread_spinunlock(self, &self->pt_siglock);
-	handler(sig, code, &xxxsc);
+#ifdef __HAVE_SIGINFO
+	{
+		ucontext_t uc;
+		(*act.sa_sigaction)(si->si_signo, si, &uc);
+	}
+#else
+	{
+		struct sigcontext xxxsc;
+		void (*handler)(int, int, struct sigcontext *);
+		handler = (void (*)(int, int, struct sigcontext *))
+		    act.sa_handler;
+		(*handler)(si->si_signo, si->si_trap, &xxxsc);
+	}
+#endif
 	pthread_spinlock(self, &self->pt_siglock);
 
 	self->pt_sigmask = oldmask;
@@ -731,19 +757,20 @@
 
 /* Must be called with target's siglock held */
 static void
-pthread__kill(pthread_t self, pthread_t target, int sig, int code)
+pthread__kill(pthread_t self, pthread_t target, siginfo_t *si)
 {
 
-	SDPRINTF(("(pthread__kill %p) target %p sig %d code %d\n", self, target, sig, code));
+	SDPRINTF(("(pthread__kill %p) target %p sig %d code %d\n", self, target,
+	    si->si_signo));
 
-	if (__sigismember14(&target->pt_sigmask, sig)) {
+	if (__sigismember14(&target->pt_sigmask, si->si_signo)) {
 		/* Record the signal for later delivery. */
-		__sigaddset14(&target->pt_siglist, sig);
+		__sigaddset14(&target->pt_siglist, si->si_signo);
 		return;
 	}
 
 	if (self == target) {
-		pthread__kill_self(self, sig, code);
+		pthread__kill_self(self, si);
 		return;
 	}
 
@@ -778,8 +805,8 @@
 		 * again for a while. Try to wake it from its torpor, then
 		 * mark the signal for later processing.
 		 */
-		__sigaddset14(&target->pt_sigblocked, sig);
-		__sigaddset14(&target->pt_sigmask, sig);
+		__sigaddset14(&target->pt_sigblocked, si->si_signo);
+		__sigaddset14(&target->pt_sigmask, si->si_signo);
 		pthread_spinlock(self, &target->pt_flaglock);
 		target->pt_flags |= PT_FLAG_SIGDEFERRED;
 		pthread_spinunlock(self, &target->pt_flaglock);
@@ -790,21 +817,21 @@
 		;
 	}
 
-	pthread__deliver_signal(self, target, sig, code);
+	pthread__deliver_signal(self, target, si);
 	pthread__sched(self, target);
 	pthread_spinunlock(self, &target->pt_statelock);
 }
 
 /* Must be called with target's siglock held */
 void
-pthread__deliver_signal(pthread_t self, pthread_t target, int sig, int code)
+pthread__deliver_signal(pthread_t self, pthread_t target, siginfo_t *si)
 {
 	sigset_t oldmask, *maskp;
 	ucontext_t *uc, *olduc;
 	struct sigaction act;
 
 	pthread_spinlock(self, &pt_sigacts_lock);
-	act = pt_sigacts[sig];
+	act = pt_sigacts[si->si_signo];
 	pthread_spinunlock(self, &pt_sigacts_lock);
 	
 	/*
@@ -813,7 +840,7 @@
 	 */
 	oldmask = target->pt_sigmask;
 	__sigplusset(&target->pt_sigmask, &act.sa_mask);
-	__sigaddset14(&target->pt_sigmask, sig);
+	__sigaddset14(&target->pt_sigmask, si->si_signo);
 
 	if (target->pt_trapuc) {
 		olduc = target->pt_trapuc;
@@ -846,10 +873,9 @@
 	uc->uc_stack.ss_size = 0;
 	uc->uc_link = NULL;
 
-	SDPRINTF(("(makecontext %p): target %p: sig: %d %d uc: %p oldmask: %08x\n",
-	    self, target, sig, code, target->pt_uc, maskp->__bits[0]));
-	makecontext(uc, pthread__signal_tramp, 5,
-	    sig, code, act.sa_handler, olduc, maskp);
+	SDPRINTF(("(makecontext %p): target %p: sig: %d uc: %p oldmask: %08x\n",
+	    self, target, si->si_signo, target->pt_uc, maskp->__bits[0]));
+	makecontext(uc, pthread__signal_tramp, 3, act.sa_handler, si, olduc);
 	target->pt_uc = uc;
 }
 
@@ -857,12 +883,15 @@
 pthread__signal_deferred(pthread_t self, pthread_t t)
 {
 	int i;
+	siginfo_t si;
 
 	pthread_spinlock(self, &t->pt_siglock);
 
+	pthread__make_siginfo(&si, 0);
 	while ((i = firstsig(&t->pt_sigblocked)) != 0) {
 		__sigdelset14(&t->pt_sigblocked, i);
-		pthread__deliver_signal(self, t, i, 0);
+		si.si_signo = i;
+		pthread__deliver_signal(self, t, &si);
 	}
 	t->pt_flags &= ~PT_FLAG_SIGDEFERRED;
 
@@ -870,21 +899,27 @@
 }
 
 static void 
-pthread__signal_tramp(int sig, int code,
-    void (*handler)(int, int, struct sigcontext *),
-    ucontext_t *uc, sigset_t *oldmask)
+pthread__signal_tramp(void (*handler)(int, siginfo_t *, void *),
+    siginfo_t *info, ucontext_t *uc)
 {
-	struct pthread__sigcontext psc;
-
 	SDPRINTF(("(tramp %p) sig %d uc %p oldmask %08x\n", 
-	    pthread__self(), sig, uc, oldmask->__bits[0]));
+	    pthread__self(), si->si_signo, uc, uc->uc_stack.ss_mask->__bits[0]));
 
-	/*
-	 * XXX we don't support siginfo here yet.
-	 */
-	PTHREAD_UCONTEXT_TO_SIGCONTEXT(oldmask, uc, &psc);
-	handler(sig, code, &psc.psc_context);
-	PTHREAD_SIGCONTEXT_TO_UCONTEXT(&psc, uc);
+#ifdef __HAVE_SIGINFO
+	(*handler)(info->si_signo, info, uc);
+#else
+	{
+		struct pthread__sigcontext psc;
+
+		/*
+		 * XXX we don't support siginfo here yet.
+		 */
+		PTHREAD_UCONTEXT_TO_SIGCONTEXT(uc->uc_stack.ss_sp, uc, &psc);
+		(*((void *)(*)(int, int, struct sigcontext *)handler))
+		    (si->si_signo, si->si_trap, &psc.psc_context);
+		PTHREAD_SIGCONTEXT_TO_UCONTEXT(&psc, uc);
+	}
+#endif
 
 	/*
 	 * We've finished the handler, so this thread can restore the