From owner-freebsd-threads@FreeBSD.ORG Fri Jun 11 08:16:22 2004 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8243416A4CE; Fri, 11 Jun 2004 08:16:22 +0000 (GMT) Received: from mail.mcneil.com (rrcs-west-24-199-45-54.biz.rr.com [24.199.45.54]) by mx1.FreeBSD.org (Postfix) with ESMTP id 46B8743D5D; Fri, 11 Jun 2004 08:16:22 +0000 (GMT) (envelope-from sean@mcneil.com) Received: from localhost (localhost.mcneil.com [127.0.0.1]) by mail.mcneil.com (Postfix) with ESMTP id 913F1FD087; Fri, 11 Jun 2004 01:16:20 -0700 (PDT) Received: from mail.mcneil.com ([127.0.0.1]) by localhost (server.mcneil.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 28084-05; Fri, 11 Jun 2004 01:16:20 -0700 (PDT) Received: from [24.199.45.54] (mcneil.com [24.199.45.54]) by mail.mcneil.com (Postfix) with ESMTP id 11FADFD075; Fri, 11 Jun 2004 01:16:20 -0700 (PDT) From: Sean McNeil To: Daniel Eischen In-Reply-To: References: Content-Type: text/plain Message-Id: <1086941779.10026.38.camel@server.mcneil.com> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.6 Date: Fri, 11 Jun 2004 01:16:20 -0700 Content-Transfer-Encoding: 7bit X-Virus-Scanned: by amavisd-new at mcneil.com cc: David Xu cc: freebsd-threads@freebsd.org Subject: Re: signal handler priority issue X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Jun 2004 08:16:22 -0000 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 #include #include #include #include #include #include #include #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); }