Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Dec 2004 14:51:56 GMT
From:      David Xu <davidxu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 67973 for review
Message-ID:  <200412311451.iBVEpuAp008978@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=67973

Change 67973 by davidxu@davidxu_tiger on 2004/12/31 14:51:33

	remove unused code.
	use SIGCANCEL defined in thr_private.h to do asynchronous cancellation.

Affected files ...

.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sig.c#4 edit

Differences ...

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_sig.c#4 (text+ko) ====

@@ -43,13 +43,6 @@
 #include <pthread.h>
 #include "thr_private.h"
 
-/* Prototypes: */
-static inline void build_siginfo(siginfo_t *info, int signo);
-static inline void thr_sigframe_restore(struct pthread *thread,
-	struct pthread_sigframe *psf);
-static inline void thr_sigframe_save(struct pthread *thread,
-	struct pthread_sigframe *psf);
-
 /* #define DEBUG_SIGNAL */
 #ifdef DEBUG_SIGNAL
 #define DBG_MSG		stdout_debug
@@ -59,11 +52,11 @@
 
 typedef void (*ohandler)(int sig, int code,
 	struct sigcontext *scp, char *addr, __sighandler_t *catcher);
+static void thr_cancel_handler(struct pthread *);
 
 void
 _thr_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
 {
-	struct pthread_sigframe psf;
 	__siginfohandler_t *sigfunc;
 	struct pthread *curthread;
 	struct sigaction act;
@@ -76,7 +69,7 @@
 	curthread = _get_curthread();
 	if (curthread == NULL)
 		PANIC("No current thread.\n");
-	if (curthread->flags & THR_FLAGS_EXITING) {
+	if (curthread->state == PS_DEAD) {
 		errno = err_save;
 		return;
 	}
@@ -85,40 +78,27 @@
 	 * If thread is in critical region or if thread is on
 	 * the way of state transition, then latch signal into buffer.
 	 */
-	if (THR_IN_CRITICAL(curthread) || curthread->state != PS_RUNNING ||
-	    curthread->lock_switch != 0 || curthread->idle != 0) {
+	if (THR_IN_CRITICAL(curthread)) {
 		DBG_MSG(">>> _thr_sig_handler(%d) in critical\n", sig);
 		curthread->siginfo[sig-1] = *info;
 		curthread->check_pending = 1;
-		curthread->sigseqno++;
 		SIGADDSET(curthread->sigpend, sig);
-		/* 
-		 * If the thread is on the way to idle itself, but
-		 * we have signal ready, we should prevent it
-		 * to sleep, kernel will latch the wakeup request,
-		 * so thr_suspend will return from kernel immediately.
-		 */
-		if (curthread->idle)
-			thr_wake(curthread->tid);
 		errno = err_save;
 		return;
 	}
 
-	/* Check if the signal requires a dump of thread information: */
-	if (sig == SIGINFO) {
-		/* Dump thread information to file: */
-		_thread_dump_info();
-	}
-
 	/* Check the threads previous state: */
 	curthread->critical_count++;
 	if (curthread->sigbackout != NULL)
 		curthread->sigbackout((void *)curthread);
 	curthread->critical_count--;
-	thr_sigframe_save(curthread, &psf);
+
+	if (sig == SIGCANCEL)
+		thr_cancel_handler(curthread);
 
 	THR_ASSERT(!(curthread->sigbackout), "sigbackout was not cleared.");
 
+	/* Reset signal handler if needed */
 	THR_LOCK_ACQUIRE(curthread, &_thread_signal_lock);
 	sigfunc = _thread_sigact[sig - 1].sa_sigaction;
 	sa_flags = _thread_sigact[sig - 1].sa_flags;
@@ -142,25 +122,17 @@
 				sig, info->si_code, (struct sigcontext *)ucp,
 				info->si_addr, (__sighandler_t *)sigfunc);
 		}
-	} else if ((__sighandler_t *)sigfunc == SIG_DFL) {
-			thr_kill(curthread->tid, sig);
+	} else if (sig != SIGCANCEL && (__sighandler_t *)sigfunc == SIG_DFL) {
+		thr_kill(curthread->tid, sig);
 	}
 
-	thr_sigframe_restore(curthread, &psf);
+	SIGDELSET(ucp->uc_sigmask, SIGCANCEL);
 
 	DBG_MSG("<<< _thr_sig_handler(%d)\n", sig);
 
 	errno = err_save;
 }
 
