You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by da...@apache.org on 2007/07/05 16:15:48 UTC

svn commit: r553514 - /apr/apr/trunk/test/testatomic.c

Author: davi
Date: Thu Jul  5 07:15:47 2007
New Revision: 553514

URL: http://svn.apache.org/viewvc?view=rev&rev=553514
Log:
Add a threaded atomic test that busy-loops on a count variable. Once the count
variable meets a predetermined value for each thread, the count will be atomically
changed, triggering another busy-loop (on another thread), and so on..

Modified:
    apr/apr/trunk/test/testatomic.c

Modified: apr/apr/trunk/test/testatomic.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/test/testatomic.c?view=diff&rev=553514&r1=553513&r2=553514
==============================================================================
--- apr/apr/trunk/test/testatomic.c (original)
+++ apr/apr/trunk/test/testatomic.c Thu Jul  5 07:15:47 2007
@@ -220,6 +220,7 @@
 
 #define NUM_THREADS 40
 #define NUM_ITERATIONS 20000
+
 void *APR_THREAD_FUNC thread_func_mutex(apr_thread_t *thd, void *data)
 {
     int i;
@@ -280,6 +281,205 @@
     ABTS_INT_EQUAL(tc, mutex_locks, NUM_THREADS * NUM_ITERATIONS);
     ABTS_INT_EQUAL(tc, apr_atomic_read32(&atomic_ops),
                    NUM_THREADS * NUM_ITERATIONS);
+
+    rv = apr_thread_mutex_destroy(thread_lock);
+    ABTS_ASSERT(tc, "Failed creating threads", rv == APR_SUCCESS);
+}
+
+#undef NUM_THREADS
+#define NUM_THREADS 7
+
+typedef struct tbox_t tbox_t;
+
+struct tbox_t {
+    abts_case *tc;
+    apr_uint32_t *mem;
+    apr_uint32_t preval;
+    apr_uint32_t postval;
+    apr_uint32_t loop;
+    void (*func)(tbox_t *box);
+};
+
+static void busyloop_set32(tbox_t *tbox)
+{
+    apr_uint32_t val;
+
+    do {
+        do {
+            val = apr_atomic_read32(tbox->mem);
+        } while (val != tbox->preval);
+
+        apr_atomic_set32(tbox->mem, tbox->postval);
+    } while (--tbox->loop);
+}
+
+static void busyloop_add32(tbox_t *tbox)
+{
+    apr_uint32_t val;
+
+    do {
+        do {
+            val = apr_atomic_read32(tbox->mem);
+        } while (val != tbox->preval);
+
+        val = apr_atomic_add32(tbox->mem, tbox->postval);
+
+        apr_thread_mutex_lock(thread_lock);
+        ABTS_INT_EQUAL(tbox->tc, val, tbox->preval);
+        apr_thread_mutex_unlock(thread_lock);
+    } while (--tbox->loop);
+}
+
+static void busyloop_sub32(tbox_t *tbox)
+{
+    apr_uint32_t val;
+
+    do {
+        do {
+            val = apr_atomic_read32(tbox->mem);
+        } while (val != tbox->preval);
+
+        apr_atomic_sub32(tbox->mem, tbox->postval);
+    } while (--tbox->loop);
+}
+
+static void busyloop_inc32(tbox_t *tbox)
+{
+    apr_uint32_t val;
+
+    do {
+        do {
+            val = apr_atomic_read32(tbox->mem);
+        } while (val != tbox->preval);
+
+        val = apr_atomic_inc32(tbox->mem);
+
+        apr_thread_mutex_lock(thread_lock);
+        ABTS_INT_EQUAL(tbox->tc, val, tbox->preval);
+        apr_thread_mutex_unlock(thread_lock);
+    } while (--tbox->loop);
+}
+
+static void busyloop_dec32(tbox_t *tbox)
+{
+    apr_uint32_t val;
+
+    do {
+        do {
+            val = apr_atomic_read32(tbox->mem);
+        } while (val != tbox->preval);
+
+        val = apr_atomic_dec32(tbox->mem);
+
+        apr_thread_mutex_lock(thread_lock);
+        ABTS_INT_NEQUAL(tbox->tc, val, 0);
+        apr_thread_mutex_unlock(thread_lock);
+    } while (--tbox->loop);
+}
+
+static void busyloop_cas32(tbox_t *tbox)
+{
+    apr_uint32_t val;
+
+    do {
+        do {
+            val = apr_atomic_cas32(tbox->mem, tbox->postval, tbox->preval);
+        } while (val != tbox->preval);
+    } while (--tbox->loop);
+}
+
+static void busyloop_xchg32(tbox_t *tbox)
+{
+    apr_uint32_t val;
+
+    do {
+        do {
+            val = apr_atomic_read32(tbox->mem);
+        } while (val != tbox->preval);
+
+        val = apr_atomic_xchg32(tbox->mem, tbox->postval);
+
+        apr_thread_mutex_lock(thread_lock);
+        ABTS_INT_EQUAL(tbox->tc, val, tbox->preval);
+        apr_thread_mutex_unlock(thread_lock);
+    } while (--tbox->loop);
+}
+
+void *APR_THREAD_FUNC thread_func_busyloop(apr_thread_t *thd, void *data)
+{
+    tbox_t *tbox = data;
+
+    tbox->func(tbox);
+
+    return NULL;
+}
+
+static void test_atomics_busyloop_threaded(abts_case *tc, void *data)
+{
+    unsigned int i;
+    apr_status_t rv;
+    apr_uint32_t count = 0;
+    tbox_t tbox[NUM_THREADS];
+    apr_thread_t *thread[NUM_THREADS];
+
+    rv = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_DEFAULT, p);
+    APR_ASSERT_SUCCESS(tc, "Could not create lock", rv);
+
+    /* get ready */
+    for (i = 0; i < NUM_THREADS; i++) {
+        tbox[i].tc = tc;
+        tbox[i].mem = &count;
+        tbox[i].loop = 5;
+    }
+
+    tbox[0].preval = 98;
+    tbox[0].postval = 3891;
+    tbox[0].func = busyloop_add32;
+
+    tbox[1].preval = 3989;
+    tbox[1].postval = 1010;
+    tbox[1].func = busyloop_sub32;
+
+    tbox[2].preval = 2979;
+    tbox[2].postval = 0; /* not used */
+    tbox[2].func = busyloop_inc32;
+
+    tbox[3].preval = 2980;
+    tbox[3].postval = 16384;
+    tbox[3].func = busyloop_set32;
+
+    tbox[4].preval = 16384;
+    tbox[4].postval = 0; /* not used */
+    tbox[4].func = busyloop_dec32;
+
+    tbox[5].preval = 16383;
+    tbox[5].postval = 1048576;
+    tbox[5].func = busyloop_cas32;
+
+    tbox[6].preval = 1048576;
+    tbox[6].postval = 98; /* goto tbox[0] */
+    tbox[6].func = busyloop_xchg32;
+
+    /* get set */
+    for (i = 0; i < NUM_THREADS; i++) {
+        rv = apr_thread_create(&thread[i], NULL, thread_func_busyloop,
+                               &tbox[i], p);
+        ABTS_ASSERT(tc, "Failed creating thread", rv == APR_SUCCESS);
+    }
+
+    /* go! */
+    apr_atomic_set32(tbox->mem, 98);
+
+    for (i = 0; i < NUM_THREADS; i++) {
+        apr_status_t retval;
+        rv = apr_thread_join(&retval, thread[i]);
+        ABTS_ASSERT(tc, "Thread join failed", rv == APR_SUCCESS);
+    }
+
+    ABTS_INT_EQUAL(tbox->tc, count, 98);
+
+    rv = apr_thread_mutex_destroy(thread_lock);
+    ABTS_ASSERT(tc, "Failed creating threads", rv == APR_SUCCESS);
 }
 
 #endif /* !APR_HAS_THREADS */
@@ -307,6 +507,7 @@
 
 #if APR_HAS_THREADS
     abts_run_test(suite, test_atomics_threaded, NULL);
+    abts_run_test(suite, test_atomics_busyloop_threaded, NULL);
 #endif
 
     return suite;