PERFORCE change 67973 for review
David Xu
davidxu at FreeBSD.org
Fri Dec 31 06:51:57 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=67973
Change 67973 by davidxu at 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 @@
}
}
}
-
More information about the p4-projects
mailing list