diff options
author | Ryan Bloom <rbb@apache.org> | 2004-03-13 00:28:45 +0000 |
---|---|---|
committer | Ryan Bloom <rbb@apache.org> | 2004-03-13 00:28:45 +0000 |
commit | 9088f678ac1ef2bffae465d5e0e788b20f3d8826 (patch) | |
tree | 92e309628db9b3723330f6d2a2450a290dcbda8b /test/testatomic.c | |
parent | ae9e0f4df0da4c0276c967baafc598f8be346eb9 (diff) | |
download | apr-9088f678ac1ef2bffae465d5e0e788b20f3d8826.tar.gz |
Migrate testatomic to testall. I have commented out a test that
specifically states that we expect it to fail. We aren't actually testing
APR with that test.
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@64970 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test/testatomic.c')
-rw-r--r-- | test/testatomic.c | 426 |
1 files changed, 173 insertions, 253 deletions
diff --git a/test/testatomic.c b/test/testatomic.c index d0955489b..92c314179 100644 --- a/test/testatomic.c +++ b/test/testatomic.c @@ -13,17 +13,13 @@ * limitations under the License. */ -#include <stdio.h> -#include <stdlib.h> +#include "test_apr.h" +#include "apr_strings.h" #include "apr_thread_proc.h" #include "apr_errno.h" #include "apr_general.h" #include "apr_atomic.h" -#include "errno.h" #include "apr_time.h" -#if APR_HAVE_UNISTD_H -#include <unistd.h> -#endif /* Use pthread_setconcurrency where it is available and not a nullop, * i.e. platforms using M:N or M:1 thread models: */ @@ -37,179 +33,159 @@ #include <pthread.h> #endif -apr_pool_t *context; -apr_uint32_t y; /* atomic locks */ -apr_uint32_t y32; +static void test_init(CuTest *tc) +{ + apr_assert_success(tc, "Could not initliaze atomics", apr_atomic_init(p)); +} -static apr_status_t check_basic_atomics32(void) +static void test_set32(CuTest *tc) { - apr_uint32_t oldval; - apr_uint32_t casval = 0; - apr_uint32_t minus1 = -1; + apr_uint32_t y32; + apr_atomic_set32(&y32, 2); + CuAssertIntEquals(tc, 2, y32); +} +static void test_read32(CuTest *tc) +{ + apr_uint32_t y32; apr_atomic_set32(&y32, 2); - printf("%-60s", "testing apr_atomic_dec32"); - if (apr_atomic_dec32(&y32) == 0) { - fprintf(stderr, "Failed\noldval =%d should not be zero\n", - apr_atomic_read32(&y32)); - return APR_EGENERAL; - } - if (apr_atomic_dec32(&y32) != 0) { - fprintf(stderr, "Failed\noldval =%d should be zero\n", - apr_atomic_read32(&y32)); - return APR_EGENERAL; - } - printf("OK\n"); + CuAssertIntEquals(tc, 2, apr_atomic_read32(&y32)); +} + +static void test_dec32(CuTest *tc) +{ + apr_uint32_t y32; + int rv; + + apr_atomic_set32(&y32, 2); + + rv = apr_atomic_dec32(&y32); + CuAssertIntEquals(tc, 1, y32); + CuAssert(tc, "atomic_dec returned zero when it shouldn't", rv != 0); + + rv = apr_atomic_dec32(&y32); + CuAssertIntEquals(tc, 0, y32); + CuAssert(tc, "atomic_dec didn't returned zero when it should", rv == 0); +} + +static void test_xchg32(CuTest *tc) +{ + apr_uint32_t oldval; + apr_uint32_t y32; - printf("%-60s", "testing apr_atomic_xchg32"); apr_atomic_set32(&y32, 100); oldval = apr_atomic_xchg32(&y32, 50); - if (oldval != 100) { - fprintf(stderr, "Failed\noldval =%d should be 100\n", oldval); - return APR_EGENERAL; - } - if (y32 != 50) { - fprintf(stderr, "Failed\nnewval =%d should be 50\n", oldval); - return APR_EGENERAL; - } - printf("OK\n"); - printf("%-60s", "testing apr_atomic_cas32"); + CuAssertIntEquals(tc, 100, oldval); + CuAssertIntEquals(tc, 50, y32); +} + +static void test_cas_equal(CuTest *tc) +{ + apr_uint32_t casval = 0; + apr_uint32_t oldval; + oldval = apr_atomic_cas32(&casval, 12, 0); - if (oldval != 0) { - fprintf(stderr, "Failed\noldval =%d should be zero\n", oldval); - return APR_EGENERAL; - } - printf("OK\n"); - printf("%-60s", "testing apr_atomic_cas32 - match non-null"); - oldval = apr_atomic_cas32(&casval, 23, 12); - if (oldval != 12) { - fprintf(stderr, "Failed\noldval =%d should be 12 y=%d\n", - oldval, casval); - return APR_EGENERAL; - } - printf("OK\n"); - printf("%-60s", "testing apr_atomic_cas32 - no match"); + CuAssertIntEquals(tc, 0, oldval); + CuAssertIntEquals(tc, 12, casval); +} + +static void test_cas_equal_nonnull(CuTest *tc) +{ + apr_uint32_t casval = 12; + apr_uint32_t oldval; + oldval = apr_atomic_cas32(&casval, 23, 12); - if (oldval != 23) { - fprintf(stderr, "Failed\noldval =%d should be 23 y=%d\n", - oldval, casval); - return APR_EGENERAL; - } - printf("OK\n"); + CuAssertIntEquals(tc, 12, oldval); + CuAssertIntEquals(tc, 23, casval); +} + +static void test_cas_notequal(CuTest *tc) +{ + apr_uint32_t casval = 12; + apr_uint32_t oldval; + + oldval = apr_atomic_cas32(&casval, 23, 2); + CuAssertIntEquals(tc, 12, oldval); + CuAssertIntEquals(tc, 12, casval); +} + +static void test_add32(CuTest *tc) +{ + apr_uint32_t oldval; + apr_uint32_t y32; - printf("%-60s", "testing apr_atomic_add32"); apr_atomic_set32(&y32, 23); - if ((oldval = apr_atomic_add32(&y32, 4)) != 23) { - fprintf(stderr, - "Failed\noldval problem =%d should be 23\n", - oldval); - return APR_EGENERAL; - } - if ((oldval = apr_atomic_read32(&y32)) != 27) { - fprintf(stderr, - "Failed\nAtomic Add doesn't add up ;( expected 27 got %d\n", - oldval); - return APR_EGENERAL; - } - printf("OK\n"); - - printf("%-60s", "testing apr_atomic_inc32"); - if ((oldval = apr_atomic_inc32(&y32)) != 27) { - fprintf(stderr, - "Failed\noldval problem =%d should be 27\n", - oldval); - return APR_EGENERAL; - } - if ((oldval = apr_atomic_read32(&y32)) != 28) { - fprintf(stderr, - "Failed\nAtomic Inc didn't increment ;( expected 28 got %d\n", - oldval); - return APR_EGENERAL; - } - printf("OK\n"); + oldval = apr_atomic_add32(&y32, 4); + CuAssertIntEquals(tc, 23, oldval); + CuAssertIntEquals(tc, 27, y32); +} + +static void test_inc32(CuTest *tc) +{ + apr_uint32_t oldval; + apr_uint32_t y32; + + apr_atomic_set32(&y32, 23); + oldval = apr_atomic_inc32(&y32); + CuAssertIntEquals(tc, 23, oldval); + CuAssertIntEquals(tc, 24, y32); +} + +static void test_set_add_inc_sub(CuTest *tc) +{ + apr_uint32_t y32; - printf("%-60s", "testing add32/inc32/sub32"); apr_atomic_set32(&y32, 0); apr_atomic_add32(&y32, 20); apr_atomic_inc32(&y32); apr_atomic_sub32(&y32, 10); - if (apr_atomic_read32(&y32) != 11) { - fprintf(stderr, "Failed.\natomics do not add up: expected 11 got %d\n", - apr_atomic_read32(&y32)); - return APR_EGENERAL; - } - fprintf(stdout, "OK\n"); - printf("%-60s", "testing wrapping around zero"); + CuAssertIntEquals(tc, 11, y32); +} - apr_atomic_set32(&y32, 0); - if (apr_atomic_dec32(&y32) == 0) { - fprintf(stderr, "apr_atomic_dec32 on zero returned zero.\n"); - return APR_EGENERAL; - } - if (apr_atomic_read32(&y32) != minus1) { - fprintf(stderr, "zero wrap failed: 0 - 1 = %d\n", - apr_atomic_read32(&y32)); - return APR_EGENERAL; - } +static void test_wrap_zero(CuTest *tc) +{ + apr_uint32_t y32; + apr_uint32_t rv; + apr_uint32_t minus1 = -1; - if (apr_atomic_inc32(&y32) != minus1) { - fprintf(stderr, "apr_atomic_inc32 on -1 returned bad value.\n"); - return APR_EGENERAL; - } - if (apr_atomic_read32(&y32) != 0) { - fprintf(stderr, "zero wrap failed: -1 + 1 = %u\n", - apr_atomic_read32(&y32)); - return APR_EGENERAL; - } - printf("OK\n"); + apr_atomic_set32(&y32, 0); + rv = apr_atomic_dec32(&y32); - return APR_SUCCESS; + CuAssert(tc, "apr_atomic_dec32 on zero returned zero.", rv != 0); + char *str = apr_psprintf(p, "zero wrap failed: 0 - 1 = %d", y32); + CuAssert(tc, str, y32 == minus1); } -#if !APR_HAS_THREADS -int main(void) +static void test_inc_neg1(CuTest *tc) { - apr_status_t rv; - - apr_initialize(); + apr_uint32_t y32 = -1; + apr_uint32_t minus1 = -1; + apr_uint32_t rv; - fprintf(stderr, - "This program won't work fully on this platform because there is no " - "support for threads.\n"); - if (apr_pool_create(&context, NULL) != APR_SUCCESS) { - fflush(stdout); - fprintf(stderr, "Failed.\nCould not initialize\n"); - exit(-1); - } - rv = apr_atomic_init(context); - if (rv != APR_SUCCESS) { - fprintf(stderr, "Failed.\nCould not initialize atomics\n"); - exit(-1); - } + rv = apr_atomic_inc32(&y32); - rv = check_basic_atomics32(); - if (rv != APR_SUCCESS) { - fprintf(stderr, "Failed.\n"); - exit(-1); - } - return 0; + CuAssert(tc, "apr_atomic_dec32 on zero returned zero.", rv == minus1); + char *str = apr_psprintf(p, "zero wrap failed: -1 + 1 = %d", y32); + CuAssert(tc, str, y32 == 0); } -#else /* !APR_HAS_THREADS */ + + +#if APR_HAS_THREADS void * APR_THREAD_FUNC thread_func_mutex(apr_thread_t *thd, void *data); void * APR_THREAD_FUNC thread_func_atomic(apr_thread_t *thd, void *data); void * APR_THREAD_FUNC thread_func_none(apr_thread_t *thd, void *data); apr_thread_mutex_t *thread_lock; -volatile long x = 0; /* mutex locks */ -volatile long z = 0; /* no locks */ -int value = 0; +volatile apr_uint32_t x = 0; /* mutex locks */ +volatile apr_uint32_t y = 0; /* atomic operations */ +volatile apr_uint32_t z = 0; /* no locks */ apr_status_t exit_ret_val = 123; /* just some made up number to check on later */ -#define NUM_THREADS 20 -#define NUM_ITERATIONS 200000 +#define NUM_THREADS 40 +#define NUM_ITERATIONS 20000 void * APR_THREAD_FUNC thread_func_mutex(apr_thread_t *thd, void *data) { int i; @@ -248,136 +224,80 @@ void * APR_THREAD_FUNC thread_func_none(apr_thread_t *thd, void *data) return NULL; } -int main(int argc, char**argv) +static void test_atomics_threaded(CuTest *tc) { apr_thread_t *t1[NUM_THREADS]; apr_thread_t *t2[NUM_THREADS]; + apr_thread_t *t3[NUM_THREADS]; apr_status_t r1[NUM_THREADS]; apr_status_t r2[NUM_THREADS]; + apr_status_t r3[NUM_THREADS]; apr_status_t s1[NUM_THREADS]; apr_status_t s2[NUM_THREADS]; + apr_status_t s3[NUM_THREADS]; apr_status_t rv; int i; - int mutex; - - apr_initialize(); - - if (argc == 2 && argv[1][0] == 'm') { - mutex = 1; - } - else { - mutex = 0; - } - printf("APR Atomic Test\n===============\n\n"); #ifdef HAVE_PTHREAD_SETCONCURRENCY pthread_setconcurrency(8); #endif - printf("%-60s", "Initializing the context"); - if (apr_pool_create(&context, NULL) != APR_SUCCESS) { - fflush(stdout); - fprintf(stderr, "Failed.\nCould not initialize\n"); - exit(-1); - } - printf("OK\n"); - - if (mutex == 1) { - printf("%-60s", "Initializing the lock"); - rv = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_DEFAULT, - context); - if (rv != APR_SUCCESS) { - fflush(stdout); - fprintf(stderr, "Failed\nCould not create lock\n"); - exit(-1); - } - printf("OK\n"); - } - printf("%-60s", "Initializing the atomics"); - rv = apr_atomic_init(context); - if (rv != APR_SUCCESS) { - fprintf(stderr, "Failed.\n"); - exit(-1); - } - printf("OK\n"); - - rv = check_basic_atomics32(); - if (rv != APR_SUCCESS) { - fprintf(stderr, "Failed.\n"); - exit(-1); - } + rv = apr_thread_mutex_create(&thread_lock, APR_THREAD_MUTEX_DEFAULT, p); + apr_assert_success(tc, "Could not create lock", rv); - printf("%-60s", "Starting all the threads"); for (i = 0; i < NUM_THREADS; i++) { - r1[i] = apr_thread_create(&t1[i], NULL, - (mutex == 1 ? thread_func_mutex : thread_func_atomic), - NULL, context); - r2[i] = apr_thread_create(&t2[i], NULL, thread_func_none, NULL, - context); - if (r1[i] != APR_SUCCESS || r2[i] != APR_SUCCESS ) { - fflush(stdout); - fprintf(stderr, "Failed\nError starting thread in group %d\n",i); - exit(-1); - } + r1[i] = apr_thread_create(&t1[i], NULL, thread_func_mutex, NULL, p); + r2[i] = apr_thread_create(&t2[i], NULL, thread_func_atomic, NULL, p); + r3[i] = apr_thread_create(&t3[i], NULL, thread_func_none, NULL, p); + CuAssert(tc, "Failed creating threads", + r1[i] == APR_SUCCESS && r2[i] == APR_SUCCESS && + r3[i] == APR_SUCCESS); } - printf("OK\n"); - - printf("%-60s\n", "Waiting for threads to exit"); - printf("%-60s", "(Note that this may take a while to complete.)"); - fflush(stdout); for (i = 0; i < NUM_THREADS; i++) { apr_thread_join(&s1[i], t1[i]); apr_thread_join(&s2[i], t2[i]); - if (s1[i] != exit_ret_val || s2[i] != exit_ret_val) { - fprintf(stderr, - "Invalid return value\n" - "Got %d/%d, but expected %d for all \n", - s1[i], s2[i], exit_ret_val); - } - } - printf("OK\n"); - - if (mutex == 1) { - printf("%-60s", "Checking if mutex locks worked"); - if (x != NUM_THREADS * NUM_ITERATIONS) { - fflush(stdout); - fprintf(stderr, - "No!\nThe locks didn't work?? x = %ld instead of %ld\n", - x, - (long)NUM_THREADS * NUM_ITERATIONS); - } - else { - printf("OK\n"); - } - } - else { - printf("%-60s", "Checking if atomic worked"); - if (apr_atomic_read32(&y) != NUM_THREADS * NUM_ITERATIONS) { - fflush(stdout); - fprintf(stderr, - "No!\nThe atomics didn't work?? y = %ld instead of %ld\n", - (long)apr_atomic_read32(&y), - (long)NUM_THREADS * NUM_ITERATIONS); - } - else { - printf("OK\n"); - } - } - printf("%-60s", "Checking if nolock worked"); - if (z != NUM_THREADS * NUM_ITERATIONS) { - fflush(stdout); - fprintf(stderr, - "no surprise\n" - "The no-locks didn't work. z = %ld instead of %ld\n", - z, - (long)NUM_THREADS * NUM_ITERATIONS); - } - else { - printf("OK\n"); - } - - return 0; + apr_thread_join(&s3[i], t3[i]); + CuAssert(tc, "Invalid return value from thread_join", + s1[i] == exit_ret_val && s2[i] == exit_ret_val && + s3[i] == exit_ret_val); + } + + CuAssertIntEquals(tc, x, NUM_THREADS * NUM_ITERATIONS); + CuAssertIntEquals(tc, apr_atomic_read32(&y), NUM_THREADS * NUM_ITERATIONS); + /* Comment out this test, because I have no clue what this test is + * actually telling us. We are checking something that may or may not + * be true, and it isn't really testing APR at all. + CuAssert(tc, "We expect this to fail, because we tried to update " + "an integer in a non-thread-safe manner.", + z != NUM_THREADS * NUM_ITERATIONS); + */ } #endif /* !APR_HAS_THREADS */ + +CuSuite *testatomic(void) +{ + CuSuite *suite = CuSuiteNew("Atomic"); + + SUITE_ADD_TEST(suite, test_init); + SUITE_ADD_TEST(suite, test_set32); + SUITE_ADD_TEST(suite, test_read32); + SUITE_ADD_TEST(suite, test_dec32); + SUITE_ADD_TEST(suite, test_xchg32); + SUITE_ADD_TEST(suite, test_cas_equal); + SUITE_ADD_TEST(suite, test_cas_equal_nonnull); + SUITE_ADD_TEST(suite, test_cas_notequal); + SUITE_ADD_TEST(suite, test_add32); + SUITE_ADD_TEST(suite, test_inc32); + SUITE_ADD_TEST(suite, test_set_add_inc_sub); + SUITE_ADD_TEST(suite, test_wrap_zero); + SUITE_ADD_TEST(suite, test_inc_neg1); + +#if APR_HAS_THREADS + SUITE_ADD_TEST(suite, test_atomics_threaded); +#endif + + return suite; +} + |