]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Commit rewrite of semaphore handling to avoid having a fixed upper
authorTom Hughes <tom@compton.nu>
Tue, 23 Mar 2004 19:48:54 +0000 (19:48 +0000)
committerTom Hughes <tom@compton.nu>
Tue, 23 Mar 2004 19:48:54 +0000 (19:48 +0000)
limit. Patch courtesy of Aleksander Salwa <A.Salwa@osmosys.tv>.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2336

coregrind/vg_include.h
coregrind/vg_libpthread.c
none/tests/Makefile.am
none/tests/semlimit.c [new file with mode: 0644]
none/tests/semlimit.stderr.exp [new file with mode: 0644]
none/tests/semlimit.stdout.exp [new file with mode: 0644]
none/tests/semlimit.vgtest [new file with mode: 0644]

index 3e807b8b012951e88547ef0711260265885010bd..b6c1a8d705113eac8614d91ce45af00dcc3f9b7b 100644 (file)
    beyond it. */
 #define VG_PTHREAD_STACK_SIZE (1 << 20)
 
-/* Number of entries in the semaphore-remapping table. */
-#define VG_N_SEMAPHORES 50
-
 /* Number of entries in the rwlock-remapping table. */
 #define VG_N_RWLOCKS 500
 
index b64c54379601494e9ae6779842a7aa56269b1f47..214dc92ab12d8aaeeffa1d425475c46dc066282c 100644 (file)
@@ -2489,9 +2489,6 @@ pid_t __vfork(void)
 
 #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;
@@ -2501,59 +2498,52 @@ typedef
    }
    vg_sem_t;
 
-static pthread_mutex_t se_remap_mx = PTHREAD_MUTEX_INITIALIZER;
+#define SEM_CHECK_MAGIC 0x5b1d0772
+
+typedef
+   struct {
+      union {
+         vg_sem_t* p;
+         int i;
+      } shadow;
+      int err_check;
+   }
+   user_sem_t;
 
-static int      se_remap_used = 0;
-static sem_t*   se_remap_orig[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;
-   res = __pthread_mutex_lock(&se_remap_mx);
-   my_assert(res == 0);
+   user_sem_t* u_sem = (user_sem_t*)orig;
+   vg_sem_t* vg_sem;
 
-   for (i = 0; i < se_remap_used; i++) {
-      if (se_remap_orig[i] == orig)
-         break;
-   }
-   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); */
-   }
-   res = __pthread_mutex_unlock(&se_remap_mx);
-   my_assert(res == 0);
-   return &se_remap_new[i];
+   vg_sem = my_malloc(sizeof(vg_sem_t));
+
+   u_sem->shadow.p = vg_sem;
+   u_sem->err_check = u_sem->shadow.i ^ SEM_CHECK_MAGIC;
+
+   return vg_sem;
 }
 
-static void se_unmap( sem_t* orig )
+static vg_sem_t* se_lookup ( sem_t* orig )
 {
-   int res, i;
-   res = __pthread_mutex_lock(&se_remap_mx);
-   my_assert(res == 0);
+   user_sem_t* u_sem = (user_sem_t*) orig;
 
-   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]));
-   }
-   res = pthread_mutex_unlock(&se_remap_mx);
-   my_assert(res == 0);
+   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_free( sem_t* orig )
+{
+   user_sem_t* u_sem = (user_sem_t*) orig;
+
+   my_free(u_sem->shadow.p);
+
+   u_sem->shadow.p = NULL;
+   u_sem->err_check = 0;
+
+   return;
 }
 
 int sem_init(sem_t *sem, int pshared, unsigned int value)
@@ -2566,12 +2556,14 @@ int sem_init(sem_t *sem, int pshared, unsigned int value)
       *(__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);
    my_assert(res == 0);
    vg_sem->count = value;
+   vg_sem->waiters = 0;
    return 0;
 }
 
@@ -2580,7 +2572,12 @@ int sem_wait ( sem_t* sem )
    int       res;
    vg_sem_t* vg_sem;
    ensure_valgrind("sem_wait");