-static inline void
-build_siginfo(siginfo_t *info, int signo)
-{
-	bzero(info, sizeof(*info));
-	info->si_signo = signo;
-	info->si_pid = _thr_pid;
-}
-
 /*
  * This is called by a thread when it has pending signals to deliver.
  * It should only be called from the context of the thread.
@@ -169,7 +141,7 @@
 _thr_sig_rundown(struct pthread *curthread)
 {
 	int i, err_save;
-	sigset_t sigmask;
+	sigset_t sigmask, oldmask;
 
 	err_save = errno;
 
@@ -178,7 +150,7 @@
 	SIGFILLSET(sigmask);
 	/* repost signal to kernel */
 	if (!SIGISEMPTY(curthread->sigpend)) {
-		__sys_sigprocmask(SIG_SETMASK, &sigmask, &curthread->sigmask);
+		__sys_sigprocmask(SIG_SETMASK, &sigmask, &oldmask);
 		for (i = 1; i <= _SIG_MAXSIG; ++i) {
 			if (SIGISMEMBER(curthread->sigpend, i)) {
 				SIGDELSET(curthread->sigpend, i);
@@ -188,35 +160,21 @@
 					thr_kill(curthread->tid, i);
 			}
 		}
-		__sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL);
+		__sys_sigprocmask(SIG_SETMASK, &oldmask, NULL);
 	}
 	DBG_MSG("<<< thr_sig_rundown (%p)\n", curthread);
 	errno = err_save;
 }
 
 /*
- * This checks pending signals for the current thread.  It should be
- * called whenever a thread changes its signal mask.  Note that this
- * is called from a thread (using its stack).
- *
- * XXX - We might want to just check to see if there are pending
- *       signals for the thread here, but enter the UTS scheduler
- *       to actually install the signal handler(s).
+ * This checks pending signals for the current thread.
  */
 void
 _thr_sig_check_pending(struct pthread *curthread)
 {
 	int errsave;
 
-	/*
-	 * If the thread is in critical region, delay processing signals.
-	 * If the thread state is not PS_RUNNING, it might be switching
-	 * into UTS and but a THR_LOCK_RELEASE saw check_pending, and it
-	 * goes here, in the case we delay processing signals, lets UTS
-	 * process complicated things, normally UTS will call _thr_sig_add
-	 * to resume the thread, so we needn't repeat doing it here.
-	 */
-	if (THR_IN_CRITICAL(curthread) || curthread->lock_switch)
+	if (THR_IN_CRITICAL(curthread))
 		return;
 
 	errsave = errno;
@@ -225,137 +183,51 @@
 	errno = errsave;
 }
 
-/*
- * Perform thread specific actions in response to a signal.
- * This function is only called if there is a handler installed
- * for the signal, and if the target thread has the signal
- * unmasked.
- *
- * This must be called with the thread's scheduling lock held.
- */
-long
-_thr_sig_add(struct pthread *pthread, int sig, siginfo_t *info)
+static void
+thr_cancel_handler(struct pthread *curthread)
 {
-	struct pthread *curthread = _get_curthread();
-	long	tid = -1;
-	int	suppress_handler = 0;
-	__sighandler_t *sigfunc;
-
-	DBG_MSG(">>> _thr_sig_add %p (%d)\n", pthread, sig);
-
-	sigfunc = _thread_sigact[sig - 1].sa_handler;
-
-	if (pthread->state == PS_DEAD || pthread->state == PS_DEADLOCK ||
-	    pthread->state == PS_STATE_MAX)
-	    	return (-1); /* return false */
-
-	if (curthread != pthread) {
-	    	PANIC("Please use _thr_send_sig for bound thread");
-		return (-1);
+	if ((curthread->cancelflags &
+	     (THR_CANCEL_AT_POINT | THR_CANCEL_ASYNCHRONOUS))) {
+		pthread_testcancel();
 	}
+	_thr_suspend_check(curthread);
+}
 
-	if (SIGISMEMBER(pthread->sigmask, sig) || THR_IN_CRITICAL(pthread)) {
-		/* signal is masked, just add signal to thread. */
-		SIGADDSET(pthread->sigpend, sig);
-		if (info == NULL)
-			build_siginfo(&pthread->siginfo[sig-1], sig);
-		else if (info != &pthread->siginfo[sig-1])
-			memcpy(&pthread->siginfo[sig-1], info,
-				 sizeof(*info));
-		if (!SIGISMEMBER(pthread->sigmask, sig))
-			pthread->check_pending = 1;
-	} else {
-		/*
-		 * Process according to thread state:
-		 */
-		switch (pthread->state) {
-		case PS_DEAD:
-		case PS_DEADLOCK:
-		case PS_STATE_MAX:
-			return (-1);	/* XXX return false */
-		case PS_SUSPENDED:
-			/*
-			 * You can't call a signal handler for threads in these
-			 * states.
-			 */
-			suppress_handler = 1;
-			break;
-		case PS_RUNNING:
-			/* Possible not in RUNQ and has curframe ? */
-			/* pthread->active_priority |= THR_SIGNAL_PRIORITY; */
-			break;
-		/*
-		 * States which cannot be interrupted but still require the
-		 * signal handler to run:
-		 */
-		case PS_MUTEX_WAIT:
-			break;
 
-		case PS_JOIN:
-			break;
-		}
-
-		SIGADDSET(pthread->sigpend, sig);
-		if (info == NULL)
-			build_siginfo(&pthread->siginfo[sig-1], sig);
-		else if (info != &pthread->siginfo[sig-1])
-			memcpy(&pthread->siginfo[sig-1], info, sizeof(*info));
-		pthread->check_pending = 1;
-		if (suppress_handler == 0) {
-			if (pthread->state != PS_RUNNING)
-				tid = _thr_setrunnable_unlocked(pthread);
-		}
-	}
-	return (tid);
-}
-
-/*
- * Send a signal to a specific thread (ala pthread_kill):
- */
 void
