From: Tom Hughes Date: Tue, 23 Mar 2004 19:48:54 +0000 (+0000) Subject: Commit rewrite of semaphore handling to avoid having a fixed upper X-Git-Tag: svn/VALGRIND_2_1_2~169 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=67bb2b010d6452ec7ea09080ac6340bdf3c8bac7;p=thirdparty%2Fvalgrind.git Commit rewrite of semaphore handling to avoid having a fixed upper limit. Patch courtesy of Aleksander Salwa . git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2336 --- diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index 3e807b8b01..b6c1a8d705 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -116,9 +116,6 @@ 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 diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c index b64c543796..214dc92ab1 100644 --- a/coregrind/vg_libpthread.c +++ b/coregrind/vg_libpthread.c @@ -2489,9 +2489,6 @@ pid_t __vfork(void) #include -/* 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 ) { diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index e8715e02b2..9bcfaeaff0 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -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 index 0000000000..5bf3d3f08d --- /dev/null +++ b/none/tests/semlimit.c @@ -0,0 +1,16 @@ +#include +#include + +#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 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/semlimit.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/semlimit.stdout.exp b/none/tests/semlimit.stdout.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/semlimit.vgtest b/none/tests/semlimit.vgtest new file mode 100644 index 0000000000..f034a65786 --- /dev/null +++ b/none/tests/semlimit.vgtest @@ -0,0 +1 @@ +prog: semlimit