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-locks | Michael Widenius | 10 Nov |