-_thr_sig_send(struct pthread *pthread, int sig)
+_thr_suspend_check(struct pthread *curthread)
 {
-	thr_kill(pthread->tid, sig);
-}
+#if 0
+	sigset_t set;
+	long cycle;
 
-static inline void
-thr_sigframe_restore(struct pthread *curthread, struct pthread_sigframe *psf)
-{
+	/* Async suspend. */
 	THR_LOCK(curthread);
-	curthread->cancelflags = (psf->psf_cancelflags |
-				  (curthread->cancelflags &
-				   (THR_CANCEL_NEEDED | THR_CANCELLING)));
-	curthread->flags = psf->psf_flags;
-	curthread->interrupted = psf->psf_interrupted;
-	curthread->timeout = psf->psf_timeout;
-	curthread->data = psf->psf_wait_data;
-	curthread->wakeup_time = psf->psf_wakeup_time;
-	curthread->continuation = psf->psf_continuation;
+	if ((curthread->flags & (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED))
+		== THR_FLAGS_NEED_SUSPEND) {
+		curthread->flags |= THR_FLAGS_SUSPENDED;
+		SIGEMPTYSET(set);
+		SIGADDSET(set, SIGCANCEL);
+		__sys_sigprocmask(SIG_UNBLOCK, &set, NULL);
+		while (curthread->flags & THR_FLAGS_NEED_SUSPEND) {
+			cycle = curthread->cycle;
+			THR_UNLOCK(curthread);
+			umtx_wait((struct umtx *)&curthread->cycle, cycle);
+			THR_LOCK(curthread);
+		}
+		curthread->flags &= ~THR_FLAGS_SUSPENDED;
+	}
 	THR_UNLOCK(curthread);
+#endif
 }
 
-static inline void
-thr_sigframe_save(struct pthread *curthread, struct pthread_sigframe *psf)
-{
-	THR_LOCK(curthread);
-	psf->psf_cancelflags = curthread->cancelflags;
-	/* This has to initialize all members of the sigframe. */
-	psf->psf_flags = (curthread->flags & (THR_FLAGS_PRIVATE | THR_FLAGS_EXITING));
-	psf->psf_interrupted = curthread->interrupted;
-	psf->psf_timeout = curthread->timeout;
-	psf->psf_wait_data = curthread->data;
-	psf->psf_wakeup_time = curthread->wakeup_time;
-	psf->psf_continuation = curthread->continuation;
-	THR_UNLOCK(curthread);
-}
-
 void
 _thr_signal_init(void)
 {
 	struct sigaction act;
 	__siginfohandler_t *sigfunc;
+	int i;
 
-	int i;
 	/* Enter a loop to get the existing signal status: */
 	for (i = 1; i <= _SIG_MAXSIG; i++) {
 		/* Get the signal handler details: */
@@ -377,16 +249,12 @@
 			__sys_sigaction(i, &act, NULL);
 		}
 	}
-	/*
-	 * Install the signal handler for SIGINFO.  It isn't
-	 * really needed, but it is nice to have for debugging
-	 * purposes.
-	 */
-	_thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART;
+	/* Install cancel handler. */
+	_thread_sigact[SIGCANCEL - 1].sa_flags = SA_SIGINFO | SA_RESTART;
 	SIGEMPTYSET(act.sa_mask);
 	act.sa_flags = SA_SIGINFO | SA_RESTART;
 	act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler;
-	__sys_sigaction(SIGINFO, &act, NULL);
+	__sys_sigaction(SIGCANCEL, &act, NULL);
 }
 
 void
@@ -411,4 +279,3 @@
 		}
 	}
 }
-



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200412311451.iBVEpuAp008978>