summaryrefslogtreecommitdiff
path: root/unittest/mysys/my_atomic-t.c
diff options
context:
space:
mode:
Diffstat (limited to 'unittest/mysys/my_atomic-t.c')
-rw-r--r--unittest/mysys/my_atomic-t.c86
1 files changed, 63 insertions, 23 deletions
diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c
index a24cbae272a..a5fa4c1bfe8 100644
--- a/unittest/mysys/my_atomic-t.c
+++ b/unittest/mysys/my_atomic-t.c
@@ -31,8 +31,10 @@ volatile int32 c32, N;
my_atomic_rwlock_t rwl;
LF_ALLOCATOR lf_allocator;
LF_HASH lf_hash;
-
-pthread_attr_t attr;
+pthread_attr_t thr_attr;
+pthread_mutex_t mutex;
+pthread_cond_t cond;
+uint running_threads;
size_t stacksize= 0;
#define STACK_SIZE (((int)stacksize-2048)*STACK_DIRECTION)
@@ -52,6 +54,9 @@ pthread_handler_t test_atomic_add_handler(void *arg)
my_atomic_add32(&a32, -x);
my_atomic_rwlock_wrunlock(&rwl);
}
+ pthread_mutex_lock(&mutex);
+ if (!--running_threads) pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
return 0;
}
@@ -66,9 +71,15 @@ 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);
+ int32 x;
+ my_atomic_rwlock_wrlock(&rwl);
+ x= my_atomic_add32(&b32, 1);
+ my_atomic_rwlock_wrunlock(&rwl);
+
+ my_atomic_rwlock_wrlock(&rwl);
my_atomic_add32(&a32, x);
+ my_atomic_rwlock_wrunlock(&rwl);
for (; m ; m--)
{
@@ -88,6 +99,9 @@ pthread_handler_t test_atomic_fas_handler(void *arg)
my_atomic_add32(&a32, -x);
my_atomic_rwlock_wrunlock(&rwl);
+ pthread_mutex_lock(&mutex);
+ if (!--running_threads) pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
return 0;
}
@@ -117,9 +131,13 @@ pthread_handler_t test_atomic_cas_handler(void *arg)
my_atomic_rwlock_wrunlock(&rwl);
} while (!ok) ;
}
+ pthread_mutex_lock(&mutex);
+ if (!--running_threads) pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
return 0;
}
+
/*
pin allocator - alloc and release an element in a loop
*/
@@ -137,6 +155,9 @@ pthread_handler_t test_lf_pinbox(void *arg)
pins= lf_pinbox_get_pins(&lf_allocator.pinbox, &m + STACK_SIZE);
}
lf_pinbox_put_pins(pins);
+ pthread_mutex_lock(&mutex);
+ if (!--running_threads) pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
return 0;
}
@@ -181,6 +202,9 @@ pthread_handler_t test_lf_alloc(void *arg)
#endif
}
my_atomic_rwlock_wrunlock(&rwl);
+ pthread_mutex_lock(&mutex);
+ if (!--running_threads) pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
return 0;
}
@@ -228,44 +252,40 @@ pthread_handler_t test_lf_hash(void *arg)
a32|= lf_hash.count;
}
my_atomic_rwlock_wrunlock(&rwl);
+ pthread_mutex_lock(&mutex);
+ if (!--running_threads) pthread_cond_signal(&cond);
+ pthread_mutex_unlock(&mutex);
return 0;
}
+
void test_atomic(const char *test, pthread_handler handler, int n, int m)
{
- pthread_t *threads;
+ pthread_t t;
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);
- N= n;
- for (i= 0 ; i < n ; i++)
+ for (running_threads= n ; n ; n--)
{
- if (pthread_create(threads+i, 0, handler, &m) != 0)
+ if (pthread_create(&t, &thr_attr, handler, &m) != 0)
{
diag("Could not create thread");
abort();
}
}
- for (i= 0 ; i < n ; i++)
- pthread_join(threads[i], 0);
+ pthread_mutex_lock(&mutex);
+ while (running_threads)
+ pthread_cond_wait(&cond, &mutex);
+ pthread_mutex_unlock(&mutex);
+
now= my_getsystime()-now;
ok(a32 == 0, "tested %s in %g secs (%d)", test, ((double)now)/1e7, a32);
- my_free((void *)threads, MYF(0));
}
-
int main()
{
int err;
@@ -277,23 +297,34 @@ int main()
plan(7);
ok(err == 0, "my_atomic_initialize() returned %d", err);
+ 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,
&my_charset_bin);
-
- pthread_attr_init(&attr);
+ pthread_attr_init(&thr_attr);
+ pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
- pthread_attr_getstacksize(&attr, &stacksize);
+ pthread_attr_getstacksize(&thr_attr, &stacksize);
if (stacksize == 0)
#endif
- stacksize= PTHREAD_STACK_MIN;
+ stacksize = PTHREAD_STACK_MIN;
+
#ifdef MY_ATOMIC_MODE_RWLOCKS
+#ifdef HPUX11 /* showed to be very slow (scheduler-related) */
+#define CYCLES 300
+#else
#define CYCLES 3000
+#endif
+#else
+#ifdef HPUX11
+#define CYCLES 30000
#else
#define CYCLES 300000
#endif
+#endif
#define THREADS 100
test_atomic("my_atomic_add32", test_atomic_add_handler, THREADS,CYCLES);
@@ -305,6 +336,15 @@ int main()
lf_hash_destroy(&lf_hash);
lf_alloc_destroy(&lf_allocator);
+
+ /*
+ workaround until we know why it crashes randomly on some machine
+ (BUG#22320).
+ */
+ sleep(2);
+ pthread_mutex_destroy(&mutex);
+ pthread_cond_destroy(&cond);
+ pthread_attr_destroy(&thr_attr);
my_atomic_rwlock_destroy(&rwl);
my_end(0);
return exit_status();