/* $Id: mtxloop.c,v 1.2 2012/09/21 10:27:27 kostik Exp kostik $ */ #include #include #include #include #include #include #include #include #define THRN 10 static unsigned long counter; static void siginfo_handler(int signo __unused) { } static void * worker(void *arg) { pthread_mutex_t *mtx; int error; mtx = arg; for (;;) { error = pthread_mutex_lock(mtx); if (error != 0) errc(1, error, "pthread_mutex_lock"); error = pthread_mutex_unlock(mtx); if (error != 0) errc(1, error, "pthread_mutex_unlock"); atomic_add_long(&counter, 1); } return (NULL); } int main(void) { pthread_t t[THRN]; pthread_mutex_t mtx; sigset_t sigs; struct sigaction sa; int error, i, sig; bzero(&sa, sizeof(sa)); sa.sa_handler = siginfo_handler; if (sigaction(SIGINFO, &sa, NULL) == -1) err(1, "sigaction"); sigemptyset(&sigs); sigaddset(&sigs, SIGINFO); sigaddset(&sigs, SIGTERM); sigaddset(&sigs, SIGINT); error = pthread_sigmask(SIG_BLOCK, &sigs, NULL); if (error != 0) errc(1, error, "pthread_sigmask"); error = pthread_mutex_init(&mtx, NULL); if (error != 0) errc(1, error, "pthread_mutex_init"); for (i = 0; i < THRN; i++) { error = pthread_create(&t[i], NULL, worker, &mtx); if (error != 0) errc(1, error, "pthread_create %d", i); } for (;;) { error = sigwait(&sigs, &sig); if (error != 0) errc(1, error, "sigwait"); switch (sig) { case SIGINFO: printf("Loop counter %lu\n", counter); break; default: return (0); } } return (0); }