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;
}