-   vg_sem = se_remap(sem);
+   vg_sem = se_lookup(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) {
@@ -2600,7 +2597,12 @@ int sem_post ( sem_t* sem )
    int       res;
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_post");
-   vg_sem = se_remap(sem);
+   vg_sem = se_lookup(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) {
@@ -2621,7 +2623,12 @@ int sem_trywait ( sem_t* sem )
    int       ret, res;
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_trywait");
-   vg_sem = se_remap(sem);
+   vg_sem = se_lookup(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) { 
@@ -2642,7 +2649,12 @@ int sem_getvalue(sem_t* sem, int * sval)
    int res;
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_getvalue");
-   vg_sem = se_remap(sem);
+   vg_sem = se_lookup(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;
@@ -2658,7 +2670,12 @@ int sem_destroy(sem_t * sem)
    vg_sem_t* vg_sem;
    int res;
    ensure_valgrind("sem_destroy");
-   vg_sem = se_remap(sem);
+   vg_sem = se_lookup(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)
@@ -2674,7 +2691,7 @@ int sem_destroy(sem_t * sem)
    my_assert(res == 0);
    res = pthread_mutex_destroy(&vg_sem->se_mx);
    my_assert(res == 0);
-   se_unmap(sem);
+   se_free(sem);
    return 0;
 }
 
@@ -2684,7 +2701,12 @@ int sem_timedwait(sem_t* sem, const struct timespec *abstime)
    int       res; 
    vg_sem_t* vg_sem; 
    ensure_valgrind("sem_timedwait"); 
-   vg_sem = se_remap(sem); 
+   vg_sem = se_lookup(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 ) { 
index e8715e02b2f200c6266ff838ebd4a0be1e30e833..9bcfaeaff0a7c4586ad1f74a517b2b3bc3643975 100644 (file)
@@ -45,6 +45,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        resolv.stderr.exp resolv.stdout.exp resolv.vgtest \
        seg_override.stderr.exp \
        seg_override.stdout.exp seg_override.vgtest \
+       semlimit.stderr.exp semlimit.stdout.exp semlimit.vgtest \
        susphello.stdout.exp susphello.stderr.exp susphello.vgtest \
        sha1_test.stderr.exp sha1_test.vgtest \
        shortpush.stderr.exp shortpush.vgtest \
@@ -61,8 +62,8 @@ check_PROGRAMS = \
        cpuid dastest discard exec-sigmask floored fork fpu_lazy_eflags \
        fucomip $(INSN_TESTS) \
        int munmap_exe map_unmap mremap rcl_assert \
-       rcrl readline1 resolv seg_override sha1_test shortpush shorts smc1 \
-       susphello pth_blockedsig pushpopseg \
+       rcrl readline1 resolv seg_override semlimit sha1_test \
+       shortpush shorts smc1 susphello pth_blockedsig pushpopseg \
        syscall-restart1 syscall-restart2 system \
        coolo_sigaction gxx304 yield
 
@@ -108,6 +109,8 @@ rcrl_SOURCES                = rcrl.c
 readline1_SOURCES      = readline1.c
 resolv_SOURCES                 = resolv.c
 seg_override_SOURCES   = seg_override.c
+semlimit_SOURCES       = semlimit.c
+semlimit_LDADD         = -lpthread
 smc1_SOURCES           = smc1.c
 sha1_test_SOURCES      = sha1_test.c
 shortpush_SOURCES      = shortpush.c
diff --git a/none/tests/semlimit.c b/none/tests/semlimit.c
new file mode 100644 (file)
index 0000000..5bf3d3f
--- /dev/null
@@ -0,0 +1,16 @@
+#include <semaphore.h>
+#include <stdlib.h>
+
+#define SEM_LIMIT 100
+
+int main(int argc, char **argv)
+{
+  sem_t s[SEM_LIMIT];
+  int i;
+  
+  for (i = 0; i < SEM_LIMIT; i++) {
+    sem_init(&s[i], 0, 0);
+  }
+
+  exit(0);
+}
diff --git a/none/tests/semlimit.stderr.exp b/none/tests/semlimit.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/semlimit.stdout.exp b/none/tests/semlimit.stdout.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/semlimit.vgtest b/none/tests/semlimit.vgtest
new file mode 100644 (file)
index 0000000..f034a65
--- /dev/null
@@ -0,0 +1 @@
+prog: semlimit