diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2011-09-23 14:47:59 +0400 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-09-23 14:47:59 +0400 |
commit | 33d8645dc6a2c1c130f0c334e2d51c3f8c5b0de8 (patch) | |
tree | 585dcd2dc4d9f06bf1b8f446a28e46b7c0f48c9a /tests | |
parent | 2aa783260816855e59fe3244658e7c2b2e2cea6e (diff) | |
parent | 831e2f2123539ce464a1a8b4c328c9275db2b6da (diff) | |
download | bdwgc-33d8645dc6a2c1c130f0c334e2d51c3f8c5b0de8.tar.gz |
Merge remote-tracking branch 'remotes/paurkedal/t/disclaim-pullreq' into paurkedal-disclaim-v2
Diffstat (limited to 'tests')
-rw-r--r-- | tests/disclaim_bench.c | 130 | ||||
-rw-r--r-- | tests/disclaim_test.c | 166 | ||||
-rw-r--r-- | tests/tests.am | 11 |
3 files changed, 307 insertions, 0 deletions
diff --git a/tests/disclaim_bench.c b/tests/disclaim_bench.c new file mode 100644 index 00000000..2bdcaac8 --- /dev/null +++ b/tests/disclaim_bench.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2011 by Hewlett-Packard Company. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <time.h> // FIXME: It would be good not to use timing API by + // default (is it is not quite portable). + +#include "atomic_ops.h" +#include "gc_disclaim.h" + +static AO_t free_count = 0; + +typedef struct testobj_s *testobj_t; +struct testobj_s { + testobj_t keep_link; + int i; +}; + +void testobj_finalize(void *obj, void *carg) +{ + AO_fetch_and_add1((AO_t *)carg); + assert(((testobj_t)obj)->i++ == 109); +} + +static struct GC_finalizer_closure fclos = { + testobj_finalize, + &free_count +}; + +testobj_t testobj_new(int model) +{ + testobj_t obj; + switch (model) { + case 0: + obj = GC_MALLOC(sizeof(struct testobj_s)); + GC_register_finalizer_no_order(obj, testobj_finalize, &free_count, + NULL, NULL); + break; + case 1: + obj = GC_finalized_malloc(sizeof(struct testobj_s), &fclos); + break; + case 2: + obj = GC_MALLOC(sizeof(struct testobj_s)); + break; + default: + exit(-1); + } + assert(obj->i == 0 && obj->keep_link == NULL); + obj->i = 109; + return obj; +} + +#define ALLOC_CNT (4*1024*1024) +#define KEEP_CNT (32*1024) + +static char const *model_str[3] = { + "regular finalization", + "finalize on reclaim", + "no finalization" +}; + +int main(int argc, char **argv) +{ + int i; + int model; + testobj_t *keep_arr; + double t; + + GC_INIT(); + GC_init_finalized_malloc(); + + keep_arr = GC_MALLOC(sizeof(void *)*KEEP_CNT); + + if (argc == 1) { + char *buf = GC_MALLOC(strlen(argv[0]) + 3); + printf("\t\t\tfin. ratio time/s time/fin.\n"); + fflush(stdout); + for (i = 0; i < 3; ++i) { + int st; + sprintf(buf, "%s %d", argv[0], i); + st = system(buf); // FIXME: is this available on all targets? + if (st != 0) + return st; + } + return 0; + } + if (argc == 2 && strcmp(argv[1], "--help") == 0) { + fprintf(stderr, + "Usage: %s FINALIZATION_MODEL\n" + "\t0 -- original finalization\n" + "\t1 -- finalization on reclaim\n" + "\t2 -- no finalization\n", argv[0]); + return 1; + } + model = atoi(argv[1]); + if (model < 0 || model > 2) + exit(2); + t = -(double)clock(); + for (i = 0; i < ALLOC_CNT; ++i) { + int k = rand() % KEEP_CNT; + keep_arr[k] = testobj_new(model); + } + + GC_gcollect(); + + t += clock(); + t /= CLOCKS_PER_SEC; + if (model < 2) + printf("%20s: %12.4lf %12lg %12lg\n", model_str[model], + free_count/(double)ALLOC_CNT, t, t/free_count); + else + printf("%20s: %12.4lf %12lg %12s\n", + model_str[model], 0.0, t, "N/A"); + return 0; +} diff --git a/tests/disclaim_test.c b/tests/disclaim_test.c new file mode 100644 index 00000000..4bd4a1d2 --- /dev/null +++ b/tests/disclaim_test.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2011 by Hewlett-Packard Company. All rights reserved. + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ + +/* Test that objects reachable from an object allocated with */ +/* GC_malloc_with_finalizer is not reclaimable before the finalizer */ +/* is called. */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "gc_disclaim.h" + +typedef struct pair_s *pair_t; + +struct pair_s { + int is_valid; + int checksum; + pair_t car; + pair_t cdr; +}; + +void pair_dct(void *obj, void *cd) +{ + pair_t p = obj; + int checksum; + + /* Check that obj and its car and cdr are not trashed. */ +# ifdef DEBUG_DISCLAIM_DESTRUCT + printf("Destruct %p = (%p, %p)\n", p, p->car, p->cdr); +# endif + assert(GC_base(obj)); + assert(p->is_valid); + assert(!p->car || p->car->is_valid); + assert(!p->cdr || p->cdr->is_valid); + checksum = 782; + if (p->car) checksum += p->car->checksum; + if (p->cdr) checksum += p->cdr->checksum; + assert(p->checksum == checksum); + + /* Invalidate it. */ + p->is_valid = 0; + p->checksum = 0; + p->car = NULL; + p->cdr = NULL; +} + +pair_t +pair_new(pair_t car, pair_t cdr) +{ + pair_t p; + static struct GC_finalizer_closure fc = { pair_dct, NULL }; + + p = GC_finalized_malloc(sizeof(struct pair_s), &fc); + p->is_valid = 1; + p->checksum = 782 + (car? car->checksum : 0) + (cdr? cdr->checksum : 0); + p->car = car; + p->cdr = cdr; +# ifdef DEBUG_DISCLAIM_DESTRUCT + printf("Construct %p = (%p, %p)\n", p, p->car, p->cdr); +# endif + return p; +} + +void +pair_check_rec(pair_t p) +{ + while (p) { + int checksum = 782; + if (p->car) checksum += p->car->checksum; + if (p->cdr) checksum += p->cdr->checksum; + assert(p->checksum == checksum); + if (rand() % 2) + p = p->car; + else + p = p->cdr; + } +} + +#ifdef GC_PTHREADS +# define THREAD_CNT 6 +#else +# define THREAD_CNT 1 +#endif + +#define POP_SIZE 1000 +#if THREAD_CNT > 1 +# define MUTATE_CNT 2000000/THREAD_CNT +#else +# define MUTATE_CNT 10000000 +#endif +#define GROW_LIMIT 10000000 + +void *test(void *data) +{ + int i; + pair_t pop[POP_SIZE]; + memset(pop, 0, sizeof(pop)); + for (i = 0; i < MUTATE_CNT; ++i) { + int t = rand() % POP_SIZE; + switch (rand() % (i > GROW_LIMIT? 5 : 3)) { + case 0: case 3: + if (pop[t]) + pop[t] = pop[t]->car; + break; + case 1: case 4: + if (pop[t]) + pop[t] = pop[t]->cdr; + break; + case 2: + pop[t] = pair_new(pop[rand() % POP_SIZE], + pop[rand() % POP_SIZE]); + break; + } + if (rand() % 8 == 1) + pair_check_rec(pop[rand() % POP_SIZE]); + } + return 0; +} + +int main(void) +{ +#if THREAD_CNT > 1 + pthread_t th[THREAD_CNT]; + int i; +#endif + + GC_INIT(); + GC_init_finalized_malloc(); + +#if THREAD_CNT > 1 + printf("Threaded disclaim test.\n"); + for (i = 0; i < THREAD_CNT; ++i) { + int err = GC_pthread_create(&th[i], NULL, test, NULL); + if (err) { + fprintf(stderr, "Failed to create thread # %d: %s\n", i, + strerror(err)); + exit(1); + } + } + for (i = 0; i < THREAD_CNT; ++i) { + int err = GC_pthread_join(th[i], NULL); + if (err) { + fprintf(stderr, "Failed to join thread # %d: %s\n", i, + strerror(err)); + exit(69); + } + } +#else + printf("Unthreaded disclaim test.\n"); + test(NULL); +#endif + return 0; +} diff --git a/tests/tests.am b/tests/tests.am index 13647b3a..9685ae67 100644 --- a/tests/tests.am +++ b/tests/tests.am @@ -91,3 +91,14 @@ else test_cpp_LDADD = libgccpp.la $(test_ldadd) endif endif + +if ENABLE_DISCLAIM +TESTS += disclaim_test +check_PROGRAMS += disclaim_test +disclaim_test_SOURCES = tests/disclaim_test.c +disclaim_test_LDADD = $(test_ldadd) +TESTS += disclaim_bench +check_PROGRAMS += disclaim_bench +disclaim_bench_SOURCES = tests/disclaim_bench.c +disclaim_bench_LDADD = $(test_ldadd) +endif |