sem_init and sem_destroy).
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10623
-
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <pthread.h>
#include <semaphore.h>
-
+#include <unistd.h>
/* 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
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
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;
{
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;
}
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
{
{ 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.
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
}
}
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
+}
-
/* 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_* */
#include <assert.h>
#include <unistd.h>
#include <semaphore.h>
-
+#include <stdio.h>
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 */
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;
}
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 */
/* 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
+}
-
/* 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 <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <assert.h>
-
+#include <unistd.h>
#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;
}
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 );
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
+//}