/* * 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. */
#ifdefined(GC_PTHREADS) || defined(LINT2) # define NOT_GCBUILD # include "private/gc_priv.h"
GC_ATTR_NO_SANITIZE_THREAD staticint GC_rand(void) /* nearly identical to GC_random */
{ staticunsigned seed; /* concurrent update does not hurt the test */
/* Redefine the standard rand() with a trivial (yet sufficient for */ /* the test purpose) implementation to avoid crashes inside rand() */ /* on some targets (e.g. FreeBSD 13.0) when used concurrently. */ /* The standard specifies rand() as not a thread-safe API function. */ # undef rand # define rand() GC_rand() #endif/* GC_PTHREADS || LINT2 */
#define my_assert(e) \ if (!(e)) { \
fflush(stdout); \
fprintf(stderr, "Assertion failure, line %d: "#e"\n", __LINE__); \ exit(-1); \
}
int memeq(void *s, int c, size_t len)
{ while (len--) { if (*(char *)s != c) return 0;
s = (char *)s + 1;
} return 1;
}
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 data;
}
int main(void)
{ # if NTHREADS > 1
pthread_t th[NTHREADS]; int i, n; # endif
GC_set_all_interior_pointers(0); /* for a stricter test */ # ifdef TEST_MANUAL_VDB
GC_set_manual_vdb_allowed(1); # endif
GC_INIT();
GC_init_finalized_malloc(); # ifndef NO_INCREMENTAL
GC_enable_incremental(); # endif if (GC_get_find_leak())
printf("This test program is not designed for leak detection mode\n");
test_misc_sizes();
# if NTHREADS > 1
printf("Threaded disclaim test.\n"); for (i = 0; i < NTHREADS; ++i) { int err = pthread_create(&th[i], NULL, test, NULL); if (err) {
fprintf(stderr, "Failed to create thread #%d: %s\n", i,
strerror(err)); if (i > 1 && EAGAIN == err) break; exit(1);
}
}
n = i; for (i = 0; i < n; ++i) { int err = 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;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.