|
From: Tom H. <th...@cy...> - 2004-10-16 14:49:56
|
CVS commit by thughes:
Remove the limit on the number of pthread read/write locks. This works
in a similar way to the previous patch that removed the limit on the
number of semaphores and fixes bug 86264.
A corecheck/tests/pth_rwlock.c 1.1 [POSSIBLY UNSAFE: printf] [no copyright]
A corecheck/tests/pth_rwlock.stderr.exp 1.1
A corecheck/tests/pth_rwlock.vgtest 1.1
M +1 -0 corecheck/tests/.cvsignore 1.9
M +4 -1 corecheck/tests/Makefile.am 1.22
M +0 -3 coregrind/core.h 1.36
M +93 -89 coregrind/vg_libpthread.c 1.167
--- valgrind/corecheck/tests/.cvsignore #1.8:1.9
@@ -11,4 +11,5 @@
pth_mutexspeed
pth_once
+pth_rwlock
res_search
.ktemp
--- valgrind/corecheck/tests/Makefile.am #1.21:1.22
@@ -29,4 +29,5 @@
pth_mutexspeed.stdout.exp pth_mutexspeed.vgtest \
pth_once.stderr.exp pth_once.stdout.exp pth_once.vgtest \
+ pth_rwlock.stderr.exp pth_rwlock.vgtest \
sigkill.stderr.exp sigkill.vgtest \
res_search.stderr.exp res_search.stdout.exp res_search.vgtest \
@@ -38,5 +39,5 @@
fdleak_socketpair sigkill res_search \
pth_atfork1 pth_cancel1 pth_cancel2 pth_cvsimple pth_empty \
- pth_exit pth_exit2 pth_mutexspeed pth_once \
+ pth_exit pth_exit2 pth_mutexspeed pth_once pth_rwlock \
as_mmap as_shm \
vgprintf
@@ -82,4 +83,6 @@
pth_once_SOURCES = pth_once.c
pth_once_LDADD = -lpthread
+pth_rwlock_SOURCES = pth_rwlock.c
+pth_rwlock_LDADD = -lpthread
res_search_SOURCES = res_search.c
res_search_LDADD = -lresolv -lpthread
--- valgrind/coregrind/core.h #1.35:1.36
@@ -165,7 +165,4 @@
#define VG_PTHREAD_STACK_SIZE (1 << 20)
-/* Number of entries in the rwlock-remapping table. */
-#define VG_N_RWLOCKS 500
-
/* Number of entries in each thread's cleanup stack. */
#define VG_N_CLEANUPSTACK 16
--- valgrind/coregrind/vg_libpthread.c #1.166:1.167
@@ -2944,5 +2944,4 @@ int sem_timedwait(sem_t* sem, const stru
typedef
struct {
- int initted; /* != 0 --> in use; sanity check only */
int prefer_w; /* != 0 --> prefer writer */
int nwait_r; /* # of waiting readers */
@@ -2958,16 +2957,12 @@ typedef
-static pthread_mutex_t rw_remap_mx = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t rw_new_mx = PTHREAD_MUTEX_INITIALIZER;
-static int rw_remap_used = 0;
-static pthread_rwlock_t* rw_remap_orig[VG_N_RWLOCKS];
-static vg_rwlock_t rw_remap_new[VG_N_RWLOCKS];
+#define RWLOCK_CHECK_MAGIC 0xb5d17027
-static
-void init_vg_rwlock ( vg_rwlock_t* vg_rwl )
+static void init_vg_rwlock ( vg_rwlock_t* vg_rwl )
{
int res = 0;
- vg_rwl->initted = 1;
vg_rwl->prefer_w = 1;
vg_rwl->nwait_r = 0;
@@ -2980,52 +2975,69 @@ void init_vg_rwlock ( vg_rwlock_t* vg_rw
}
-
-/* Take the address of a LinuxThreads rwlock_t and return the shadow
- address of our version. Further, if the LinuxThreads version
- appears to have been statically initialised, do the same to the one
- we allocate here. The vg_pthread_rwlock_t.__vg_rw_readers field is set
- to zero by PTHREAD_RWLOCK_INITIALIZER (as are several other fields), so
- we take zero as meaning uninitialised and non-zero meaning initialised.
-*/
-static vg_rwlock_t* rw_remap ( pthread_rwlock_t* orig )
+static vg_rwlock_t* rw_new ( pthread_rwlock_t* orig )
{
- int res, i;
- vg_rwlock_t* vg_rwl;
+ int res;
+ vg_rwlock_t* rwl;
vg_pthread_rwlock_t* vg_orig;
+ CONVERT(rwlock, orig, vg_orig);
- res = __pthread_mutex_lock(&rw_remap_mx);
+ res = __pthread_mutex_lock(&rw_new_mx);
my_assert(res == 0);
- for (i = 0; i < rw_remap_used; i++) {
- if (rw_remap_orig[i] == orig)
- break;
- }
- if (i == rw_remap_used) {
- if (rw_remap_used == VG_N_RWLOCKS) {
- res = __pthread_mutex_unlock(&rw_remap_mx);
- my_assert(res == 0);
- barf("VG_N_RWLOCKS is too low. Increase and recompile.");
- }
- rw_remap_used++;
- rw_remap_orig[i] = orig;
- rw_remap_new[i].initted = 0;
- if (0) printf("allocated rwlock %d\n", i);
- }
- res = __pthread_mutex_unlock(&rw_remap_mx);
+ rwl = my_malloc(sizeof(vg_rwlock_t));
+
+ vg_orig->__vg_rw_writer = rwl;
+ vg_orig->__vg_rw_read_waiting = (void *)((Addr)rwl ^ RWLOCK_CHECK_MAGIC);
+
+ init_vg_rwlock(rwl);
+ if (vg_orig->__vg_rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP)
+ rwl->prefer_w = 0;
+
+ res = __pthread_mutex_unlock(&rw_new_mx);
my_assert(res == 0);
- vg_rwl = &rw_remap_new[i];
- /* Initialise the shadow, if required. */
+ return rwl;
+}
+
+static vg_rwlock_t* rw_lookup ( pthread_rwlock_t* orig )
+{
+ vg_rwlock_t* rwl;
+ vg_pthread_rwlock_t* vg_orig;
CONVERT(rwlock, orig, vg_orig);
- if (vg_orig->__vg_rw_readers == 0) {
- vg_orig->__vg_rw_readers = 1;
- init_vg_rwlock(vg_rwl);
- if (vg_orig->__vg_rw_kind == PTHREAD_RWLOCK_PREFER_READER_NP)
- vg_rwl->prefer_w = 0;
- }
- return vg_rwl;
+ if (vg_orig->__vg_rw_writer == NULL)
+ rwl = rw_new (orig);
+ else if (((Addr)vg_orig->__vg_rw_writer ^ RWLOCK_CHECK_MAGIC) == (Addr)vg_orig->__vg_rw_read_waiting)
+ rwl = vg_orig->__vg_rw_writer;
+ else
+ rwl = NULL;
+
+ return rwl;
}
+static void rw_free ( pthread_rwlock_t* orig )
+{
+ int res;
+ vg_rwlock_t* rwl;
+ vg_pthread_rwlock_t* vg_orig;
+ CONVERT(rwlock, orig, vg_orig);
+
+ rwl = vg_orig->__vg_rw_writer;
+
+ vg_orig->__vg_rw_writer = NULL;
+ vg_orig->__vg_rw_read_waiting = NULL;
+
+ res = __pthread_mutex_unlock(&rwl->mx);
+ my_assert(res == 0);
+
+ res = pthread_cond_destroy(&rwl->cv_w);
+ res |= pthread_cond_destroy(&rwl->cv_r);
+ res |= pthread_mutex_destroy(&rwl->mx);
+ my_assert(res == 0);
+
+ my_free(rwl);
+
+ return;
+}
int pthread_rwlock_init ( pthread_rwlock_t* orig,
@@ -3039,11 +3051,11 @@ int pthread_rwlock_init ( pthread_rwlock
if (0) printf ("pthread_rwlock_init\n");
- /* Force the remapper to initialise the shadow. */
- vg_orig->__vg_rw_readers = 0;
/* Install the lock preference; the remapper needs to know it. */
- vg_orig->__vg_rw_kind = PTHREAD_RWLOCK_DEFAULT_NP;
if (vg_attr)
vg_orig->__vg_rw_kind = vg_attr->__vg_lockkind;
- rwl = rw_remap ( (pthread_rwlock_t*)vg_orig );
+ else
+ vg_orig->__vg_rw_kind = PTHREAD_RWLOCK_DEFAULT_NP;
+ /* Allocate the shadow */
+ rwl = rw_new ((pthread_rwlock_t *)vg_orig);
return 0;
}
@@ -3065,12 +3077,11 @@ int pthread_rwlock_rdlock ( pthread_rwlo
if (0) printf ("pthread_rwlock_rdlock\n");
- rwl = rw_remap ( orig );
- res = __pthread_mutex_lock(&rwl->mx);
- my_assert(res == 0);
- if (!rwl->initted) {
- res = __pthread_mutex_unlock(&rwl->mx);
- my_assert(res == 0);
+ rwl = rw_lookup (orig);
+ if(!rwl) {
+ pthread_error("pthread_rwlock_rdlock: lock overwritten or not initialized");
return EINVAL;
}
+ res = __pthread_mutex_lock(&rwl->mx);
+ my_assert(res == 0);
if (rwl->status < 0) {
my_assert(rwl->status == -1);
@@ -3099,12 +3110,11 @@ int pthread_rwlock_tryrdlock ( pthread_r
if (0) printf ("pthread_rwlock_tryrdlock\n");
- rwl = rw_remap ( orig );
- res = __pthread_mutex_lock(&rwl->mx);
- my_assert(res == 0);
- if (!rwl->initted) {
- res = __pthread_mutex_unlock(&rwl->mx);
- my_assert(res == 0);
+ rwl = rw_lookup (orig);
+ if(!rwl) {
+ pthread_error("pthread_rwlock_tryrdlock: lock overwritten or not initialized");
return EINVAL;
}
+ res = __pthread_mutex_lock(&rwl->mx);
+ my_assert(res == 0);
if (rwl->status == -1) {
/* Writer active; we have to give up. */
@@ -3137,12 +3147,11 @@ int pthread_rwlock_wrlock ( pthread_rwlo
if (0) printf ("pthread_rwlock_wrlock\n");
- rwl = rw_remap ( orig );
- res = __pthread_mutex_lock(&rwl->mx);
- my_assert(res == 0);
- if (!rwl->initted) {
- res = __pthread_mutex_unlock(&rwl->mx);
- my_assert(res == 0);
+ rwl = rw_lookup (orig);
+ if(!rwl) {
+ pthread_error("pthread_rwlock_wrlock: lock overwritten or not initialized");
return EINVAL;
}
+ res = __pthread_mutex_lock(&rwl->mx);
+ my_assert(res == 0);
if (rwl->status != 0) {
rwl->nwait_w++;
@@ -3169,12 +3178,11 @@ int pthread_rwlock_trywrlock ( pthread_r
vg_rwlock_t* rwl;
if (0) printf ("pthread_wrlock_trywrlock\n");
- rwl = rw_remap ( orig );
- res = __pthread_mutex_lock(&rwl->mx);
- my_assert(res == 0);
- if (!rwl->initted) {
- res = __pthread_mutex_unlock(&rwl->mx);
- my_assert(res == 0);
+ rwl = rw_lookup (orig);
+ if(!rwl) {
+ pthread_error("pthread_rwlock_trywrlock: lock overwritten or not initialized");
return EINVAL;
}
+ res = __pthread_mutex_lock(&rwl->mx);
+ my_assert(res == 0);
if (rwl->status != 0) {
/* Reader(s) or a writer active; we have to give up. */
@@ -3197,12 +3205,11 @@ int pthread_rwlock_unlock ( pthread_rwlo
vg_rwlock_t* rwl;
if (0) printf ("pthread_rwlock_unlock\n");
- rwl = rw_remap ( orig );
- res = __pthread_mutex_lock(&rwl->mx);
- my_assert(res == 0);
- if (!rwl->initted) {
- res = __pthread_mutex_unlock(&rwl->mx);
- my_assert(res == 0);
+ rwl = rw_lookup (orig);
+ if(!rwl) {
+ pthread_error("pthread_rwlock_unlock: lock overwritten or not initialized");
return EINVAL;
}
+ res = __pthread_mutex_lock(&rwl->mx);
+ my_assert(res == 0);
if (rwl->status == 0) {
res = __pthread_mutex_unlock(&rwl->mx);
@@ -3272,12 +3279,11 @@ int pthread_rwlock_destroy ( pthread_rwl
vg_rwlock_t* rwl;
if (0) printf ("pthread_rwlock_destroy\n");
- rwl = rw_remap ( orig );
- res = __pthread_mutex_lock(&rwl->mx);
- my_assert(res == 0);
- if (!rwl->initted) {
- res = __pthread_mutex_unlock(&rwl->mx);
- my_assert(res == 0);
+ rwl = rw_lookup (orig);
+ if(!rwl) {
+ pthread_error("pthread_rwlock_destroy: lock overwritten or not initialized");
return EINVAL;
}
+ res = __pthread_mutex_lock(&rwl->mx);
+ my_assert(res == 0);
if (rwl->status != 0 || rwl->nwait_r > 0 || rwl->nwait_w > 0) {
res = __pthread_mutex_unlock(&rwl->mx);
@@ -3285,7 +3291,5 @@ int pthread_rwlock_destroy ( pthread_rwl
return EBUSY;
}
- rwl->initted = 0;
- res = __pthread_mutex_unlock(&rwl->mx);
- my_assert(res == 0);
+ rw_free (orig);
return 0;
}
|