summaryrefslogtreecommitdiff
path: root/test/testatomic.c
diff options
context:
space:
mode:
authorRyan Bloom <rbb@apache.org>2004-03-13 00:28:45 +0000
committerRyan Bloom <rbb@apache.org>2004-03-13 00:28:45 +0000
commit9088f678ac1ef2bffae465d5e0e788b20f3d8826 (patch)
tree92e309628db9b3723330f6d2a2450a290dcbda8b /test/testatomic.c
parentae9e0f4df0da4c0276c967baafc598f8be346eb9 (diff)
downloadapr-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.c426
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;
+}
+