Index: coregrind/vg_libpthread.c
===================================================================
RCS file: /home/kde/valgrind/coregrind/vg_libpthread.c,v
retrieving revision 1.147
diff -u -r1.147 vg_libpthread.c
--- coregrind/vg_libpthread.c	8 Mar 2004 15:57:17 -0000	1.147
+++ coregrind/vg_libpthread.c	16 Mar 2004 09:48:53 -0000
@@ -2480,9 +2480,6 @@
 
 #include <semaphore.h>
 
-/* This is a terrible way to do the remapping.  Plan is to import an
-   AVL tree at some point. */
-
 typedef
    struct {
       pthread_mutex_t se_mx;
@@ -2492,57 +2489,84 @@
    }
    vg_sem_t;
 
+#define SEM_CHECK_MAGIC 0x5b1d0772
+
+typedef
+   struct {
+      union {
+         vg_sem_t* p;
+         int i;
+      } shadow;
+      int err_check;
+   }
+   user_sem_t;
+
 static pthread_mutex_t se_remap_mx = PTHREAD_MUTEX_INITIALIZER;
 
-static int      se_remap_used = 0;
-static sem_t*   se_remap_orig[VG_N_SEMAPHORES];
+static vg_sem_t* se_remap_free[VG_N_SEMAPHORES];
+static vg_sem_t** first_free = se_remap_free;
+static int free_cnt = VG_N_SEMAPHORES;
 static vg_sem_t se_remap_new[VG_N_SEMAPHORES];
 
