Date: Fri, 11 Jun 2004 01:16:20 -0700 From: Sean McNeil <sean@mcneil.com> To: Daniel Eischen <eischen@vigrid.com> Cc: freebsd-threads@freebsd.org Subject: Re: signal handler priority issue Message-ID: <1086941779.10026.38.camel@server.mcneil.com> In-Reply-To: <Pine.GSO.4.10.10406110313540.3491-100000@pcnet5.pcnet.com> References: <Pine.GSO.4.10.10406110313540.3491-100000@pcnet5.pcnet.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Now here is something odd.... If I change the program a little, it acts completely different. It actually works faster and looks correct. I don't get it. This is pretty much exactly what boehm-gc is doing. /* * test_sr.c * * Demonstrate use of signals & semaphores for suspending and * resuming threads. */ #include <errno.h> #include <pthread.h> #include <semaphore.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <ucontext.h> #include <unistd.h> #ifndef NUM_THREADS #define NUM_THREADS 5 #endif static sem_t semaphore; static int done = 0; static pthread_t tids[NUM_THREADS]; static void errno_abort(char *msg) { printf("%s, errno %d\n", msg, errno); abort(); } static void err_abort(int status, char *msg) { printf("%s, status %d\n", msg, status); abort(); } static void sighandler1(int sig, siginfo_t *info, ucontext_t *ucp) { sigset_t mask; printf("Thread %p pausing.\n", pthread_self()); sigfillset(&mask); sigdelset(&mask, SIGUSR2); sem_post(&semaphore); sigsuspend(&mask); printf("Thread %p successfully resumed.\n", pthread_self()); } static void sighandler2(int sig, siginfo_t *info, ucontext_t *ucp) { printf("Thread %p got resume signal.\n", pthread_self()); } /* * Thread start routine to wait on a semaphore. */ static void * worker(void *arg) { int num = (int)arg; int x; num = (int)arg; x = num * 10; printf ("Thread %d starting.\n", num); while (!done) { x = x + 1; x = x - 1; } printf("Thread %d stopping.\n", num); return (NULL); } static void pause_threads(void) { int i; printf("Master: pausing all threads.\n"); for (i = 0; i < NUM_THREADS; i++) { pthread_kill(tids[i], SIGUSR1); } for (i = 0; i < NUM_THREADS; i++) { if (sem_wait(&semaphore) == -1) errno_abort("Wait on semaphore"); } } static void resume_threads(void) { int i; printf("Master: resuming all threads.\n"); for (i = 0; i < NUM_THREADS; i++) { pthread_kill(tids[i], SIGUSR2); } } int main(int argc, char *argv[]) { struct sigaction act; int status; int i; if (sem_init (&semaphore, 0, 0) == -1) errno_abort ("Init semaphore"); /* Mask all signals while in the signal handler. */ sigfillset(&act.sa_mask); act.sa_flags = SA_RESTART; act.sa_handler = sighandler1; sigaction(SIGUSR1, &act, NULL); act.sa_handler = sighandler2; sigaction(SIGUSR2, &act, NULL); /* * Create some worker threads. */ for (i = 0; i < NUM_THREADS; i++) { status = pthread_create(&tids[i], NULL, worker, (void *)i); if (status != 0) err_abort (status, "Create thread"); } sleep (1); for (i = 0; i < 5; i++) { pause_threads(); resume_threads(); } done = 1; /* * Wait for all threads to complete. */ for (i = 0; i < NUM_THREADS; i++) { status = pthread_join(tids[i], NULL); if (status != 0) err_abort(status, "Join thread"); } return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1086941779.10026.38.camel>