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()
}
pthread_attr_t rt_attr;
pthread_mutex_t rt_mutex;
pthread_cond_t rt_cond;
int rt_num_threads;
int litmus;
int thread_number= 0, timeouts= 0;
void run_test(const char *test, pthread_handler handler, int n, int m)
{
pthread_t t;
pthread_t *threads;
ulonglong now= my_getsystime();
int i;
thread_number= timeouts= 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);
for (rt_num_threads= n ; n ; n--)
if (pthread_create(&t, &rt_attr, handler, &m))
rt_num_threads= n;
for (i= 0; i < n ; i++)
if (pthread_create(threads+i, 0, handler, &m))
{
diag("Could not create thread");
litmus++;
rt_num_threads--;
abort();
}
pthread_mutex_lock(&rt_mutex);
while (rt_num_threads)
pthread_cond_wait(&rt_cond, &rt_mutex);
pthread_mutex_unlock(&rt_mutex);
for (i= 0 ; i < n ; i++)
pthread_join(threads[i], 0);
now= my_getsystime()-now;
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 Ntables= 10;
int table_lock_ratio= 10;
......@@ -222,10 +227,7 @@ pthread_handler_t test_lockman(void *arg)
rt_num_threads--;
timeouts+= timeout;
if (!rt_num_threads)
{
pthread_cond_signal(&rt_cond);
diag("number of timeouts: %d", timeouts);
}
pthread_mutex_unlock(&rt_mutex);
return 0;
......@@ -236,16 +238,13 @@ int main()
int i;
my_init();
pthread_mutex_init(&rt_mutex, 0);
plan(31);
if (my_atomic_initialize())
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);
......@@ -294,8 +293,6 @@ int main()
}
pthread_mutex_destroy(&rt_mutex);
pthread_cond_destroy(&rt_cond);
pthread_attr_destroy(&rt_attr);
my_end(0);
return exit_status();
}
......
......@@ -22,9 +22,7 @@
#include <lf.h>
#include "../trnman.h"
pthread_attr_t rt_attr;
pthread_mutex_t rt_mutex;
pthread_cond_t rt_cond;
int rt_num_threads;
int litmus;
......@@ -74,8 +72,6 @@ end:
}
pthread_mutex_lock(&rt_mutex);
rt_num_threads--;
if (!rt_num_threads)
pthread_cond_signal(&rt_cond);
pthread_mutex_unlock(&rt_mutex);
return 0;
......@@ -84,25 +80,32 @@ end:
void run_test(const char *test, pthread_handler handler, int n, int m)
{
pthread_t t;
pthread_t *threads;
ulonglong now= my_getsystime();
int i;
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);
for (rt_num_threads= n ; n ; n--)
if (pthread_create(&t, &rt_attr, handler, &m))
rt_num_threads= n;
for (i= 0; i < n ; i++)
if (pthread_create(threads+i, 0, handler, &m))
{
diag("Could not create thread");
litmus++;
rt_num_threads--;
abort();
}
pthread_mutex_lock(&rt_mutex);
while (rt_num_threads)
pthread_cond_wait(&rt_cond, &rt_mutex);
pthread_mutex_unlock(&rt_mutex);
for (i= 0 ; i < n ; i++)
pthread_join(threads[i], 0);
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) \
......@@ -157,10 +160,7 @@ int main()
if (my_atomic_initialize())
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);
#define CYCLES 10000
#define THREADS 10
......@@ -179,8 +179,6 @@ int main()
}
pthread_mutex_destroy(&rt_mutex);
pthread_cond_destroy(&rt_cond);
pthread_attr_destroy(&rt_attr);
my_end(0);
return exit_status();
}
......
......@@ -21,24 +21,19 @@
#include <my_atomic.h>
#include <lf.h>
volatile uint32 a32,b32,c32;
volatile uint32 a32,b32,c32, N;
my_atomic_rwlock_t rwl;
LF_ALLOCATOR lf_allocator;
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 */
pthread_handler_t test_atomic_add_handler(void *arg)
{
int m=(*(int *)arg)/2;
int m= (*(int *)arg)/2;
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_add32(&a32, x);
my_atomic_rwlock_wrunlock(&rwl);
......@@ -47,10 +42,6 @@ pthread_handler_t test_atomic_add_handler(void *arg)
my_atomic_add32(&a32, -x);
my_atomic_rwlock_wrunlock(&rwl);
}
pthread_mutex_lock(&mutex);
N--;
if (!N) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0;
}
......@@ -64,22 +55,22 @@ pthread_handler_t test_atomic_add_handler(void *arg)
*/
pthread_handler_t test_atomic_fas_handler(void *arg)
{
int m=*(int *)arg;
uint32 x=my_atomic_add32(&b32, 1);
int m= *(int *)arg;
uint32 x= my_atomic_add32(&b32, 1);
my_atomic_add32(&a32, x);
for (; m ; m--)
{
my_atomic_rwlock_wrlock(&rwl);
x=my_atomic_fas32(&c32, x);
x= my_atomic_fas32(&c32, x);
my_atomic_rwlock_wrunlock(&rwl);
}
if (!x)
{
my_atomic_rwlock_wrlock(&rwl);
x=my_atomic_fas32(&c32, x);
x= my_atomic_fas32(&c32, x);
my_atomic_rwlock_wrunlock(&rwl);
}
......@@ -87,10 +78,6 @@ pthread_handler_t test_atomic_fas_handler(void *arg)
my_atomic_add32(&a32, -x);
my_atomic_rwlock_wrunlock(&rwl);
pthread_mutex_lock(&mutex);
N--;
if (!N) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0;
}
......@@ -101,29 +88,25 @@ pthread_handler_t test_atomic_fas_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;
for (x=((int)(intptr)(&m)); m ; m--)
for (x= ((int)(intptr)(&m)); m ; m--)
{
my_atomic_rwlock_wrlock(&rwl);
y=my_atomic_load32(&a32);
y= my_atomic_load32(&a32);
my_atomic_rwlock_wrunlock(&rwl);
x=(x*m+0x87654321) & INT_MAX32;
x= (x*m+0x87654321) & INT_MAX32;
do {
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);
} while (!ok) ;
do {
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);
} while (!ok) ;
}
pthread_mutex_lock(&mutex);
N--;
if (!N) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0;
}
......@@ -132,23 +115,18 @@ pthread_handler_t test_atomic_cas_handler(void *arg)
*/
pthread_handler_t test_lf_pinbox(void *arg)
{
int m=*(int *)arg;
int32 x=0;
int m= *(int *)arg;
int32 x= 0;
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);
pins=lf_pinbox_get_pins(&lf_allocator.pinbox);
pins= lf_pinbox_get_pins(&lf_allocator.pinbox);
}
lf_pinbox_put_pins(pins);
pthread_mutex_lock(&mutex);
N--;
if (!N)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return 0;
}
......@@ -159,122 +137,124 @@ typedef union {
pthread_handler_t test_lf_alloc(void *arg)
{
int m=(*(int *)arg)/2;
int32 x,y=0;
int m= (*(int *)arg)/2;
int32 x,y= 0;
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;
x=(x*m+0x87654321) & INT_MAX32;
node1=(TLA *)lf_alloc_new(pins);
node1->data=x;
y+=node1->data;
node1->data=0;
node2=(TLA *)lf_alloc_new(pins);
node2->data=x;
y-=node2->data;
node2->data=0;
x= (x*m+0x87654321) & INT_MAX32;
node1= (TLA *)lf_alloc_new(pins);
node1->data= x;
y+= node1->data;
node1->data= 0;
node2= (TLA *)lf_alloc_new(pins);
node2->data= x;
y-= node2->data;
node2->data= 0;
lf_alloc_free(pins, node1);
lf_alloc_free(pins, node2);
}
lf_alloc_put_pins(pins);
my_atomic_rwlock_wrlock(&rwl);
my_atomic_add32(&a32, y);
my_atomic_rwlock_wrunlock(&rwl);
pthread_mutex_lock(&mutex);
N--;
if (!N)
if (my_atomic_add32(&N, -1) == 1)
{
diag("%d mallocs, %d pins in stack",
lf_allocator.mallocs, lf_allocator.pinbox.pins_in_stack);
#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
pthread_cond_signal(&cond);
}
pthread_mutex_unlock(&mutex);
my_atomic_rwlock_wrunlock(&rwl);
return 0;
}
#define N_TLH 1000
pthread_handler_t test_lf_hash(void *arg)
{
int m=(*(int *)arg)/(2*N_TLH);
int32 x,y,z,sum=0, ins=0;
int m= (*(int *)arg)/(2*N_TLH);
int32 x,y,z,sum= 0, ins= 0;
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;
y=x;
for (i=0; i < N_TLH; i++)
y= x;
for (i= 0; i < N_TLH; i++)
{
x=(x*(m+i)+0x87654321) & INT_MAX32;
z=(x<0) ? -x : x;
x= (x*(m+i)+0x87654321) & INT_MAX32;
z= (x<0) ? -x : x;
if (lf_hash_insert(&lf_hash, pins, &z))
{
sum+=z;
sum+= z;
ins++;
}
}
for (i=0; i < N_TLH; i++)
for (i= 0; i < N_TLH; i++)
{
y=(y*(m+i)+0x87654321) & INT_MAX32;
z=(y<0) ? -y : y;
y= (y*(m+i)+0x87654321) & INT_MAX32;
z= (y<0) ? -y : y;
if (lf_hash_delete(&lf_hash, pins, (uchar *)&z, sizeof(z)))
sum-=z;
sum-= z;
}
}
lf_hash_put_pins(pins);
my_atomic_rwlock_wrlock(&rwl);
my_atomic_add32(&a32, sum);
my_atomic_add32(&b32, ins);
my_atomic_rwlock_wrunlock(&rwl);
pthread_mutex_lock(&mutex);
N--;
if (!N)
my_atomic_add32(&a32, y);
if (my_atomic_add32(&N, -1) == 1)
{
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.size, b32);
a32|=lf_hash.count;
pthread_cond_signal(&cond);
a32|= lf_hash.count;
}
pthread_mutex_unlock(&mutex);
my_atomic_rwlock_wrunlock(&rwl);
return 0;
}
void test_atomic(const char *test, pthread_handler handler, int n, int m)
{
pthread_t t;
ulonglong now=my_getsystime();
pthread_t *threads;
ulonglong now= my_getsystime();
int i;
a32= 0;
b32= 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);
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");
a32= 1;
goto err;
abort();
}
}
pthread_mutex_lock(&mutex);
while (N)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
now=my_getsystime()-now;
for (i= 0 ; i < n ; i++)
pthread_join(threads[i], 0);
now= my_getsystime()-now;
err:
ok(a32 == 0, "tested %s in %g secs (%d)", test, ((double)now)/1e7, a32);
my_free((void *)threads, MYF(0));
}
int main()
......@@ -289,10 +269,6 @@ int main()
plan(7);
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);
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,
......@@ -315,9 +291,6 @@ int main()
lf_hash_destroy(&lf_hash);
lf_alloc_destroy(&lf_allocator);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
pthread_attr_destroy(&thr_attr);
my_atomic_rwlock_destroy(&rwl);
my_end(0);
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