-static vg_sem_t* se_remap ( sem_t* orig )
+static vg_sem_t* se_new ( sem_t* orig )
 {
-   int res, i;
+   int res;
+   user_sem_t* u_sem = (user_sem_t*)orig;
+   vg_sem_t* vg_sem;
+
    res = __pthread_mutex_lock(&se_remap_mx);
    my_assert(res == 0);
 
-   for (i = 0; i < se_remap_used; i++) {
-      if (se_remap_orig[i] == orig)
-         break;
+   if(se_remap_free[0] == 0) { // init se_remap_free 
+      int i;
+      for(i = 0; i<VG_N_SEMAPHORES; ++i)
+         se_remap_free[i] = se_remap_new+i;
    }
-   if (i == se_remap_used) {
-      if (se_remap_used == VG_N_SEMAPHORES) {
-         res = pthread_mutex_unlock(&se_remap_mx);
-         my_assert(res == 0);
-         barf("VG_N_SEMAPHORES is too low.  Increase and recompile.");
-      }
-      se_remap_used++;
-      se_remap_orig[i] = orig;
-      /* printf("allocated semaphore %d\n", i); */
+
+   if(free_cnt == 0) {
+      res = pthread_mutex_unlock(&se_remap_mx);
+      my_assert(res == 0);
+      barf("VG_N_SEMAPHORES is too low.  Increase and recompile.");
    }
-   res = __pthread_mutex_unlock(&se_remap_mx);
+   vg_sem = *first_free;
+   if(++first_free == se_remap_free+VG_N_SEMAPHORES)
+      first_free = se_remap_free;
+   --free_cnt;
+   
+   res = pthread_mutex_unlock(&se_remap_mx);
    my_assert(res == 0);
-   return &se_remap_new[i];
+
+   u_sem->shadow.p = vg_sem;
+   u_sem->err_check = u_sem->shadow.i ^ SEM_CHECK_MAGIC;
+
+   return vg_sem;
 }
 
+static vg_sem_t* se_remap ( sem_t* orig )
+{
+   user_sem_t* u_sem = (user_sem_t*) orig;
+
+   if(!u_sem->shadow.p || ((u_sem->shadow.i ^ SEM_CHECK_MAGIC) != u_sem->err_check))
+      return NULL;
+   return u_sem->shadow.p;
+}
+   
 static void se_unmap( sem_t* orig )
 {
-   int res, i;
+   int res;
+   user_sem_t* u_sem = (user_sem_t*) orig;
+   int after_last_free;
+
    res = __pthread_mutex_lock(&se_remap_mx);
    my_assert(res == 0);
 
-   for (i = 0; i < se_remap_used; i++) {
-      if (se_remap_orig[i] == orig)
-         break;
-   }
-   if (i == se_remap_used) {
-      res = pthread_mutex_unlock(&se_remap_mx);
-      my_assert(res == 0);
-      barf("se_unmap: unmapping invalid semaphore");
-   } else {
-      se_remap_orig[i] = se_remap_orig[--se_remap_used];
-      se_remap_orig[se_remap_used] = 0;
-      memset(&se_remap_new[se_remap_used], 0,
-             sizeof(se_remap_new[se_remap_used]));
-   }
+   my_assert(free_cnt<VG_N_SEMAPHORES);
+   after_last_free = (first_free-se_remap_free)+free_cnt;
+   if(after_last_free >= VG_N_SEMAPHORES)
+      after_last_free -= VG_N_SEMAPHORES;
+   se_remap_free[after_last_free] = u_sem->shadow.p;
+   ++free_cnt;
+
    res = pthread_mutex_unlock(&se_remap_mx);
    my_assert(res == 0);
 }
@@ -2557,7 +2581,8 @@
       *(__errno_location()) = ENOSYS;
       return -1;
    }
-   vg_sem = se_remap(sem);
+   vg_sem = se_new(sem);
+
    res = pthread_mutex_init(&vg_sem->se_mx, NULL);
    my_assert(res == 0);
    res = pthread_cond_init(&vg_sem->se_cv, NULL);
@@ -2572,6 +2597,11 @@
    vg_sem_t* vg_sem;
    ensure_valgrind("sem_wait");
    vg_sem = se_remap(sem);
+   if(!vg_sem) {
+      pthread_error("sem_wait: semaphore overwritten or not initialized");
+      *(__errno_location()) = EINVAL;
+      return -1;
+   }
    res = __pthread_mutex_lock(&vg_sem->se_mx);
    my_assert(res == 0);
    while (vg_sem->count == 0) {
@@ -2592,6 +2622,11 @@
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_post");
    vg_sem = se_remap(sem);
+   if(!vg_sem) {
+      pthread_error("sem_post: semaphore overwritten or not initialized");
+      *(__errno_location()) = EINVAL;
+      return -1;
+   }
    res = __pthread_mutex_lock(&vg_sem->se_mx);
    my_assert(res == 0);
    if (vg_sem->count == 0) {
@@ -2613,6 +2648,11 @@
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_trywait");
    vg_sem = se_remap(sem);
+   if(!vg_sem) {
+      pthread_error("sem_trywait: semaphore overwritten or not initialized");
+      *(__errno_location()) = EINVAL;
+      return -1;
+   }
    res = __pthread_mutex_lock(&vg_sem->se_mx);
    my_assert(res == 0);
    if (vg_sem->count > 0) { 
@@ -2634,6 +2674,11 @@
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_getvalue");
    vg_sem = se_remap(sem);
+   if(!vg_sem) {
+      pthread_error("sem_getvalue: semaphore overwritten or not initialized");
+      *(__errno_location()) = EINVAL;
+      return -1;
+   }
    res = __pthread_mutex_lock(&vg_sem->se_mx);
    my_assert(res == 0);
    *sval = vg_sem->count;
@@ -2650,6 +2695,11 @@
    int res;
    ensure_valgrind("sem_destroy");
    vg_sem = se_remap(sem);
+   if(!vg_sem) {
+      pthread_error("sem_destroy: semaphore overwritten or not initialized");
+      *(__errno_location()) = EINVAL;
+      return -1;
+   }
    res = __pthread_mutex_lock(&vg_sem->se_mx);
    my_assert(res == 0);
    if (vg_sem->waiters > 0)
@@ -2666,6 +2716,7 @@
    res = pthread_mutex_destroy(&vg_sem->se_mx);
    my_assert(res == 0);
    se_unmap(sem);
+   memset(sem, 0, sizeof(user_sem_t));
    return 0;
 }
 
@@ -2676,6 +2727,11 @@
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_timedwait"); 
    vg_sem = se_remap(sem); 
+   if(!vg_sem) {
+      pthread_error("sem_timedwait: semaphore overwritten or not initialized");
+      *(__errno_location()) = EINVAL;
+      return -1;
+   }
    res = __pthread_mutex_lock(&vg_sem->se_mx); 
    my_assert(res == 0); 
    while ( vg_sem->count == 0 && res != ETIMEDOUT ) { 
