From: Julian Seward Date: Sun, 26 Jul 2009 19:53:42 +0000 (+0000) Subject: Portability fixes for Darwin (use sem_open and sem_close rather than X-Git-Tag: svn/VALGRIND_3_5_0~225 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c6991c8fd7f18d037b42fa65bf91d9303db0ccb9;p=thirdparty%2Fvalgrind.git Portability fixes for Darwin (use sem_open and sem_close rather than sem_init and sem_destroy). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10623 --- diff --git a/helgrind/tests/tc17_sembar.c b/helgrind/tests/tc17_sembar.c index cc91f5e0b1..1113a67672 100644 --- a/helgrind/tests/tc17_sembar.c +++ b/helgrind/tests/tc17_sembar.c @@ -1,10 +1,9 @@ - #include #include #include #include #include - +#include /* This is really a test of semaphore handling (sem_{init,destroy,post,wait}). Using semaphores a barrier function is created. Helgrind-3.3 (p.k.a Thrcheck) does understand @@ -12,7 +11,6 @@ from happens-before relationships obtained from the component semaphores. However, it does falsely report one race. Ah well. Helgrind-3.4 is pure h-b and so reports no races (yay!). */ - /* This code is derived from gcc-4.3-20071012/libgomp/config/posix/bar.c, which is @@ -27,7 +25,9 @@ but it is used to create enough extra inter-thread dependencies that the barrier-like behaviour of gomp_barrier_t is evident to Thrcheck. There is no other purpose for the .xxx field. */ - +static int my_sem_init(sem_t*, char*, int, unsigned); +static int my_sem_destroy(sem_t*); +static int my_sem_wait(sem_t*); static int my_sem_post(sem_t*); typedef struct { pthread_mutex_t mutex1; @@ -46,9 +46,9 @@ gomp_barrier_init (gomp_barrier_t *bar, unsigned count) { pthread_mutex_init (&bar->mutex1, NULL); pthread_mutex_init (&bar->mutex2, NULL); - sem_init (&bar->sem1, 0, 0); - sem_init (&bar->sem2, 0, 0); - sem_init (&bar->xxx, 0, 0); + my_sem_init (&bar->sem1, "sem1", 0, 0); + my_sem_init (&bar->sem2, "sem2", 0, 0); + my_sem_init (&bar->xxx, "xxx", 0, 0); bar->total = count; bar->arrived = 0; } @@ -62,9 +62,9 @@ gomp_barrier_destroy (gomp_barrier_t *bar) pthread_mutex_destroy (&bar->mutex1); pthread_mutex_destroy (&bar->mutex2); - sem_destroy (&bar->sem1); - sem_destroy (&bar->sem2); - sem_destroy(&bar->xxx); + my_sem_destroy (&bar->sem1); + my_sem_destroy (&bar->sem2); + my_sem_destroy(&bar->xxx); } void @@ -91,20 +91,20 @@ gomp_barrier_wait (gomp_barrier_t *bar) { { unsigned int i; for (i = 0; i < n; i++) - sem_wait(&bar->xxx); // acquire an obvious dependency from + my_sem_wait(&bar->xxx); // acquire an obvious dependency from // all other threads arriving at the barrier } // 1 up n times, 2 down once // now let all the other threads past the barrier, giving them // an obvious dependency with this thread. do - sem_post (&bar->sem1); // 1 up + my_sem_post (&bar->sem1); // 1 up while (--n != 0); // and wait till the last thread has left - sem_wait (&bar->sem2); // 2 down + my_sem_wait (&bar->sem2); // 2 down } pthread_mutex_unlock (&bar->mutex1); - /* «Résultats professionnels!» First we made this thread have an + /* «Resultats professionnels!» First we made this thread have an obvious (Thrcheck-visible) dependency on all other threads calling gomp_barrier_wait. Then, we released them all again, so they all have a (visible) dependency on this thread. @@ -115,16 +115,16 @@ gomp_barrier_wait (gomp_barrier_t *bar) else { pthread_mutex_unlock (&bar->mutex1); - sem_post(&bar->xxx); + my_sem_post(&bar->xxx); // first N-1 threads wind up waiting here - sem_wait (&bar->sem1); // 1 down + my_sem_wait (&bar->sem1); // 1 down pthread_mutex_lock (&bar->mutex2); n = --bar->arrived; /* XXX see below */ pthread_mutex_unlock (&bar->mutex2); if (n == 0) - sem_post (&bar->sem2); // 2 up + my_sem_post (&bar->sem2); // 2 up } } @@ -211,3 +211,65 @@ int main (int argc, char *argv[]) return 0; } + + + + + + + +static int my_sem_init (sem_t* s, char* identity, int pshared, unsigned count) +{ +#if defined(VGO_linux) + return sem_init(s, pshared, count); +#elif defined(VGO_darwin) + char name[100]; + sem_t** fakeptr = (sem_t**)s; + assert(sizeof(sem_t) >= sizeof(sem_t*)); + { int i; for (i = 0; i < sizeof(name); i++) name[i] = 0; } + sprintf(name, "anonsem_%s_pid%d", identity, (int)getpid()); + name[ sizeof(name)-1 ] = 0; + if (0) printf("name = %s\n", name); + *fakeptr = sem_open(name, O_CREAT, 0600, count); + if (*fakeptr == (sem_t*)SEM_FAILED) + return -1; + else + return 0; +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_destroy ( sem_t* s ) +{ +#if defined(VGO_linux) + return sem_destroy(s); +#elif defined(VGO_darwin) + sem_t** fakeptr = (sem_t**)s; + return sem_close(*fakeptr); +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_wait(sem_t* s) +{ +#if defined(VGO_linux) + return sem_wait(s); +#elif defined(VGO_darwin) + return sem_wait( *(sem_t**)s ); +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_post(sem_t* s) +{ +#if defined(VGO_linux) + return sem_post(s); +#elif defined(VGO_darwin) + return sem_post( *(sem_t**)s ); +#else +# error "Unsupported OS" +#endif +} diff --git a/helgrind/tests/tc23_bogus_condwait.c b/helgrind/tests/tc23_bogus_condwait.c index a0fad5d5d7..77276a183c 100644 --- a/helgrind/tests/tc23_bogus_condwait.c +++ b/helgrind/tests/tc23_bogus_condwait.c @@ -1,4 +1,3 @@ - /* Expect 5 errors total (4 re cvs, 1 re exiting w/lock.). Tests passing bogus mutexes to pthread_cond_wait. */ #define _GNU_SOURCE 1 /* needed by glibc <= 2.3 for pthread_rwlock_* */ @@ -6,13 +5,14 @@ #include #include #include - +#include pthread_mutex_t mx[4]; pthread_cond_t cv; pthread_rwlock_t rwl; - sem_t quit_now; - +static int my_sem_init(sem_t*, char*, int, unsigned); +static int my_sem_destroy(sem_t*); +static int my_sem_wait(sem_t*); static int my_sem_post(sem_t*); void* rescue_me ( void* uu ) { /* wait for, and unblock, the first wait */ @@ -31,14 +31,14 @@ void* rescue_me ( void* uu ) sleep(1); pthread_cond_signal( &cv ); - sem_wait( &quit_now ); + my_sem_wait( &quit_now ); return NULL; } void* grab_the_lock ( void* uu ) { int r= pthread_mutex_lock( &mx[2] ); assert(!r); - sem_wait( &quit_now ); + my_sem_wait( &quit_now ); r= pthread_mutex_unlock( &mx[2] ); assert(!r); return NULL; } @@ -56,7 +56,7 @@ int main ( void ) r= pthread_cond_init(&cv, NULL); assert(!r); r= pthread_rwlock_init(&rwl, NULL); assert(!r); - r= sem_init( &quit_now, 0,0 ); assert(!r); + r= my_sem_init( &quit_now, "quit_now", 0,0 ); assert(!r); r= pthread_create( &grabber, NULL, grab_the_lock, NULL ); assert(!r); sleep(1); /* let the grabber get there first */ @@ -77,10 +77,75 @@ int main ( void ) /* mx is held by someone else. */ r= pthread_cond_wait(&cv, &mx[2] ); - r= sem_post( &quit_now ); assert(!r); - r= sem_post( &quit_now ); assert(!r); + r= my_sem_post( &quit_now ); assert(!r); + r= my_sem_post( &quit_now ); assert(!r); r= pthread_join( my_rescuer, NULL ); assert(!r); r= pthread_join( grabber, NULL ); assert(!r); + + r= my_sem_destroy( &quit_now ); assert(!r); return 0; } + + + + + + + + +static int my_sem_init (sem_t* s, char* identity, int pshared, unsigned count) +{ +#if defined(VGO_linux) + return sem_init(s, pshared, count); +#elif defined(VGO_darwin) + char name[100]; + sem_t** fakeptr = (sem_t**)s; + assert(sizeof(sem_t) >= sizeof(sem_t*)); + { int i; for (i = 0; i < sizeof(name); i++) name[i] = 0; } + sprintf(name, "anonsem_%s_pid%d", identity, (int)getpid()); + name[ sizeof(name)-1 ] = 0; + if (0) printf("name = %s\n", name); + *fakeptr = sem_open(name, O_CREAT, 0600, count); + if (*fakeptr == (sem_t*)SEM_FAILED) + return -1; + else + return 0; +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_destroy ( sem_t* s ) +{ +#if defined(VGO_linux) + return sem_destroy(s); +#elif defined(VGO_darwin) + sem_t** fakeptr = (sem_t**)s; + return sem_close(*fakeptr); +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_wait(sem_t* s) +{ +#if defined(VGO_linux) + return sem_wait(s); +#elif defined(VGO_darwin) + return sem_wait( *(sem_t**)s ); +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_post(sem_t* s) +{ +#if defined(VGO_linux) + return sem_post(s); +#elif defined(VGO_darwin) + return sem_post( *(sem_t**)s ); +#else +# error "Unsupported OS" +#endif +} diff --git a/helgrind/tests/tc24_nonzero_sem.c b/helgrind/tests/tc24_nonzero_sem.c index 01c23e811a..e88ab5c8f1 100644 --- a/helgrind/tests/tc24_nonzero_sem.c +++ b/helgrind/tests/tc24_nonzero_sem.c @@ -1,20 +1,20 @@ - /* Check that Helgrind does not complain about semaphores with a nonzero initial value, when said semaphores are correctly used. Also useful for generating VCG of simple semaphore activity, for inspection. */ - +#include #include #include #include - +#include #define N_THREADS 3 - -void* child_fn ( void* semV ) -{ +static int my_sem_init(sem_t*, char*, int, unsigned); +static int my_sem_destroy(sem_t*); +static int my_sem_wait(sem_t*); //static int my_sem_post(sem_t*); +void* child_fn ( void* semV ) { int r; sem_t* sem = (sem_t*)semV; - r= sem_wait(sem); assert(!r); + r= my_sem_wait(sem); assert(!r); return NULL; } @@ -24,7 +24,7 @@ int main ( void ) sem_t sem; pthread_t child[N_THREADS]; - r= sem_init(&sem, 0, N_THREADS); assert(!r); + r= my_sem_init(&sem, "sem1", 0, N_THREADS); assert(!r); for (i = 0; i < N_THREADS; i++) { r= pthread_create( &child[i], NULL, child_fn, (void*)&sem ); @@ -36,6 +36,63 @@ int main ( void ) assert(!r); } - sem_destroy(&sem); + r= my_sem_destroy(&sem); assert(!r); return 0; } + + +static int my_sem_init (sem_t* s, char* identity, int pshared, unsigned count) +{ +#if defined(VGO_linux) + return sem_init(s, pshared, count); +#elif defined(VGO_darwin) + char name[100]; + sem_t** fakeptr = (sem_t**)s; + assert(sizeof(sem_t) >= sizeof(sem_t*)); + { int i; for (i = 0; i < sizeof(name); i++) name[i] = 0; } + sprintf(name, "anonsem_%s_pid%d", identity, (int)getpid()); + name[ sizeof(name)-1 ] = 0; + if (0) printf("name = %s\n", name); + *fakeptr = sem_open(name, O_CREAT, 0600, count); + if (*fakeptr == (sem_t*)SEM_FAILED) + return -1; + else + return 0; +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_destroy ( sem_t* s ) +{ +#if defined(VGO_linux) + return sem_destroy(s); +#elif defined(VGO_darwin) + sem_t** fakeptr = (sem_t**)s; + return sem_close(*fakeptr); +#else +# error "Unsupported OS" +#endif +} + +static int my_sem_wait(sem_t* s) +{ +#if defined(VGO_linux) + return sem_wait(s); +#elif defined(VGO_darwin) + return sem_wait( *(sem_t**)s ); +#else +# error "Unsupported OS" +#endif +} + +//static int my_sem_post(sem_t* s) +//{ +//#if defined(VGO_linux) +// return sem_post(s); +//#elif defined(VGO_darwin) +// return sem_post( *(sem_t**)s ); +//#else +//# error "Unsupported OS" +//#endif +//}