Commit 32739cbb authored by unknown's avatar unknown

make sure all test threads really exit before main() - workaround for

NPTL bug in some linux kernels (Bug#22320)

parent d1852da7
...@@ -109,36 +109,41 @@ void test_lockman_simple() ...@@ -109,36 +109,41 @@ void test_lockman_simple()
} }
pthread_attr_t rt_attr;
pthread_mutex_t rt_mutex;
pthread_cond_t rt_cond;
int rt_num_threads; int rt_num_threads;
int litmus; int litmus;
int thread_number= 0, timeouts= 0; int thread_number= 0, timeouts= 0;
void run_test(const char *test, pthread_handler handler, int n, int m) void run_test(const char *test, pthread_handler handler, int n, int m)
{ {
pthread_t t; pthread_t *threads;
ulonglong now= my_getsystime(); ulonglong now= my_getsystime();
int i;
thread_number= timeouts= 0; thread_number= timeouts= 0;
litmus= 0; litmus= 0;
threads= (pthread_t *)my_malloc(sizeof(void *)*n, MYF(0));
if (!threads)
{
diag("Out of memory");
abort();
}
diag("Running %s with %d threads, %d iterations... ", test, n, m); diag("Running %s with %d threads, %d iterations... ", test, n, m);
for (rt_num_threads= n ; n ; n--) rt_num_threads= n;
if (pthread_create(&t, &rt_attr, handler, &m)) for (i= 0; i < n ; i++)
if (pthread_create(threads+i, 0, handler, &m))
{ {
diag("Could not create thread"); diag("Could not create thread");
litmus++; abort();
rt_num_threads--;
} }
pthread_mutex_lock(&rt_mutex); for (i= 0 ; i < n ; i++)
while (rt_num_threads) pthread_join(threads[i], 0);
pthread_cond_wait(&rt_cond, &rt_mutex);
pthread_mutex_unlock(&rt_mutex);
now= my_getsystime()-now; now= my_getsystime()-now;
ok(litmus == 0, "Finished %s in %g secs (%d)", test, ((double)now)/1e7, litmus); ok(litmus == 0, "Finished %s in %g secs (%d)", test, ((double)now)/1e7, litmus);
my_free((void*)threads, MYF(0));
} }
pthread_mutex_t rt_mutex;
int Nrows= 100; int Nrows= 100;
int Ntables= 10; int Ntables= 10;
int table_lock_ratio= 10; int table_lock_ratio= 10;
...@@ -222,10 +227,7 @@ pthread_handler_t test_lockman(void *arg) ...@@ -222,10 +227,7 @@ pthread_handler_t test_lockman(void *arg)
rt_num_threads--; rt_num_threads--;
timeouts+= timeout; timeouts+= timeout;
if (!rt_num_threads) if (!rt_num_threads)
{
pthread_cond_signal(&rt_cond);
diag("number of timeouts: %d", timeouts); diag("number of timeouts: %d", timeouts);
}
pthread_mutex_unlock(&rt_mutex); pthread_mutex_unlock(&rt_mutex);
return 0; return 0;
...@@ -236,16 +238,13 @@ int main() ...@@ -236,16 +238,13 @@ int main()
int i; int i;
my_init(); my_init();
pthread_mutex_init(&rt_mutex, 0);
plan(31); plan(31);
if (my_atomic_initialize()) if (my_atomic_initialize())
return exit_status(); return exit_status();
pthread_attr_init(&rt_attr);
pthread_attr_setdetachstate(&rt_attr, PTHREAD_CREATE_DETACHED);
pthread_mutex_init(&rt_mutex, 0);
pthread_cond_init(&rt_cond, 0);
lockman_init(&lockman, &loid2lo, 50); lockman_init(&lockman, &loid2lo, 50);
...@@ -294,8 +293,6 @@ int main() ...@@ -294,8 +293,6 @@ int main()
} }
pthread_mutex_destroy(&rt_mutex); pthread_mutex_destroy(&rt_mutex);
pthread_cond_destroy(&rt_cond);
pthread_attr_destroy(&rt_attr);
my_end(0); my_end(0);
return exit_status(); return exit_status();
} }
......
...@@ -22,9 +22,7 @@ ...@@ -22,9 +22,7 @@
#include <lf.h> #include <lf.h>
#include "../trnman.h" #include "../trnman.h"
pthread_attr_t rt_attr;
pthread_mutex_t rt_mutex; pthread_mutex_t rt_mutex;
pthread_cond_t rt_cond;
int rt_num_threads; int rt_num_threads;
int litmus; int litmus;
...@@ -74,8 +72,6 @@ pthread_handler_t test_trnman(void *arg) ...@@ -74,8 +72,6 @@ pthread_handler_t test_trnman(void *arg)
} }
pthread_mutex_lock(&rt_mutex); pthread_mutex_lock(&rt_mutex);
rt_num_threads--; rt_num_threads--;
if (!rt_num_threads)
pthread_cond_signal(&rt_cond);
pthread_mutex_unlock(&rt_mutex); pthread_mutex_unlock(&rt_mutex);
return 0; return 0;
...@@ -84,25 +80,32 @@ pthread_handler_t test_trnman(void *arg) ...@@ -84,25 +80,32 @@ pthread_handler_t test_trnman(void *arg)
void run_test(const char *test, pthread_handler handler, int n, int m) void run_test(const char *test, pthread_handler handler, int n, int m)
{ {
pthread_t t; pthread_t *threads;
ulonglong now= my_getsystime(); ulonglong now= my_getsystime();
int i;
litmus= 0; litmus= 0;
threads= (pthread_t *)my_malloc(sizeof(void *)*n, MYF(0));
if (!threads)
{
diag("Out of memory");
abort();
}
diag("Testing %s with %d threads, %d iterations... ", test, n, m); diag("Testing %s with %d threads, %d iterations... ", test, n, m);
for (rt_num_threads= n ; n ; n--) rt_num_threads= n;
if (pthread_create(&t, &rt_attr, handler, &m)) for (i= 0; i < n ; i++)
if (pthread_create(threads+i, 0, handler, &m))
{ {
diag("Could not create thread"); diag("Could not create thread");
litmus++; abort();
rt_num_threads--;
} }
pthread_mutex_lock(&rt_mutex); for (i= 0 ; i < n ; i++)
while (rt_num_threads) pthread_join(threads[i], 0);
pthread_cond_wait(&rt_cond, &rt_mutex);
pthread_mutex_unlock(&rt_mutex);
now= my_getsystime()-now; now= my_getsystime()-now;
ok(litmus == 0, "tested %s in %g secs (%d)", test, ((double)now)/1e7, litmus); ok(litmus == 0, "Tested %s in %g secs (%d)", test, ((double)now)/1e7, litmus);
my_free((void*)threads, MYF(0));
} }
#define ok_read_from(T1, T2, RES) \ #define ok_read_from(T1, T2, RES) \
...@@ -157,10 +160,7 @@ int main() ...@@ -157,10 +160,7 @@ int main()
if (my_atomic_initialize()) if (my_atomic_initialize())
return exit_status(); return exit_status();
pthread_attr_init(&rt_attr);
pthread_attr_setdetachstate(&rt_attr, PTHREAD_CREATE_DETACHED);
pthread_mutex_init(&rt_mutex, 0); pthread_mutex_init(&rt_mutex, 0);
pthread_cond_init(&rt_cond, 0);
#define CYCLES 10000 #define CYCLES 10000
#define THREADS 10 #define THREADS 10
...@@ -179,8 +179,6 @@ int main() ...@@ -179,8 +179,6 @@ int main()
} }
pthread_mutex_destroy(&rt_mutex); pthread_mutex_destroy(&rt_mutex);
pthread_cond_destroy(&rt_cond);
pthread_attr_destroy(&rt_attr);
my_end(0); my_end(0);
return exit_status(); return exit_status();
} }
......
...@@ -21,24 +21,19 @@ ...@@ -21,24 +21,19 @@
#include <my_atomic.h> #include <my_atomic.h>
#include <lf.h> #include <lf.h>
volatile uint32 a32,b32,c32; volatile uint32 a32,b32,c32, N;
my_atomic_rwlock_t rwl; my_atomic_rwlock_t rwl;
LF_ALLOCATOR lf_allocator; LF_ALLOCATOR lf_allocator;
LF_HASH lf_hash; LF_HASH lf_hash;
pthread_attr_t thr_attr;
pthread_mutex_t mutex;
pthread_cond_t cond;
int N;
/* add and sub a random number in a loop. Must get 0 at the end */ /* add and sub a random number in a loop. Must get 0 at the end */
pthread_handler_t test_atomic_add_handler(void *arg) pthread_handler_t test_atomic_add_handler(void *arg)
{ {
int m=(*(int *)arg)/2; int m= (*(int *)arg)/2;
int32 x; int32 x;
for (x=((int)(intptr)(&m)); m ; m--) for (x= ((int)(intptr)(&m)); m ; m--)
{ {
x=(x*m+0x87654321) & INT_MAX32; x= (x*m+0x87654321) & INT_MAX32;
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
my_atomic_add32(&a32, x); my_atomic_add32(&a32, x);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
...@@ -47,10 +42,6 @@ pthread_handler_t test_atomic_add_handler(void *arg) ...@@ -47,10 +42,6 @@ pthread_handler_t test_atomic_add_handler(void *arg)
my_atomic_add32(&a32, -x); my_atomic_add32(&a32, -x);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
} }
pthread_mutex_lock(&mutex);
N--;
if (!N) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0; return 0;
} }
...@@ -64,22 +55,22 @@ pthread_handler_t test_atomic_add_handler(void *arg) ...@@ -64,22 +55,22 @@ pthread_handler_t test_atomic_add_handler(void *arg)
*/ */
pthread_handler_t test_atomic_fas_handler(void *arg) pthread_handler_t test_atomic_fas_handler(void *arg)
{ {
int m=*(int *)arg; int m= *(int *)arg;
uint32 x=my_atomic_add32(&b32, 1); uint32 x= my_atomic_add32(&b32, 1);
my_atomic_add32(&a32, x); my_atomic_add32(&a32, x);
for (; m ; m--) for (; m ; m--)
{ {
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
x=my_atomic_fas32(&c32, x); x= my_atomic_fas32(&c32, x);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
} }
if (!x) if (!x)
{ {
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
x=my_atomic_fas32(&c32, x); x= my_atomic_fas32(&c32, x);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
} }
...@@ -87,10 +78,6 @@ pthread_handler_t test_atomic_fas_handler(void *arg) ...@@ -87,10 +78,6 @@ pthread_handler_t test_atomic_fas_handler(void *arg)
my_atomic_add32(&a32, -x); my_atomic_add32(&a32, -x);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
pthread_mutex_lock(&mutex);
N--;
if (!N) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0; return 0;
} }
...@@ -101,29 +88,25 @@ pthread_handler_t test_atomic_fas_handler(void *arg) ...@@ -101,29 +88,25 @@ pthread_handler_t test_atomic_fas_handler(void *arg)
*/ */
pthread_handler_t test_atomic_cas_handler(void *arg) pthread_handler_t test_atomic_cas_handler(void *arg)
{ {
int m=(*(int *)arg)/2, ok=0; int m= (*(int *)arg)/2, ok= 0;
int32 x, y; int32 x, y;
for (x=((int)(intptr)(&m)); m ; m--) for (x= ((int)(intptr)(&m)); m ; m--)
{ {
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
y=my_atomic_load32(&a32); y= my_atomic_load32(&a32);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
x=(x*m+0x87654321) & INT_MAX32; x= (x*m+0x87654321) & INT_MAX32;
do { do {
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
ok=my_atomic_cas32(&a32, &y, y+x); ok= my_atomic_cas32(&a32, &y, y+x);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
} while (!ok) ; } while (!ok) ;
do { do {
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
ok=my_atomic_cas32(&a32, &y, y-x); ok= my_atomic_cas32(&a32, &y, y-x);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrunlock(&rwl);
} while (!ok) ; } while (!ok) ;
} }
pthread_mutex_lock(&mutex);
N--;
if (!N) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0; return 0;
} }
...@@ -132,23 +115,18 @@ pthread_handler_t test_atomic_cas_handler(void *arg) ...@@ -132,23 +115,18 @@ pthread_handler_t test_atomic_cas_handler(void *arg)
*/ */
pthread_handler_t test_lf_pinbox(void *arg) pthread_handler_t test_lf_pinbox(void *arg)
{ {
int m=*(int *)arg; int m= *(int *)arg;
int32 x=0; int32 x= 0;
LF_PINS *pins; LF_PINS *pins;
pins=lf_pinbox_get_pins(&lf_allocator.pinbox); pins= lf_pinbox_get_pins(&lf_allocator.pinbox);
for (x=((int)(intptr)(&m)); m ; m--) for (x= ((int)(intptr)(&m)); m ; m--)
{ {
lf_pinbox_put_pins(pins); lf_pinbox_put_pins(pins);
pins=lf_pinbox_get_pins(&lf_allocator.pinbox); pins= lf_pinbox_get_pins(&lf_allocator.pinbox);
} }
lf_pinbox_put_pins(pins); lf_pinbox_put_pins(pins);
pthread_mutex_lock(&mutex);
N--;
if (!N)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0; return 0;
} }
...@@ -159,122 +137,124 @@ typedef union { ...@@ -159,122 +137,124 @@ typedef union {
pthread_handler_t test_lf_alloc(void *arg) pthread_handler_t test_lf_alloc(void *arg)
{ {
int m=(*(int *)arg)/2; int m= (*(int *)arg)/2;
int32 x,y=0; int32 x,y= 0;
LF_PINS *pins; LF_PINS *pins;
pins=lf_alloc_get_pins(&lf_allocator); pins= lf_alloc_get_pins(&lf_allocator);
for (x=((int)(intptr)(&m)); m ; m--) for (x= ((int)(intptr)(&m)); m ; m--)
{ {
TLA *node1, *node2; TLA *node1, *node2;
x=(x*m+0x87654321) & INT_MAX32; x= (x*m+0x87654321) & INT_MAX32;
node1=(TLA *)lf_alloc_new(pins); node1= (TLA *)lf_alloc_new(pins);
node1->data=x; node1->data= x;
y+=node1->data; y+= node1->data;
node1->data=0; node1->data= 0;
node2=(TLA *)lf_alloc_new(pins); node2= (TLA *)lf_alloc_new(pins);
node2->data=x; node2->data= x;
y-=node2->data; y-= node2->data;
node2->data=0; node2->data= 0;
lf_alloc_free(pins, node1); lf_alloc_free(pins, node1);
lf_alloc_free(pins, node2); lf_alloc_free(pins, node2);
} }
lf_alloc_put_pins(pins); lf_alloc_put_pins(pins);
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
my_atomic_add32(&a32, y); my_atomic_add32(&a32, y);
my_atomic_rwlock_wrunlock(&rwl);
pthread_mutex_lock(&mutex); if (my_atomic_add32(&N, -1) == 1)
N--;
if (!N)
{ {
diag("%d mallocs, %d pins in stack", diag("%d mallocs, %d pins in stack",
lf_allocator.mallocs, lf_allocator.pinbox.pins_in_stack); lf_allocator.mallocs, lf_allocator.pinbox.pins_in_stack);
#ifdef MY_LF_EXTRA_DEBUG #ifdef MY_LF_EXTRA_DEBUG
a32|=lf_allocator.mallocs - lf_alloc_in_pool(&lf_allocator); a32|= lf_allocator.mallocs - lf_alloc_in_pool(&lf_allocator);
#endif #endif
pthread_cond_signal(&cond);
} }
pthread_mutex_unlock(&mutex); my_atomic_rwlock_wrunlock(&rwl);
return 0; return 0;
} }
#define N_TLH 1000 #define N_TLH 1000
pthread_handler_t test_lf_hash(void *arg) pthread_handler_t test_lf_hash(void *arg)
{ {
int m=(*(int *)arg)/(2*N_TLH); int m= (*(int *)arg)/(2*N_TLH);
int32 x,y,z,sum=0, ins=0; int32 x,y,z,sum= 0, ins= 0;
LF_PINS *pins; LF_PINS *pins;
pins=lf_hash_get_pins(&lf_hash); pins= lf_hash_get_pins(&lf_hash);
for (x=((int)(intptr)(&m)); m ; m--) for (x= ((int)(intptr)(&m)); m ; m--)
{ {
int i; int i;
y=x; y= x;
for (i=0; i < N_TLH; i++) for (i= 0; i < N_TLH; i++)
{ {
x=(x*(m+i)+0x87654321) & INT_MAX32; x= (x*(m+i)+0x87654321) & INT_MAX32;
z=(x<0) ? -x : x; z= (x<0) ? -x : x;
if (lf_hash_insert(&lf_hash, pins, &z)) if (lf_hash_insert(&lf_hash, pins, &z))
{ {
sum+=z; sum+= z;
ins++; ins++;
} }
} }
for (i=0; i < N_TLH; i++) for (i= 0; i < N_TLH; i++)
{ {
y=(y*(m+i)+0x87654321) & INT_MAX32; y= (y*(m+i)+0x87654321) & INT_MAX32;
z=(y<0) ? -y : y; z= (y<0) ? -y : y;
if (lf_hash_delete(&lf_hash, pins, (uchar *)&z, sizeof(z))) if (lf_hash_delete(&lf_hash, pins, (uchar *)&z, sizeof(z)))
sum-=z; sum-= z;
} }
} }
lf_hash_put_pins(pins); lf_hash_put_pins(pins);
my_atomic_rwlock_wrlock(&rwl); my_atomic_rwlock_wrlock(&rwl);
my_atomic_add32(&a32, sum); my_atomic_add32(&a32, sum);
my_atomic_add32(&b32, ins); my_atomic_add32(&b32, ins);
my_atomic_rwlock_wrunlock(&rwl); my_atomic_add32(&a32, y);
pthread_mutex_lock(&mutex);
N--; if (my_atomic_add32(&N, -1) == 1)
if (!N)
{ {
diag("%d mallocs, %d pins in stack, %d hash size, %d inserts", diag("%d mallocs, %d pins in stack, %d hash size, %d inserts",
lf_hash.alloc.mallocs, lf_hash.alloc.pinbox.pins_in_stack, lf_hash.alloc.mallocs, lf_hash.alloc.pinbox.pins_in_stack,
lf_hash.size, b32); lf_hash.size, b32);
a32|=lf_hash.count; a32|= lf_hash.count;
pthread_cond_signal(&cond);
} }
pthread_mutex_unlock(&mutex); my_atomic_rwlock_wrunlock(&rwl);
return 0; return 0;
} }
void test_atomic(const char *test, pthread_handler handler, int n, int m) void test_atomic(const char *test, pthread_handler handler, int n, int m)
{ {
pthread_t t; pthread_t *threads;
ulonglong now=my_getsystime(); ulonglong now= my_getsystime();
int i;
a32= 0; a32= 0;
b32= 0; b32= 0;
c32= 0; c32= 0;
threads= (pthread_t *)my_malloc(sizeof(void *)*n, MYF(0));
if (!threads)
{
diag("Out of memory");
abort();
}
diag("Testing %s with %d threads, %d iterations... ", test, n, m); diag("Testing %s with %d threads, %d iterations... ", test, n, m);
for (N=n ; n ; n--) N= n;
for (i= 0 ; i < n ; i++)
{ {
if (pthread_create(&t, &thr_attr, handler, &m) != 0) if (pthread_create(threads+i, 0, handler, &m) != 0)
{ {
diag("Could not create thread"); diag("Could not create thread");
a32= 1; abort();
goto err;
} }
} }
pthread_mutex_lock(&mutex); for (i= 0 ; i < n ; i++)
while (N) pthread_join(threads[i], 0);
pthread_cond_wait(&cond, &mutex); now= my_getsystime()-now;
pthread_mutex_unlock(&mutex);
now=my_getsystime()-now;
err: err:
ok(a32 == 0, "tested %s in %g secs (%d)", test, ((double)now)/1e7, a32); ok(a32 == 0, "tested %s in %g secs (%d)", test, ((double)now)/1e7, a32);
my_free((void *)threads, MYF(0));
} }
int main() int main()
...@@ -289,10 +269,6 @@ int main() ...@@ -289,10 +269,6 @@ int main()
plan(7); plan(7);
ok(err == 0, "my_atomic_initialize() returned %d", err); ok(err == 0, "my_atomic_initialize() returned %d", err);
pthread_attr_init(&thr_attr);
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0);
my_atomic_rwlock_init(&rwl); my_atomic_rwlock_init(&rwl);
lf_alloc_init(&lf_allocator, sizeof(TLA), offsetof(TLA, not_used)); lf_alloc_init(&lf_allocator, sizeof(TLA), offsetof(TLA, not_used));
lf_hash_init(&lf_hash, sizeof(int), LF_HASH_UNIQUE, 0, sizeof(int), 0, lf_hash_init(&lf_hash, sizeof(int), LF_HASH_UNIQUE, 0, sizeof(int), 0,
...@@ -315,9 +291,6 @@ int main() ...@@ -315,9 +291,6 @@ int main()
lf_hash_destroy(&lf_hash); lf_hash_destroy(&lf_hash);
lf_alloc_destroy(&lf_allocator); lf_alloc_destroy(&lf_allocator);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
pthread_attr_destroy(&thr_attr);
my_atomic_rwlock_destroy(&rwl); my_atomic_rwlock_destroy(&rwl);
my_end(0); my_end(0);
return exit_status(); return exit_status();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment