diff options
author | Craig Tiller <ctiller@google.com> | 2017-03-13 06:57:29 -0700 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2017-03-13 06:57:29 -0700 |
commit | 0dd81003b5a9601d4bc79afdd269a7e93b53c5a9 (patch) | |
tree | aeee273940b299fb0a59d72d2e236c8dcfb5e887 | |
parent | 9202b3fdfdaf890752d7472692296490ec55c750 (diff) |
Concurrent test
-rw-r--r-- | src/core/lib/support/arena.c | 5 | ||||
-rw-r--r-- | test/core/support/arena_test.c | 43 |
2 files changed, 48 insertions, 0 deletions
diff --git a/src/core/lib/support/arena.c b/src/core/lib/support/arena.c index a5b0be4d48..faceb1a1eb 100644 --- a/src/core/lib/support/arena.c +++ b/src/core/lib/support/arena.c @@ -36,6 +36,9 @@ #include <grpc/support/atm.h> #include <grpc/support/useful.h> +#define ROUND_UP_TO_ALIGNMENT_SIZE(x) \ + (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u)) + typedef struct zone { size_t size_begin; size_t size_end; @@ -48,6 +51,7 @@ struct gpr_arena { }; gpr_arena *gpr_arena_create(size_t initial_size) { + initial_size = ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); gpr_arena *a = gpr_zalloc(sizeof(gpr_arena) + initial_size); a->initial_zone.size_end = initial_size; return a; @@ -66,6 +70,7 @@ size_t gpr_arena_destroy(gpr_arena *arena) { } void *gpr_arena_alloc(gpr_arena *arena, size_t size) { + size = ROUND_UP_TO_ALIGNMENT_SIZE(size); size_t start = (size_t)gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size); zone *z = &arena->initial_zone; diff --git a/test/core/support/arena_test.c b/test/core/support/arena_test.c index bbf6d48db3..3e21867bcf 100644 --- a/test/core/support/arena_test.c +++ b/test/core/support/arena_test.c @@ -36,8 +36,11 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> #include <grpc/support/useful.h> #include <inttypes.h> +#include <string.h> #include "src/core/lib/support/string.h" #include "test/core/util/test_config.h" @@ -65,9 +68,12 @@ static void test(const char *name, size_t init_size, const size_t *allocs, void **ps = gpr_zalloc(sizeof(*ps) * nallocs); for (size_t i = 0; i < nallocs; i++) { ps[i] = gpr_arena_alloc(a, allocs[i]); + // ensure no duplicate results for (size_t j = 0; j < i; j++) { GPR_ASSERT(ps[i] != ps[j]); } + // ensure writable + memset(ps[i], 1, allocs[i]); } gpr_arena_destroy(a); } @@ -76,6 +82,42 @@ static void test(const char *name, size_t init_size, const size_t *allocs, static const size_t allocs_##name[] = {__VA_ARGS__}; \ test(#name, init_size, allocs_##name, GPR_ARRAY_SIZE(allocs_##name)) +#define CONCURRENT_TEST_ITERATIONS 100000 +#define CONCURRENT_TEST_THREADS 100 + +typedef struct { + gpr_event ev_start; + gpr_arena *arena; +} concurrent_test_args; + +static void concurrent_test_body(void *arg) { + concurrent_test_args *a = arg; + gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME)); + for (size_t i = 0; i < CONCURRENT_TEST_ITERATIONS; i++) { + *(char *)gpr_arena_alloc(a->arena, 1) = (char)i; + } +} + +static void concurrent_test(void) { + concurrent_test_args args; + gpr_event_init(&args.ev_start); + args.arena = gpr_arena_create(1024); + + gpr_thd_id thds[CONCURRENT_TEST_THREADS]; + + for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) { + gpr_thd_options opt = gpr_thd_options_default(); + gpr_thd_options_is_joinable(&opt); + gpr_thd_new(&thds[i], concurrent_test_body, &args, &opt); + } + + gpr_event_set(&args.ev_start, (void *)1); + + for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) { + gpr_thd_join(thds[i]); + } +} + int main(int argc, char *argv[]) { grpc_test_init(argc, argv); @@ -86,6 +128,7 @@ int main(int argc, char *argv[]) { TEST(1_3, 1, 3); TEST(1_inc, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); TEST(6_123, 6, 1, 2, 3); + concurrent_test(); return 0; } |