diff --git a/Makefile.in b/Makefile.in index 78554433..cd137fd9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -103,10 +103,12 @@ DOCS_XML := $(objroot)doc/jemalloc$(install_suffix).xml DOCS_HTML := $(DOCS_XML:$(objroot)%.xml=$(srcroot)%.html) DOCS_MAN3 := $(DOCS_XML:$(objroot)%.xml=$(srcroot)%.3) DOCS := $(DOCS_HTML) $(DOCS_MAN3) -C_TESTLIB_SRCS := $(srcroot)test/src/math.c $(srcroot)test/src/SFMT.c \ - $(srcroot)test/src/test.c $(srcroot)test/src/thread.c +C_TESTLIB_SRCS := $(srcroot)test/src/math.c $(srcroot)test/src/mtx.c \ + $(srcroot)test/src/SFMT.c $(srcroot)test/src/test.c \ + $(srcroot)test/src/thd.c C_UTIL_INTEGRATION_SRCS := $(srcroot)src/util.c TESTS_UNIT := $(srcroot)test/unit/bitmap.c $(srcroot)test/unit/math.c \ + $(srcroot)test/unit/mq.c $(srcroot)test/unit/mtx.c \ $(srcroot)test/unit/SFMT.c $(srcroot)test/unit/tsd.c TESTS_INTEGRATION := $(srcroot)test/integration/aligned_alloc.c \ $(srcroot)test/integration/allocated.c \ diff --git a/include/jemalloc/internal/hash.h b/include/jemalloc/internal/hash.h index 56ecc793..6b8d9cd5 100644 --- a/include/jemalloc/internal/hash.h +++ b/include/jemalloc/internal/hash.h @@ -43,14 +43,14 @@ JEMALLOC_INLINE uint32_t hash_get_block_32(const uint32_t *p, int i) { - return p[i]; + return (p[i]); } JEMALLOC_INLINE uint64_t hash_get_block_64(const uint64_t *p, int i) { - return p[i]; + return (p[i]); } JEMALLOC_INLINE uint32_t @@ -63,7 +63,7 @@ hash_fmix_32(uint32_t h) h *= 0xc2b2ae35; h ^= h >> 16; - return h; + return (h); } JEMALLOC_INLINE uint64_t @@ -76,7 +76,7 @@ hash_fmix_64(uint64_t k) k *= QU(0xc4ceb9fe1a85ec53LLU); k ^= k >> 33; - return k; + return (k); } JEMALLOC_INLINE uint32_t @@ -127,7 +127,7 @@ hash_x86_32(const void *key, int len, uint32_t seed) h1 = hash_fmix_32(h1); - return h1; + return (h1); } UNUSED JEMALLOC_INLINE void diff --git a/include/jemalloc/internal/jemalloc_internal_defs.h.in b/include/jemalloc/internal/jemalloc_internal_defs.h.in index 3b72b35f..752bb103 100644 --- a/include/jemalloc/internal/jemalloc_internal_defs.h.in +++ b/include/jemalloc/internal/jemalloc_internal_defs.h.in @@ -1,3 +1,5 @@ +#ifndef JEMALLOC_INTERNAL_DEFS_H_ +#define JEMALLOC_INTERNAL_DEFS_H_ /* * If JEMALLOC_PREFIX is defined via --with-jemalloc-prefix, it will cause all * public APIs to be prefixed. This makes it possible, with some care, to use @@ -193,3 +195,5 @@ /* sizeof(intmax_t) == 2^LG_SIZEOF_INTMAX_T. */ #undef LG_SIZEOF_INTMAX_T + +#endif /* JEMALLOC_INTERNAL_DEFS_H_ */ diff --git a/include/jemalloc/internal/tsd.h b/include/jemalloc/internal/tsd.h index 5f7ad1c5..9fb4a23e 100644 --- a/include/jemalloc/internal/tsd.h +++ b/include/jemalloc/internal/tsd.h @@ -348,7 +348,7 @@ a_name##_tsd_get_wrapper(void) \ wrapper = tsd_init_check_recursion( \ &a_name##_tsd_init_head, &block); \ if (wrapper) \ - return wrapper; \ + return (wrapper); \ wrapper = (a_name##_tsd_wrapper_t *) \ malloc_tsd_malloc(sizeof(a_name##_tsd_wrapper_t)); \ block.data = wrapper; \ diff --git a/test/include/test/jemalloc_test.h.in b/test/include/test/jemalloc_test.h.in index 9743cd52..9f7dfa46 100644 --- a/test/include/test/jemalloc_test.h.in +++ b/test/include/test/jemalloc_test.h.in @@ -1,8 +1,10 @@ #include +#include #include -#include +#include #include #include +#include #ifdef _WIN32 # include @@ -45,6 +47,10 @@ #include "test/jemalloc_test_defs.h" +#ifdef JEMALLOC_OSSPIN +# include +#endif + #if defined(HAVE_ALTIVEC) && !defined(__APPLE__) # include #endif @@ -75,13 +81,13 @@ # define JEMALLOC_N(n) @private_namespace@##n # include "jemalloc/internal/private_namespace.h" -# include -# include # define JEMALLOC_H_TYPES # define JEMALLOC_H_STRUCTS # define JEMALLOC_H_EXTERNS # define JEMALLOC_H_INLINES # include "jemalloc/internal/util.h" +# include "jemalloc/internal/qr.h" +# include "jemalloc/internal/ql.h" # undef JEMALLOC_H_TYPES # undef JEMALLOC_H_STRUCTS # undef JEMALLOC_H_EXTERNS @@ -124,7 +130,9 @@ * Common test utilities. */ #include "test/math.h" +#include "test/mtx.h" +#include "test/mq.h" #include "test/test.h" -#include "test/thread.h" +#include "test/thd.h" #define MEXP 19937 #include "test/SFMT.h" diff --git a/test/include/test/jemalloc_test_defs.h.in b/test/include/test/jemalloc_test_defs.h.in index 093e2f23..18a9773d 100644 --- a/test/include/test/jemalloc_test_defs.h.in +++ b/test/include/test/jemalloc_test_defs.h.in @@ -1,3 +1,5 @@ +#include "jemalloc/internal/jemalloc_internal_defs.h" + /* For use by SFMT. */ #undef HAVE_SSE2 #undef HAVE_ALTIVEC diff --git a/test/include/test/mq.h b/test/include/test/mq.h new file mode 100644 index 00000000..11188653 --- /dev/null +++ b/test/include/test/mq.h @@ -0,0 +1,110 @@ +/* + * Simple templated message queue implementation that relies on only mutexes for + * synchronization (which reduces portability issues). Given the following + * setup: + * + * typedef struct mq_msg_s mq_msg_t; + * struct mq_msg_s { + * mq_msg(mq_msg_t) link; + * [message data] + * }; + * mq_gen(, mq_, mq_t, mq_msg_t, link) + * + * The API is as follows: + * + * bool mq_init(mq_t *mq); + * void mq_fini(mq_t *mq); + * unsigned mq_count(mq_t *mq); + * mq_msg_t *mq_tryget(mq_t *mq); + * mq_msg_t *mq_get(mq_t *mq); + * void mq_put(mq_t *mq, mq_msg_t *msg); + * + * The message queue linkage embedded in each message is to be treated as + * externally opaque (no need to initialize or clean up externally). mq_fini() + * does not perform any cleanup of messages, since it knows nothing of their + * payloads. + */ +#define mq_msg(a_mq_msg_type) ql_elm(a_mq_msg_type) + +#define mq_gen(a_attr, a_prefix, a_mq_type, a_mq_msg_type, a_field) \ +typedef struct { \ + mtx_t lock; \ + ql_head(a_mq_msg_type) msgs; \ + unsigned count; \ +} a_mq_type; \ +a_attr bool \ +a_prefix##init(a_mq_type *mq) { \ + \ + if (mtx_init(&mq->lock)) \ + return (true); \ + ql_new(&mq->msgs); \ + mq->count = 0; \ + return (false); \ +} \ +a_attr void \ +a_prefix##fini(a_mq_type *mq) \ +{ \ + \ + mtx_fini(&mq->lock); \ +} \ +a_attr unsigned \ +a_prefix##count(a_mq_type *mq) \ +{ \ + unsigned count; \ + \ + mtx_lock(&mq->lock); \ + count = mq->count; \ + mtx_unlock(&mq->lock); \ + return (count); \ +} \ +a_attr a_mq_msg_type * \ +a_prefix##tryget(a_mq_type *mq) \ +{ \ + a_mq_msg_type *msg; \ + \ + mtx_lock(&mq->lock); \ + msg = ql_first(&mq->msgs); \ + if (msg != NULL) { \ + ql_head_remove(&mq->msgs, a_mq_msg_type, a_field); \ + mq->count--; \ + } \ + mtx_unlock(&mq->lock); \ + return (msg); \ +} \ +a_attr a_mq_msg_type * \ +a_prefix##get(a_mq_type *mq) \ +{ \ + a_mq_msg_type *msg; \ + struct timespec timeout; \ + \ + msg = a_prefix##tryget(mq); \ + if (msg != NULL) \ + return (msg); \ + \ + timeout.tv_sec = 0; \ + timeout.tv_nsec = 1; \ + while (true) { \ + nanosleep(&timeout, NULL); \ + msg = a_prefix##tryget(mq); \ + if (msg != NULL) \ + return (msg); \ + if (timeout.tv_sec == 0) { \ + /* Double sleep time, up to max 1 second. */ \ + timeout.tv_nsec <<= 1; \ + if (timeout.tv_nsec >= 1000*1000*1000) { \ + timeout.tv_sec = 1; \ + timeout.tv_nsec = 0; \ + } \ + } \ + } \ +} \ +a_attr void \ +a_prefix##put(a_mq_type *mq, a_mq_msg_type *msg) \ +{ \ + \ + mtx_lock(&mq->lock); \ + ql_elm_new(msg, a_field); \ + ql_tail_insert(&mq->msgs, msg, a_field); \ + mq->count++; \ + mtx_unlock(&mq->lock); \ +} diff --git a/test/include/test/mtx.h b/test/include/test/mtx.h new file mode 100644 index 00000000..bbe822f5 --- /dev/null +++ b/test/include/test/mtx.h @@ -0,0 +1,21 @@ +/* + * mtx is a slightly simplified version of malloc_mutex. This code duplication + * is unfortunate, but there are allocator bootstrapping considerations that + * would leak into the test infrastructure if malloc_mutex were used directly + * in tests. + */ + +typedef struct { +#ifdef _WIN32 + CRITICAL_SECTION lock; +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLock lock; +#else + pthread_mutex_t lock; +#endif +} mtx_t; + +bool mtx_init(mtx_t *mtx); +void mtx_fini(mtx_t *mtx); +void mtx_lock(mtx_t *mtx); +void mtx_unlock(mtx_t *mtx); diff --git a/test/include/test/thd.h b/test/include/test/thd.h new file mode 100644 index 00000000..f941d7a7 --- /dev/null +++ b/test/include/test/thd.h @@ -0,0 +1,9 @@ +/* Abstraction layer for threading in tests */ +#ifdef _WIN32 +typedef HANDLE thd_t; +#else +typedef pthread_t thd_t; +#endif + +void thd_create(thd_t *thd, void *(*proc)(void *), void *arg); +void thd_join(thd_t thd, void **ret); diff --git a/test/include/test/thread.h b/test/include/test/thread.h deleted file mode 100644 index 3b02a011..00000000 --- a/test/include/test/thread.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Abstraction layer for threading in tests */ -#ifdef _WIN32 -typedef HANDLE je_thread_t; -#else -typedef pthread_t je_thread_t; -#endif - -void je_thread_create(je_thread_t *thread, void *(*proc)(void *), void *arg); -void je_thread_join(je_thread_t thread, void **ret); diff --git a/test/integration/ALLOCM_ARENA.c b/test/integration/ALLOCM_ARENA.c index ec91c59b..5bf3c4ab 100644 --- a/test/integration/ALLOCM_ARENA.c +++ b/test/integration/ALLOCM_ARENA.c @@ -3,7 +3,7 @@ #define NTHREADS 10 void * -je_thread_start(void *arg) +thd_start(void *arg) { unsigned thread_ind = (unsigned)(uintptr_t)arg; unsigned arena_ind; @@ -36,16 +36,16 @@ je_thread_start(void *arg) TEST_BEGIN(test_ALLOCM_ARENA) { - je_thread_t threads[NTHREADS]; + thd_t thds[NTHREADS]; unsigned i; for (i = 0; i < NTHREADS; i++) { - je_thread_create(&threads[i], je_thread_start, + thd_create(&thds[i], thd_start, (void *)(uintptr_t)i); } for (i = 0; i < NTHREADS; i++) - je_thread_join(threads[i], NULL); + thd_join(thds[i], NULL); } TEST_END diff --git a/test/integration/allocated.c b/test/integration/allocated.c index 156451dc..3630e80c 100644 --- a/test/integration/allocated.c +++ b/test/integration/allocated.c @@ -9,7 +9,7 @@ static const bool config_stats = ; void * -je_thread_start(void *arg) +thd_start(void *arg) { int err; void *p; @@ -98,16 +98,16 @@ label_ENOENT: TEST_BEGIN(test_main_thread) { - je_thread_start(NULL); + thd_start(NULL); } TEST_END TEST_BEGIN(test_subthread) { - je_thread_t thread; + thd_t thd; - je_thread_create(&thread, je_thread_start, NULL); - je_thread_join(thread, NULL); + thd_create(&thd, thd_start, NULL); + thd_join(thd, NULL); } TEST_END diff --git a/test/integration/jemalloc_integration.h.in b/test/integration/jemalloc_integration.h.in deleted file mode 100644 index 4730aab1..00000000 --- a/test/integration/jemalloc_integration.h.in +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This header should be included by tests, rather than directly including - * jemalloc/jemalloc.h, because --with-install-suffix may cause the header to - * have a different name. - */ -#include "jemalloc/jemalloc@install_suffix@.h" -#include "jemalloc/internal/jemalloc_internal.h" - -/* Abstraction layer for threading in tests. */ -#ifdef _WIN32 -#include - -typedef HANDLE je_thread_t; - -void -je_thread_create(je_thread_t *thread, void *(*proc)(void *), void *arg) -{ - LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; - *thread = CreateThread(NULL, 0, routine, arg, 0, NULL); - if (*thread == NULL) - test_fail("Error in CreateThread()\n"); -} - -void -je_thread_join(je_thread_t thread, void **ret) -{ - - WaitForSingleObject(thread, INFINITE); -} - -#else -#include - -typedef pthread_t je_thread_t; - -void -je_thread_create(je_thread_t *thread, void *(*proc)(void *), void *arg) -{ - - if (pthread_create(thread, NULL, proc, arg) != 0) - test_fail("Error in pthread_create()\n"); -} - -void -je_thread_join(je_thread_t thread, void **ret) -{ - - pthread_join(thread, ret); -} -#endif diff --git a/test/integration/thread_arena.c b/test/integration/thread_arena.c index cf0aad73..67be5351 100644 --- a/test/integration/thread_arena.c +++ b/test/integration/thread_arena.c @@ -3,7 +3,7 @@ #define NTHREADS 10 void * -je_thread_start(void *arg) +thd_start(void *arg) { unsigned main_arena_ind = *(unsigned *)arg; void *p; @@ -43,7 +43,7 @@ TEST_BEGIN(test_thread_arena) unsigned arena_ind; size_t size; int err; - je_thread_t threads[NTHREADS]; + thd_t thds[NTHREADS]; unsigned i; p = malloc(1); @@ -58,13 +58,13 @@ TEST_BEGIN(test_thread_arena) } for (i = 0; i < NTHREADS; i++) { - je_thread_create(&threads[i], je_thread_start, + thd_create(&thds[i], thd_start, (void *)&arena_ind); } for (i = 0; i < NTHREADS; i++) { intptr_t join_ret; - je_thread_join(threads[i], (void *)&join_ret); + thd_join(thds[i], (void *)&join_ret); assert_zd_eq(join_ret, 0, "Unexpected thread join error"); } } diff --git a/test/integration/thread_tcache_enabled.c b/test/integration/thread_tcache_enabled.c index 52e8a11c..f4e89c68 100644 --- a/test/integration/thread_tcache_enabled.c +++ b/test/integration/thread_tcache_enabled.c @@ -9,7 +9,7 @@ static const bool config_tcache = ; void * -je_thread_start(void *arg) +thd_start(void *arg) { int err; size_t sz; @@ -86,16 +86,16 @@ label_ENOENT: TEST_BEGIN(test_main_thread) { - je_thread_start(NULL); + thd_start(NULL); } TEST_END TEST_BEGIN(test_subthread) { - je_thread_t thread; + thd_t thd; - je_thread_create(&thread, je_thread_start, NULL); - je_thread_join(thread, NULL); + thd_create(&thd, thd_start, NULL); + thd_join(thd, NULL); } TEST_END diff --git a/test/src/mtx.c b/test/src/mtx.c new file mode 100644 index 00000000..8d9e0ca1 --- /dev/null +++ b/test/src/mtx.c @@ -0,0 +1,62 @@ +#include "test/jemalloc_test.h" + +bool +mtx_init(mtx_t *mtx) +{ + +#ifdef _WIN32 + if (!InitializeCriticalSectionAndSpinCount(&mtx->lock, _CRT_SPINCOUNT)) + return (true); +#elif (defined(JEMALLOC_OSSPIN)) + mtx->lock = 0; +#else + pthread_mutexattr_t attr; + + if (pthread_mutexattr_init(&attr) != 0) + return (true); + pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE); + if (pthread_mutex_init(&mtx->lock, &attr) != 0) { + pthread_mutexattr_destroy(&attr); + return (true); + } + pthread_mutexattr_destroy(&attr); +#endif + return (false); +} + +void +mtx_fini(mtx_t *mtx) +{ + +#ifdef _WIN32 +#elif (defined(JEMALLOC_OSSPIN)) +#else + pthread_mutex_destroy(&mtx->lock); +#endif +} + +void +mtx_lock(mtx_t *mtx) +{ + +#ifdef _WIN32 + EnterCriticalSection(&mtx->lock); +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockLock(&mtx->lock); +#else + pthread_mutex_lock(&mtx->lock); +#endif +} + +void +mtx_unlock(mtx_t *mtx) +{ + +#ifdef _WIN32 + LeaveCriticalSection(&mtx->lock); +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockUnlock(&mtx->lock); +#else + pthread_mutex_unlock(&mtx->lock); +#endif +} diff --git a/test/src/thd.c b/test/src/thd.c new file mode 100644 index 00000000..233242a1 --- /dev/null +++ b/test/src/thd.c @@ -0,0 +1,35 @@ +#include "test/jemalloc_test.h" + +#ifdef _WIN32 +void +thd_create(thd_t *thd, void *(*proc)(void *), void *arg) +{ + LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; + *thd = CreateThread(NULL, 0, routine, arg, 0, NULL); + if (*thd == NULL) + test_fail("Error in CreateThread()\n"); +} + +void +thd_join(thd_t thd, void **ret) +{ + + WaitForSingleObject(thd, INFINITE); +} + +#else +void +thd_create(thd_t *thd, void *(*proc)(void *), void *arg) +{ + + if (pthread_create(thd, NULL, proc, arg) != 0) + test_fail("Error in pthread_create()\n"); +} + +void +thd_join(thd_t thd, void **ret) +{ + + pthread_join(thd, ret); +} +#endif diff --git a/test/src/thread.c b/test/src/thread.c deleted file mode 100644 index 5a91e27e..00000000 --- a/test/src/thread.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "test/jemalloc_test.h" - -#ifdef _WIN32 -void -je_thread_create(je_thread_t *thread, void *(*proc)(void *), void *arg) -{ - LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; - *thread = CreateThread(NULL, 0, routine, arg, 0, NULL); - if (*thread == NULL) - test_fail("Error in CreateThread()\n"); -} - -void -je_thread_join(je_thread_t thread, void **ret) -{ - - WaitForSingleObject(thread, INFINITE); -} - -#else -void -je_thread_create(je_thread_t *thread, void *(*proc)(void *), void *arg) -{ - - if (pthread_create(thread, NULL, proc, arg) != 0) - test_fail("Error in pthread_create()\n"); -} - -void -je_thread_join(je_thread_t thread, void **ret) -{ - - pthread_join(thread, ret); -} -#endif diff --git a/test/unit/mq.c b/test/unit/mq.c new file mode 100644 index 00000000..f0f49905 --- /dev/null +++ b/test/unit/mq.c @@ -0,0 +1,91 @@ +#include "test/jemalloc_test.h" + +#define NSENDERS 3 +#define NMSGS 100000 + +typedef struct mq_msg_s mq_msg_t; +struct mq_msg_s { + mq_msg(mq_msg_t) link; +}; +mq_gen(static, mq_, mq_t, mq_msg_t, link) + +TEST_BEGIN(test_mq_basic) +{ + mq_t mq; + mq_msg_t msg; + + assert_false(mq_init(&mq), "Unexpected mq_init() failure"); + assert_u_eq(mq_count(&mq), 0, "mq should be empty"); + assert_ptr_null(mq_tryget(&mq), + "mq_tryget() should fail when the queue is empty"); + + mq_put(&mq, &msg); + assert_u_eq(mq_count(&mq), 1, "mq should contain one message"); + assert_ptr_eq(mq_tryget(&mq), &msg, "mq_tryget() should return msg"); + + mq_put(&mq, &msg); + assert_ptr_eq(mq_get(&mq), &msg, "mq_get() should return msg"); + + mq_fini(&mq); +} +TEST_END + +static void * +thd_receiver_start(void *arg) +{ + mq_t *mq = (mq_t *)arg; + unsigned i; + + for (i = 0; i < (NSENDERS * NMSGS); i++) { + mq_msg_t *msg = mq_get(mq); + assert_ptr_not_null(msg, "mq_get() should never return NULL"); + assert_d_eq(jet_dallocm(msg, 0), ALLOCM_SUCCESS, + "Unexpected dallocm() failure"); + } + return (NULL); +} + +static void * +thd_sender_start(void *arg) +{ + mq_t *mq = (mq_t *)arg; + unsigned i; + + for (i = 0; i < NMSGS; i++) { + mq_msg_t *msg; + assert_d_eq(jet_allocm((void **)&msg, NULL, sizeof(mq_msg_t), + 0), ALLOCM_SUCCESS, "Unexpected allocm() failure"); + mq_put(mq, msg); + } + return (NULL); +} + +TEST_BEGIN(test_mq_threaded) +{ + mq_t mq; + thd_t receiver; + thd_t senders[NSENDERS]; + unsigned i; + + assert_false(mq_init(&mq), "Unexpected mq_init() failure"); + + thd_create(&receiver, thd_receiver_start, (void *)&mq); + for (i = 0; i < NSENDERS; i++) + thd_create(&senders[i], thd_sender_start, (void *)&mq); + + thd_join(receiver, NULL); + for (i = 0; i < NSENDERS; i++) + thd_join(senders[i], NULL); + + mq_fini(&mq); +} +TEST_END + +int +main(void) +{ + return (test( + test_mq_basic, + test_mq_threaded)); +} + diff --git a/test/unit/mtx.c b/test/unit/mtx.c new file mode 100644 index 00000000..96ff6948 --- /dev/null +++ b/test/unit/mtx.c @@ -0,0 +1,60 @@ +#include "test/jemalloc_test.h" + +#define NTHREADS 2 +#define NINCRS 2000000 + +TEST_BEGIN(test_mtx_basic) +{ + mtx_t mtx; + + assert_false(mtx_init(&mtx), "Unexpected mtx_init() failure"); + mtx_lock(&mtx); + mtx_unlock(&mtx); + mtx_fini(&mtx); +} +TEST_END + +typedef struct { + mtx_t mtx; + unsigned x; +} thd_start_arg_t; + +static void * +thd_start(void *varg) +{ + thd_start_arg_t *arg = (thd_start_arg_t *)varg; + unsigned i; + + for (i = 0; i < NINCRS; i++) { + mtx_lock(&arg->mtx); + arg->x++; + mtx_unlock(&arg->mtx); + } + return (NULL); +} + +TEST_BEGIN(test_mtx_race) +{ + thd_start_arg_t arg; + thd_t thds[NTHREADS]; + unsigned i; + + assert_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure"); + arg.x = 0; + for (i = 0; i < NTHREADS; i++) + thd_create(&thds[i], thd_start, (void *)&arg); + for (i = 0; i < NTHREADS; i++) + thd_join(thds[i], NULL); + assert_u_eq(arg.x, NTHREADS * NINCRS, + "Race-related counter corruption"); +} +TEST_END + +int +main(void) +{ + + return (test( + test_mtx_basic, + test_mtx_race)); +} diff --git a/test/unit/tsd.c b/test/unit/tsd.c index 71feb847..f421c1a3 100644 --- a/test/unit/tsd.c +++ b/test/unit/tsd.c @@ -22,8 +22,8 @@ malloc_tsd_externs(data, data_t) malloc_tsd_data(, data, data_t, DATA_INIT) malloc_tsd_funcs(, data, data_t, DATA_INIT, data_cleanup) -void * -je_thread_start(void *arg) +static void * +thd_start(void *arg) { data_t d = (data_t)(uintptr_t)arg; assert_x_eq(*data_tsd_get(), DATA_INIT, @@ -37,23 +37,23 @@ je_thread_start(void *arg) assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg, "Resetting local data should have no effect on tsd"); - return NULL; + return (NULL); } TEST_BEGIN(test_tsd_main_thread) { - je_thread_start((void *) 0xa5f3e329); + thd_start((void *) 0xa5f3e329); } TEST_END TEST_BEGIN(test_tsd_sub_thread) { - je_thread_t thread; + thd_t thd; data_cleanup_executed = false; - je_thread_create(&thread, je_thread_start, (void *) THREAD_DATA); - je_thread_join(thread, NULL); + thd_create(&thd, thd_start, (void *)THREAD_DATA); + thd_join(thd, NULL); assert_true(data_cleanup_executed, "Cleanup function should have executed"); }