* win32_threads.c (CHECK_LOOKUP_MY_THREAD): New macro definition.
* win32_threads.c (GC_reset_finalizer_nested,
GC_check_finalizer_nested, GC_unregister_my_thread,
GC_do_blocking_inner, GC_call_with_gc_active, GC_init_parallel):
Insert CHECK_LOOKUP_MY_THREAD before dereferencing thread
descriptor pointer (to instruct a LINT-like tool that it is ok to
dereference the pointer).
* win32_threads.c (GC_get_next_stack): Assert plast_stack_min is
non-NULL if current_min is not ADDR_LIMIT (for a LINT-like tool).
* win32_threads.c (GC_init_parallel): Define and use "me" local
variable.
* cord/cordtest.c (test_basics): Test CORD_substr() result is
non-NULL.
* cord/cordtest.c (test_extras): Test fopen() result is non-NULL.
* cord/cordtest.c (test_basics, test_extras, test_printf, main):
Replace the K&R-style function definition with the ANSI C one.
* cord/cordtest.c: Expand all tabs to spaces; remove
trailing spaces at EOLn.
* include/private/gc_priv.h (ABORT): Define as abort() when
checking the code with a LINT-like tool (Win32 only).
* tests/test.c (FAIL): Ditto.
* tests/test.c (CHECH_GCLIB_VERSION): New macro (to check that the
version of libgc.so used at runtime matches that at compile time).
* tests/test.c (GC_COND_INIT): Use CHECH_GCLIB_VERSION.
* tests/test.c (CHECK_OUT_OF_MEMORY): New macro (to test malloc
result for out of memory).
* tests/test.c (cons, small_cons, small_cons_uncollectable,
gcj_cons, reverse_test_inner, mktree, alloc8bytes, typed_test,
run_one_test): Use CHECK_OUT_OF_MEMORY.
+2011-07-01 Ivan Maidanski <ivmai@mail.ru>
+
+ * win32_threads.c (CHECK_LOOKUP_MY_THREAD): New macro definition.
+ * win32_threads.c (GC_reset_finalizer_nested,
+ GC_check_finalizer_nested, GC_unregister_my_thread,
+ GC_do_blocking_inner, GC_call_with_gc_active, GC_init_parallel):
+ Insert CHECK_LOOKUP_MY_THREAD before dereferencing thread
+ descriptor pointer (to instruct a LINT-like tool that it is ok to
+ dereference the pointer).
+ * win32_threads.c (GC_get_next_stack): Assert plast_stack_min is
+ non-NULL if current_min is not ADDR_LIMIT (for a LINT-like tool).
+ * win32_threads.c (GC_init_parallel): Define and use "me" local
+ variable.
+ * cord/cordtest.c (test_basics): Test CORD_substr() result is
+ non-NULL.
+ * cord/cordtest.c (test_extras): Test fopen() result is non-NULL.
+ * cord/cordtest.c (test_basics, test_extras, test_printf, main):
+ Replace the K&R-style function definition with the ANSI C one.
+ * cord/cordtest.c: Expand all tabs to spaces; remove
+ trailing spaces at EOLn.
+ * include/private/gc_priv.h (ABORT): Define as abort() when
+ checking the code with a LINT-like tool (Win32 only).
+ * tests/test.c (FAIL): Ditto.
+ * tests/test.c (CHECH_GCLIB_VERSION): New macro (to check that the
+ version of libgc.so used at runtime matches that at compile time).
+ * tests/test.c (GC_COND_INIT): Use CHECH_GCLIB_VERSION.
+ * tests/test.c (CHECK_OUT_OF_MEMORY): New macro (to test malloc
+ result for out of memory).
+ * tests/test.c (cons, small_cons, small_cons_uncollectable,
+ gcj_cons, reverse_test_inner, mktree, alloc8bytes, typed_test,
+ run_one_test): Use CHECK_OUT_OF_MEMORY.
+
2011-06-30 Ivan Maidanski <ivmai@mail.ru>
* dyn_load.c (GC_register_map_entries): Remove "count" local
-/*
+/*
* Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved.
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
-/* Boehm, August 24, 1994 11:58 am PDT */
-# include "gc.h" /* For GC_INIT() only */
+
+# include "gc.h" /* For GC_INIT() only */
# include "cord.h"
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
-/* This is a very incomplete test of the cord package. It knows about */
-/* a few internals of the package (e.g. when C strings are returned) */
-/* that real clients shouldn't rely on. */
+/* This is a very incomplete test of the cord package. It knows about */
+/* a few internals of the package (e.g. when C strings are returned) */
+/* that real clients shouldn't rely on. */
# define ABORT(string) \
-{ int x = 0; fprintf(stderr, "FAILED: %s\n", string); x = 1 / x; abort(); }
+ { int x = 0; fprintf(stderr, "FAILED: %s\n", string); x = 1 / x; abort(); }
int count;
return((char)i);
}
-void test_basics()
+void test_basics(void)
{
CORD x = CORD_from_char_star("ab");
register int i;
char c;
CORD y;
CORD_pos p;
-
+
x = CORD_cat(x,x);
if (!CORD_IS_STRING(x)) ABORT("short cord should usually be a string");
if (strcmp(x, "abab") != 0) ABORT("bad CORD_cat result");
-
+
for (i = 1; i < 16; i++) {
x = CORD_cat(x,x);
}
x = CORD_cat(x,"c");
if (CORD_len(x) != 128*1024+1) ABORT("bad length");
-
+
count = 0;
if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, (void *)13) == 0) {
ABORT("CORD_iter5 failed");
}
if (count != 64*1024 + 2) ABORT("CORD_iter5 failed");
-
+
count = 0;
CORD_set_pos(p, x, 64*1024-1);
while(CORD_pos_valid(p)) {
- (void) test_fn(CORD_pos_fetch(p), (void *)13);
- CORD_next(p);
+ (void) test_fn(CORD_pos_fetch(p), (void *)13);
+ CORD_next(p);
}
if (count != 64*1024 + 2) ABORT("Position based iteration failed");
-
+
y = CORD_substr(x, 1023, 5);
+ if (!y) ABORT("CORD_substr returned NULL");
if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result");
-
+
y = CORD_substr(x, 1024, 8);
+ if (!y) ABORT("CORD_substr returned NULL");
if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
if (strcmp(y, "abababab") != 0) ABORT("bad CORD_substr result");
-
+
y = CORD_substr(x, 128*1024-1, 8);
+ if (!y) ABORT("CORD_substr returned NULL");
if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
if (strcmp(y, "bc") != 0) ABORT("bad CORD_substr result");
-
+
x = CORD_balance(x);
if (CORD_len(x) != 128*1024+1) ABORT("bad length");
-
+
count = 0;
if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, (void *)13) == 0) {
ABORT("CORD_iter5 failed");
}
if (count != 64*1024 + 2) ABORT("CORD_iter5 failed");
-
+
y = CORD_substr(x, 1023, 5);
+ if (!y) ABORT("CORD_substr returned NULL");
if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result");
y = CORD_from_fn(id_cord_fn, 0, 13);
CORD_set_pos(p, y, i);
while(CORD_pos_valid(p)) {
c = CORD_pos_fetch(p);
- if(c != i) ABORT("Traversal of function node failed");
- CORD_next(p); i++;
+ if(c != i) ABORT("Traversal of function node failed");
+ CORD_next(p); i++;
}
if (i != 13) ABORT("Bad apparent length for function node");
}
-void test_extras()
+void test_extras(void)
{
# if defined(__OS2__) || defined(__DJGPP__)
-# define FNAME1 "tmp1"
-# define FNAME2 "tmp2"
+# define FNAME1 "tmp1"
+# define FNAME2 "tmp2"
# elif defined(AMIGA)
-# define FNAME1 "T:tmp1"
-# define FNAME2 "T:tmp2"
+# define FNAME1 "T:tmp1"
+# define FNAME2 "T:tmp2"
# else
-# define FNAME1 "/tmp/cord_test"
-# define FNAME2 "/tmp/cord_test2"
+# define FNAME1 "/tmp/cord_test"
+# define FNAME2 "/tmp/cord_test2"
# endif
register int i;
CORD y = "abcdefghijklmnopqrstuvwxyz0123456789";
CORD w, z;
FILE *f;
FILE *f1a, *f1b, *f2;
-
+
w = CORD_cat(CORD_cat(y,y),y);
z = CORD_catn(3,y,y,y);
if (CORD_cmp(w,z) != 0) ABORT("CORD_catn comparison wrong");
if ((f = fopen(FNAME1, "w")) == 0) ABORT("open failed");
if (CORD_put(z,f) == EOF) ABORT("CORD_put failed");
if (fclose(f) == EOF) ABORT("fclose failed");
- w = CORD_from_file(f1a = fopen(FNAME1, "rb"));
+ f1a = fopen(FNAME1, "rb");
+ if (!f1a) ABORT("Unable to open " FNAME1);
+ w = CORD_from_file(f1a);
if (CORD_len(w) != CORD_len(z)) ABORT("file length wrong");
if (CORD_cmp(w,z) != 0) ABORT("file comparison wrong");
if (CORD_cmp(CORD_substr(w, 50*36+2, 36), y) != 0)
- ABORT("file substr wrong");
- z = CORD_from_file_lazy(f1b = fopen(FNAME1, "rb"));
+ ABORT("file substr wrong");
+ f1b = fopen(FNAME1, "rb");
+ if (!f1b) ABORT("2nd open failed: " FNAME1);
+ z = CORD_from_file_lazy(f1b);
if (CORD_cmp(w,z) != 0) ABORT("File conversions differ");
if (CORD_chr(w, 0, '9') != 37) ABORT("CORD_chr failed 1");
if (CORD_chr(w, 3, 'a') != 38) ABORT("CORD_chr failed 2");
# endif
if (CORD_put(x,f) == EOF) ABORT("CORD_put failed");
if (fclose(f) == EOF) ABORT("fclose failed");
- w = CORD_from_file(f2 = fopen(FNAME2, "rb"));
+ f2 = fopen(FNAME2, "rb");
+ if (!f2) ABORT("Unable to open " FNAME2);
+ w = CORD_from_file(f2);
if (CORD_len(w) != CORD_len(x)) ABORT("file length wrong");
if (CORD_cmp(w,x) != 0) ABORT("file comparison wrong");
if (CORD_cmp(CORD_substr(w, 1000*36, 36), y) != 0)
- ABORT("file substr wrong");
+ ABORT("file substr wrong");
if (strcmp(CORD_to_char_star(CORD_substr(w, 1000*36, 36)), y) != 0)
- ABORT("char * file substr wrong");
+ ABORT("char * file substr wrong");
if (strcmp(CORD_substr(w, 1000*36, 2), "ab") != 0)
- ABORT("short file substr wrong");
+ ABORT("short file substr wrong");
if (CORD_str(x,1,"9a") != 35) ABORT("CORD_str failed 1");
if (CORD_str(x,0,"9abcdefghijk") != 35) ABORT("CORD_str failed 2");
if (CORD_str(x,0,"9abcdefghijx") != CORD_NOT_FOUND)
- ABORT("CORD_str failed 3");
+ ABORT("CORD_str failed 3");
if (CORD_str(x,0,"9>") != CORD_NOT_FOUND) ABORT("CORD_str failed 4");
if (remove(FNAME1) != 0) {
- /* On some systems, e.g. OS2, this may fail if f1 is still open. */
- if ((fclose(f1a) == EOF) & (fclose(f1b) == EOF))
- ABORT("fclose(f1) failed");
- if (remove(FNAME1) != 0) ABORT("remove 1 failed");
+ /* On some systems, e.g. OS2, this may fail if f1 is still open. */
+ if ((fclose(f1a) == EOF) & (fclose(f1b) == EOF))
+ ABORT("fclose(f1) failed");
+ if (remove(FNAME1) != 0) ABORT("remove 1 failed");
}
if (remove(FNAME2) != 0) {
- if (fclose(f2) == EOF) ABORT("fclose(f2) failed");
- if (remove(FNAME2) != 0) ABORT("remove 2 failed");
+ if (fclose(f2) == EOF) ABORT("fclose(f2) failed");
+ if (remove(FNAME2) != 0) ABORT("remove 2 failed");
}
}
-void test_printf()
+void test_printf(void)
{
CORD result;
char result2[200];
long l;
short s;
CORD x;
-
+
if (CORD_sprintf(&result, "%7.2f%ln", 3.14159F, &l) != 7)
- ABORT("CORD_sprintf failed 1");
+ ABORT("CORD_sprintf failed 1");
if (CORD_cmp(result, " 3.14") != 0)ABORT("CORD_sprintf goofed 1");
if (l != 7) ABORT("CORD_sprintf goofed 2");
if (CORD_sprintf(&result, "%-7.2s%hn%c%s", "abcd", &s, 'x', "yz") != 10)
- ABORT("CORD_sprintf failed 2");
+ ABORT("CORD_sprintf failed 2");
if (CORD_cmp(result, "ab xyz") != 0)ABORT("CORD_sprintf goofed 3");
if (s != 7) ABORT("CORD_sprintf goofed 4");
x = "abcdefghij";
x = CORD_cat(x,x);
x = CORD_cat(x,x);
if (CORD_sprintf(&result, "->%-120.78r!\n", x) != 124)
- ABORT("CORD_sprintf failed 3");
+ ABORT("CORD_sprintf failed 3");
(void) sprintf(result2, "->%-120.78s!\n", CORD_to_char_star(x));
if (CORD_cmp(result, result2) != 0)ABORT("CORD_sprintf goofed 5");
}
-int main()
+int main(void)
{
# ifdef THINK_C
printf("cordtest:\n");
# define DebugBreak() _exit(-1) /* there is no abort() in WinCE */
# endif
# ifdef SMALL_CONFIG
-# if defined(MSWIN32) || defined(MSWINCE)
+# if (defined(MSWIN32) && !defined(LINT2)) || defined(MSWINCE)
# define ABORT(msg) DebugBreak()
# else
# define ABORT(msg) abort()
# include <stdarg.h>
+#define CHECH_GCLIB_VERSION \
+ if (GC_get_version() != ((GC_VERSION_MAJOR<<16) \
+ | (GC_VERSION_MINOR<<8) \
+ | GC_ALPHA_VERSION)) { \
+ GC_printf("libgc version mismatch\n"); \
+ exit(1); \
+ }
+
/* Call GC_INIT only on platforms on which we think we really need it, */
/* so that we can test automatic initialization on the rest. */
#if defined(CYGWIN32) || defined (AIX) || defined(DARWIN) \
|| defined(THREAD_LOCAL_ALLOC) \
|| (defined(MSWINCE) && !defined(GC_WINMAIN_REDIRECT))
-# define GC_COND_INIT() GC_INIT()
+# define GC_COND_INIT() GC_INIT(); CHECH_GCLIB_VERSION
#else
-# define GC_COND_INIT()
+# define GC_COND_INIT() CHECH_GCLIB_VERSION
#endif
+#define CHECK_OUT_OF_MEMORY(p) \
+ if ((p) == NULL) { \
+ GC_printf("Out of memory\n"); \
+ exit(1); \
+ }
+
/* Allocation Statistics. Incremented without synchronization. */
/* FIXME: We should be using synchronization. */
int stubborn_count = 0;
#else /* !AMIGA_FASTALLOC */
-# ifdef PCR
+# if defined(PCR) || defined(LINT2)
# define FAIL (void)abort()
# else
# define FAIL ABORT("Test failed")
stubborn_count++;
r = (sexpr) GC_MALLOC_STUBBORN(sizeof(struct SEXPR) + my_extra);
- if (r == 0) {
- GC_printf("Out of memory\n");
- exit(1);
- }
+ CHECK_OUT_OF_MEMORY(r);
for (p = (int *)r;
((char *)p) < ((char *)r) + my_extra + sizeof(struct SEXPR); p++) {
if (*p) {
collectable_count++;
r = (sexpr) GC_MALLOC(sizeof(struct SEXPR));
- if (r == 0) {
- GC_printf("Out of memory\n");
- exit(1);
- }
+ CHECK_OUT_OF_MEMORY(r);
r -> sexpr_car = x;
r -> sexpr_cdr = y;
return(r);
uncollectable_count++;
r = (sexpr) GC_MALLOC_UNCOLLECTABLE(sizeof(struct SEXPR));
- if (r == 0) {
- GC_printf("Out of memory\n");
- exit(1);
- }
+ CHECK_OUT_OF_MEMORY(r);
r -> sexpr_car = x;
r -> sexpr_cdr = (sexpr)(~(GC_word)y);
return(r);
r = (GC_word *) GC_GCJ_MALLOC(sizeof(struct SEXPR)
+ sizeof(struct fake_vtable*),
&gcj_class_struct2);
- if (r == 0) {
- GC_printf("Out of memory\n");
- exit(1);
- }
+ CHECK_OUT_OF_MEMORY(r);
result = (sexpr)(r + 1);
result -> sexpr_car = x;
result -> sexpr_cdr = y;
f = (sexpr *)GC_MALLOC(4 * sizeof(sexpr));
realloc_count++;
f = (sexpr *)GC_REALLOC((void *)f, 6 * sizeof(sexpr));
+ CHECK_OUT_OF_MEMORY(f);
f[5] = ints(1,17);
collectable_count++;
g = (sexpr *)GC_MALLOC(513 * sizeof(sexpr));
realloc_count++;
g = (sexpr *)GC_REALLOC((void *)g, 800 * sizeof(sexpr));
+ CHECK_OUT_OF_MEMORY(g);
g[799] = ints(1,18);
collectable_count++;
h = (sexpr *)GC_MALLOC(1025 * sizeof(sexpr));
realloc_count++;
h = (sexpr *)GC_REALLOC((void *)h, 2000 * sizeof(sexpr));
+ CHECK_OUT_OF_MEMORY(h);
# ifdef GC_GCJ_SUPPORT
h[1999] = gcj_ints(1,200);
for (i = 0; i < 51; ++i)
collectable_count++;
# if defined(MACOS)
/* get around static data limitations. */
- if (!live_indicators)
- live_indicators =
- (GC_word*)NewPtrClear(MAX_FINALIZED * sizeof(GC_word));
if (!live_indicators) {
- GC_printf("Out of memory\n");
- exit(1);
+ live_indicators =
+ (GC_word*)NewPtrClear(MAX_FINALIZED * sizeof(GC_word));
+ CHECK_OUT_OF_MEMORY(live_indicators);
}
# endif
if (n == 0) return(0);
- if (result == 0) {
- GC_printf("Out of memory\n");
- exit(1);
- }
+ CHECK_OUT_OF_MEMORY(result);
result -> level = n;
result -> lchild = mktree(n-1);
result -> rchild = mktree(n-1);
if (my_free_list_ptr == 0) {
uncollectable_count++;
my_free_list_ptr = GC_NEW_UNCOLLECTABLE(void *);
+ CHECK_OUT_OF_MEMORY(my_free_list_ptr);
if (pthread_setspecific(fl_key, my_free_list_ptr) != 0) {
GC_printf("pthread_setspecific failed\n");
FAIL;
my_free_list = *my_free_list_ptr;
if (my_free_list == 0) {
my_free_list = GC_malloc_many(8);
- if (my_free_list == 0) {
- GC_printf("alloc8bytes out of memory\n");
- FAIL;
- }
+ CHECK_OUT_OF_MEMORY(my_free_list);
}
*my_free_list_ptr = GC_NEXT(my_free_list);
GC_NEXT(my_free_list) = 0;
for (i = 0; i < 4000; i++) {
collectable_count++;
new = (GC_word *) GC_malloc_explicitly_typed(4 * sizeof(GC_word), d1);
+ CHECK_OUT_OF_MEMORY(new);
if (0 != new[0] || 0 != new[1]) {
GC_printf("Bad initialization by GC_malloc_explicitly_typed\n");
FAIL;
old = new;
collectable_count++;
new = (GC_word *) GC_malloc_explicitly_typed(4 * sizeof(GC_word), d2);
+ CHECK_OUT_OF_MEMORY(new);
new[0] = 17;
new[1] = (GC_word)old;
old = new;
collectable_count++;
new = (GC_word *) GC_malloc_explicitly_typed(33 * sizeof(GC_word), d3);
+ CHECK_OUT_OF_MEMORY(new);
new[0] = 17;
new[1] = (GC_word)old;
old = new;
collectable_count++;
new = (GC_word *) GC_calloc_explicitly_typed(4, 2 * sizeof(GC_word),
d1);
+ CHECK_OUT_OF_MEMORY(new);
new[0] = 17;
new[1] = (GC_word)old;
old = new;
new = (GC_word *) GC_calloc_explicitly_typed(1001,
3 * sizeof(GC_word),
d2);
- if (0 != new[0] || 0 != new[1]) {
+ if (new && (0 != new[0] || 0 != new[1])) {
GC_printf("Bad initialization by GC_malloc_explicitly_typed\n");
FAIL;
}
}
+ CHECK_OUT_OF_MEMORY(new);
new[0] = 17;
new[1] = (GC_word)old;
old = new;
# endif /* DBG_HDRS_ALL */
/* Test floating point alignment */
collectable_count += 2;
- *(double *)GC_MALLOC(sizeof(double)) = 1.0;
- *(double *)GC_MALLOC(sizeof(double)) = 1.0;
+ {
+ double *dp = GC_MALLOC(sizeof(double));
+ CHECK_OUT_OF_MEMORY(dp);
+ *dp = 1.0;
+ dp = GC_MALLOC(sizeof(double));
+ CHECK_OUT_OF_MEMORY(dp);
+ *dp = 1.0;
+ }
/* Test size 0 allocation a bit more */
{
size_t i;
}
}
+#ifdef LINT2
+# define CHECK_LOOKUP_MY_THREAD(me) \
+ if (!(me)) ABORT("GC_lookup_thread_inner(GetCurrentThreadId) failed")
+#else
+# define CHECK_LOOKUP_MY_THREAD(me) /* empty */
+#endif
+
/* Called by GC_finalize() (in case of an allocation failure observed). */
/* GC_reset_finalizer_nested() is the same as in pthread_support.c. */
GC_INNER void GC_reset_finalizer_nested(void)
{
GC_thread me = GC_lookup_thread_inner(GetCurrentThreadId());
+ CHECK_LOOKUP_MY_THREAD(me);
me->finalizer_nested = 0;
}
GC_INNER unsigned char *GC_check_finalizer_nested(void)
{
GC_thread me = GC_lookup_thread_inner(GetCurrentThreadId());
- unsigned nesting_level = me->finalizer_nested;
+ unsigned nesting_level;
+ CHECK_LOOKUP_MY_THREAD(me);
+ nesting_level = me->finalizer_nested;
if (nesting_level) {
/* We are inside another GC_invoke_finalizers(). */
/* Skip some implicitly-called GC_invoke_finalizers() */
LOCK();
# if defined(THREAD_LOCAL_ALLOC) || defined(GC_PTHREADS)
me = GC_lookup_thread_inner(thread_id);
+ CHECK_LOOKUP_MY_THREAD(me);
GC_ASSERT(!KNOWN_FINISHED(me));
# endif
# if defined(THREAD_LOCAL_ALLOC)
LOCK();
me = GC_lookup_thread_inner(thread_id);
+ CHECK_LOOKUP_MY_THREAD(me);
GC_ASSERT(me -> thread_blocked_sp == NULL);
# ifdef IA64
me -> backing_store_ptr = stack_ptr;
LOCK(); /* This will block if the world is stopped. */
me = GC_lookup_thread_inner(GetCurrentThreadId());
-
+ CHECK_LOOKUP_MY_THREAD(me);
/* Adjust our stack base value (this could happen unless */
/* GC_get_stack_base() was used which returned GC_SUCCESS). */
GC_ASSERT(me -> stack_base != NULL);
return;
}
- GC_ASSERT(current_min > start);
+ GC_ASSERT(current_min > start && plast_stack_min != NULL);
# ifdef MSWINCE
if (GC_dont_query_stack_min) {
*lo = GC_wince_evaluate_stack_min(current_min);
GC_INNER void GC_init_parallel(void)
{
# if defined(THREAD_LOCAL_ALLOC)
+ GC_thread me;
DCL_LOCK_STATE;
# endif
/* Initialize thread local free lists if used. */
# if defined(THREAD_LOCAL_ALLOC)
LOCK();
- GC_init_thread_local(
- &GC_lookup_thread_inner(GetCurrentThreadId())->tlfs);
+ me = GC_lookup_thread_inner(GetCurrentThreadId());
+ CHECK_LOOKUP_MY_THREAD(me);
+ GC_init_thread_local(&me->tlfs);
UNLOCK();
# endif
}