Continue trying to extract myself from the pthread_mutex_* swamp.

Fall back to a compromise position, which makes my mutex implementation
initialiser- and structure-compatible with LinuxThreads, and ditto the
upcoming condition var implementation.  In particular this means that
((ThreadId)0) is an invalid thread ID, so vg_threads[0] is never used,
and vg_threads[1] specially denotes the "main" thread.

Remove the scheme of having a linked list of threads waiting on
each mutex.  It is too difficult to get the right semantics for
when a signal is delivered to a thread blocked in pthread_mutex_lock().
Instead, use the old scheme of each thread stating with its .waited_on_mx
field, which mutex it is waiting for.  This makes pthread_mutex_unlock()
less efficient, but at least it all works.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@100 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/vg_libpthread.c b/vg_libpthread.c
index e910ccf..435b7e2 100644
--- a/vg_libpthread.c
+++ b/vg_libpthread.c
@@ -141,6 +141,12 @@
    THREADs
    ------------------------------------------------ */
 
+int pthread_equal(pthread_t thread1, pthread_t thread2)
+{
+   return thread1 == thread2 ? 1 : 0;
+}
+
+
 int
 pthread_create (pthread_t *__restrict __thread,
                 __const pthread_attr_t *__restrict __attr,
@@ -269,11 +275,57 @@
       need to involve it. */
     if (mutex->__m_count > 0)
        return EBUSY;
+    mutex->__m_count = 0;
+    mutex->__m_owner = (_pthread_descr)VG_INVALID_THREADID;
+    mutex->__m_kind  = PTHREAD_MUTEX_ERRORCHECK_NP;
     return 0;
 }
 
 
 /* ---------------------------------------------------
+   CONDITION VARIABLES
+   ------------------------------------------------ */
+
+/* LinuxThreads supports no attributes for conditions.  Hence ... */
+
+int pthread_condattr_init(pthread_condattr_t *attr)
+{
+   return 0;
+}
+
+
+int pthread_cond_init( pthread_cond_t *cond,
+                       const pthread_condattr_t *cond_attr)
+{
+   cond->__c_waiting = (_pthread_descr)VG_INVALID_THREADID;
+   return 0;
+}
+
+
+/* ---------------------------------------------------
+   SCHEDULING
+   ------------------------------------------------ */
+
+/* This is completely bogus. */
+int   pthread_getschedparam(pthread_t  target_thread,  
+                            int  *policy,
+                            struct sched_param *param)
+{
+   if (policy) *policy = SCHED_OTHER;
+   if (param) param->__sched_priority = 0; /* who knows */
+   return 0;
+}
+
+int pthread_setschedparam(pthread_t target_thread, 
+                          int policy, 
+                          const struct sched_param *param)
+{
+   ignored("pthread_setschedparam");
+   return 0;
+}
+
+
+/* ---------------------------------------------------
    CANCELLATION
    ------------------------------------------------ */