On Mon, Mar 17, 2008 at 04:33:34PM +0100, Andreas Bihlmaier wrote: > Hello misc@, > > doing some C programming with threads (yeah *ugh*), I discovered a > strange issue. > > There seems to be some problem using "static mutexes" (a mutex not > created by pthread_mutex_init()). > > Here is some test code which works very well on linux, but gives: > ------> (ID:2238337024) > First > mutex_prob: thread1: pthread_mutex_unlock() (0): Undefined error: 0 > > on OpenBSD. > > The output should look like: > ------> (ID:<somenumber>) > First > Second > Thread <somenumber2> done > Thread <somenumber3> done > <------ (ID:<somenumber>) > > the mutex is looked by the main-thread and only thread1 may print > without locking the mutex first, thus "First" will always be printed > first. > > If this is not a bug, perhaps somebody can point out the API difference > between OpenBSD and Linux I missed. > > Regards > ahb > > > Test code: Correct test code (on #openbsd oenoene just pointed out to me that errno does not get set (doh!)): #include <err.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h>
/* static Mutex-Variable */ static pthread_mutex_t fz_mutex = PTHREAD_MUTEX_INITIALIZER; static void thread1(void *name) { int ret; printf("First\n"); /* free Mutex */ if ((ret = pthread_mutex_unlock(&fz_mutex)) != 0) errx(1, "thread1: pthread_mutex_unlock() (return: %d)", ret); /* thread end */ pthread_exit((void *)pthread_self()); } static void thread2(void *name) { int ret; /* lock Mutex */ pthread_mutex_lock(&fz_mutex); printf("Second\n"); /* free Mutex again */ if ((ret = pthread_mutex_unlock(&fz_mutex)) != 0) errx(1, "thread2: pthread_mutex_unlock() (return: %d)", ret); /* thread end */ pthread_exit((void *)pthread_self()); } int main(void) { static pthread_t th1, th2; static int ret1, ret2; /* main thread */ printf("\n------> (ID:%lu)\n", pthread_self()); /* lock mutex */ pthread_mutex_lock(&fz_mutex); /* Threads erzeugen */ if (pthread_create(&th1, NULL, (void *)&thread1,NULL) != 0) err(1, "pthread_create(th1)"); if (pthread_create(&th2, NULL, (void *)&thread2,NULL) != 0) err(1, "pthread_create(th2)"); /* Wait for both threads to finish */ pthread_join(th1, (void *)&ret1); pthread_join(th2, (void *)&ret2); printf("Thread %lu done\n", th1); printf("Thread %lu done\n", th2); printf("<----- (ID: %lu)\n", pthread_self()); return EXIT_SUCCESS; }