Add fairly complete, and apparently working, support for condition
variables.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@102 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/vg_libpthread.c b/vg_libpthread.c
index 435b7e2..3ecd6f1 100644
--- a/vg_libpthread.c
+++ b/vg_libpthread.c
@@ -87,6 +87,7 @@
 
 
 static
+__attribute__((noreturn))
 void barf ( char* str )
 {
    char buf[100];
@@ -96,6 +97,8 @@
    strcat(buf, "\n\n");
    write(2, buf, strlen(buf));
    myexit(1);
+   /* We have to persuade gcc into believing this doesn't return. */
+   while (1) { };
 }
 
 
@@ -175,6 +178,18 @@
 }
 
 
+void pthread_exit(void *retval)
+{
+   int res;
+   ensure_valgrind("pthread_exit");
+   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
+                           VG_USERREQ__PTHREAD_EXIT,
+                           retval, 0, 0, 0);
+   /* Doesn't return! */
+   /* However, we have to fool gcc into knowing that. */
+   barf("pthread_exit: still alive after request?!");
+}
+
 
 static int thread_specific_errno[VG_N_THREADS];
 
@@ -324,6 +339,36 @@
    return 0;
 }
 
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+   int res;
+   ensure_valgrind("pthread_cond_wait");
+   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
+                           VG_USERREQ__PTHREAD_COND_WAIT,
+			   cond, mutex, 0, 0);
+   return res;
+}
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+   int res;
+   ensure_valgrind("pthread_cond_signal");
+   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
+                           VG_USERREQ__PTHREAD_COND_SIGNAL,
+			   cond, 0, 0, 0);
+   return res;
+}
+
+int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+   int res;
+   ensure_valgrind("pthread_cond_broadcast");
+   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
+                           VG_USERREQ__PTHREAD_COND_BROADCAST,
+			   cond, 0, 0, 0);
+   return res;
+}
+
 
 /* ---------------------------------------------------
    CANCELLATION