List:Internals« Previous MessageNext Message »
From:Michael Widenius Date:November 10 2004 11:34am
Subject:Too new rw-locks
View as plain text  
Hi!

I found a problem with running valgrind 2.2 with the MySQL test suite.

The problem is that the test suite creates ands drop a lot of tables
with a lot of index. In MySQL/MyISAM every active index uses a rw-lock,
which will overflow the coregrind internal rw-lock table, because this
doesn't reuse destroyed locks.

The following patch fixes the problem by reusing destroyed locks when
all locks in the 'rw_remap_orig' array has been used up.

-----------
*** valgrind-2.2.0/coregrind/vg_libpthread.c	Mon Aug 30 00:02:27 2004
--- valgrind-2.2.0-new/coregrind/vg_libpthread.c	Mon Nov  8 16:02:29
2004
***************
*** 2918,2924 ****
  
  typedef 
     struct {
!       int             initted;  /* != 0 --> in use; sanity check only
*/
        int             prefer_w; /* != 0 --> prefer writer */
        int             nwait_r;  /* # of waiting readers */
        int             nwait_w;  /* # of waiting writers */
--- 2918,2925 ----
  
  typedef 
     struct {
!      /* -1  destroyed, 0 not initialized, 1 in use; sanity check only
*/
!       int             initted;
        int             prefer_w; /* != 0 --> prefer writer */
        int             nwait_r;  /* # of waiting readers */
        int             nwait_w;  /* # of waiting writers */
***************
*** 2964,2987 ****
  */
  static vg_rwlock_t* rw_remap ( pthread_rwlock_t* orig )
  {
!    int          res, i;
     vg_rwlock_t* vg_rwl;
     vg_pthread_rwlock_t* vg_orig;
     
     res = __pthread_mutex_lock(&rw_remap_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);
--- 2965,2997 ----
  */
  static vg_rwlock_t* rw_remap ( pthread_rwlock_t* orig )
  {
!   int          res, i, empty_pos;
     vg_rwlock_t* vg_rwl;
     vg_pthread_rwlock_t* vg_orig;
     
     res = __pthread_mutex_lock(&rw_remap_mx);
     my_assert(res == 0);
  
+    empty_pos= rw_remap_used;
     for (i = 0; i < rw_remap_used; i++) {
        if (rw_remap_orig[i] == orig)
           break;
+       if (rw_remap_new[i].initted < 0)
+         empty_pos= i;                           /* Use destroyed mutex
*/
     }
     if (i == rw_remap_used) {
        if (rw_remap_used == VG_N_RWLOCKS) {
!         if (empty_pos == rw_remap_used) {
!           /* All positions are in use; abort */
!           res = __pthread_mutex_unlock(&rw_remap_mx);
!           my_assert(res == 0);
!           barf("VG_N_RWLOCKS is too low.  Increase and recompile.");
!         }
!         else
!           i= empty_pos;                         /* Reuse found
position */
        }
!       if (i == rw_remap_used)
!         rw_remap_used++;
        rw_remap_orig[i] = orig;
        rw_remap_new[i].initted = 0;
        if (0) printf("allocated rwlock %d\n", i);
***************
*** 3042,3048 ****
     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);
        return EINVAL;
--- 3052,3058 ----
     rwl = rw_remap ( orig );
     res = __pthread_mutex_lock(&rwl->mx);
     my_assert(res == 0);
!    if (rwl->initted <= 0) {
        res = __pthread_mutex_unlock(&rwl->mx);
        my_assert(res == 0);
        return EINVAL;
***************
*** 3076,3082 ****
     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);
        return EINVAL;
--- 3086,3092 ----
     rwl = rw_remap ( orig );
     res = __pthread_mutex_lock(&rwl->mx);
     my_assert(res == 0);
!    if (rwl->initted <= 0) {
        res = __pthread_mutex_unlock(&rwl->mx);
        my_assert(res == 0);
        return EINVAL;
***************
*** 3114,3120 ****
     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);
        return EINVAL;
--- 3124,3130 ----
     rwl = rw_remap ( orig );
     res = __pthread_mutex_lock(&rwl->mx);
     my_assert(res == 0);
!    if (rwl->initted <= 0) {
        res = __pthread_mutex_unlock(&rwl->mx);
        my_assert(res == 0);
        return EINVAL;
***************
*** 3146,3152 ****
     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);
        return EINVAL;
--- 3156,3162 ----
     rwl = rw_remap ( orig );
     res = __pthread_mutex_lock(&rwl->mx);
     my_assert(res == 0);
!    if (rwl->initted <= 0) {
        res = __pthread_mutex_unlock(&rwl->mx);
        my_assert(res == 0);
        return EINVAL;
***************
*** 3174,3180 ****
     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);
        return EINVAL;
--- 3184,3190 ----
     rwl = rw_remap ( orig );
     res = __pthread_mutex_lock(&rwl->mx);
     my_assert(res == 0);
!    if (rwl->initted <= 0) {
        res = __pthread_mutex_unlock(&rwl->mx);
        my_assert(res == 0);
        return EINVAL;
***************
*** 3249,3255 ****
     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);
        return EINVAL;
--- 3259,3265 ----
     rwl = rw_remap ( orig );
     res = __pthread_mutex_lock(&rwl->mx);
     my_assert(res == 0);
!    if (rwl->initted <= 0) {
        res = __pthread_mutex_unlock(&rwl->mx);
        my_assert(res == 0);
        return EINVAL;
***************
*** 3259,3265 ****
        my_assert(res == 0);
        return EBUSY;
     }
!    rwl->initted = 0;
     res = __pthread_mutex_unlock(&rwl->mx);
     my_assert(res == 0);
     return 0;
--- 3269,3275 ----
        my_assert(res == 0);
        return EBUSY;
     }
!    rwl->initted = -1;                           /* Can be reused */
     res = __pthread_mutex_unlock(&rwl->mx);
     my_assert(res == 0);
     return 0;

--------------
Regards,
Monty
CTO of MySQL AB


Thread
Too new rw-locksMichael Widenius10 Nov