Date: Fri, 11 Jun 2004 02:28:34 -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: <1086946114.76446.16.camel@server.mcneil.com> In-Reply-To: <1086944114.76446.5.camel@server.mcneil.com> References: <Pine.GSO.4.10.10406110432370.12394-100000@pcnet5.pcnet.com> <1086944114.76446.5.camel@server.mcneil.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Sorry for top-posting, but it may be easier to read this way.... The program below has an optimization bug in that done isn't declare volatile. With that fixed, it works just fine. I've been attempting to get boehm-gc working and it seems OK with libc_r, but fails with libpthread. It is essentially doing what the program below does, but for some reason it gets stuck. Has anyone else been experimenting with boehm-gc? Also, it would really help if I had a debugger that worked with kse threads. How is that going? Tracking down pthread issues right now has been difficult with the current debugger. Can anyone throw some patches my way that may help? On Fri, 2004-06-11 at 01:55, Sean McNeil wrote: > (I've cc'd the amd64 list so here is some background) > > I'm experiencing some odd behavior with signals and threads. Daniel has > managed to isolate it to an example program that works. Except.... > > OK, so maybe this is an optimization bug. The following works fine with > no optimization, but with -O or -O2 it fails on an amd64. Can someone > test with various optimizations on i386? > > Compiled with > > cc -o test_sr test_sr.c -pthread > works > > cc -O -o test_sr test_sr.c -pthread > or > cc -O2 -o test_sr test_sr.c -pthread > hangs > > /* > * 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; > int i; > pthread_t self = pthread_self(); > > for (i=0; i<NUM_THREADS && self != tids[i]; i++); > > printf("Thread %d pausing.\n", i); > sem_post(&semaphore); > > sigfillset(&mask); > sigdelset(&mask, SIGUSR2); > sigsuspend(&mask); > printf("Thread %d successfully resumed.\n", i); > } > > static void > sighandler2(int sig, siginfo_t *info, ucontext_t *ucp) > { > int i; > pthread_t self = pthread_self(); > > for (i=0; i<NUM_THREADS && self != tids[i]; i++); > > printf("Thread %d got resume signal.\n", i); > } > > /* > * 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); > } > } > > static void * > pause_resume(void *arg) > { > int i; > > for (i = 0; i < 5; i++) { > pause_threads(); > resume_threads(); > } > > return NULL; > } > > int > main(int argc, char *argv[]) > { > pthread_t prid; > 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"); > } > > pthread_create (&prid, NULL, pause_resume, NULL); > pthread_join(prid, NULL); > > 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?1086946114.76446.16.camel>