/* This call must be made from the new thread. */ GC_INNER void GC_init_thread_local(GC_tlfs p) { int i, j; GC_ASSERT(I_HOLD_LOCK()); if (!EXPECT(keys_initialized, TRUE)) { GC_ASSERT((word)&GC_thread_key % sizeof(word) == 0); if (0 != GC_key_create(&GC_thread_key, reset_thread_key)) { ABORT("Failed to create key for local allocator"); } keys_initialized = TRUE; } if (0 != GC_setspecific(GC_thread_key, p)) { ABORT("Failed to set thread specific allocation pointers"); } for (j = 0; j < TINY_FREELISTS; ++j) { for (i = 0; i < THREAD_FREELISTS_KINDS; ++i) { p -> _freelists[i][j] = (void *)(word)1; } # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[j] = (void *)(word)1; # endif # ifdef ENABLE_DISCLAIM p -> finalized_freelists[j] = (void *)(word)1; # endif } /* The size 0 free lists are handled like the regular free lists, */ /* to ensure that the explicit deallocation works. However, */ /* allocation of a size 0 "gcj" object is always an error. */ # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[0] = ERROR_FL; # endif }
/* Caller holds allocation lock. */ void GC_init_thread_local(GC_thread p) { int i; if (!keys_initialized) { if (0 != GC_key_create(&GC_thread_key, 0)) { ABORT("Failed to create key for local allocator"); } keys_initialized = TRUE; } if (0 != GC_setspecific(GC_thread_key, p)) { ABORT("Failed to set thread specific allocation pointers"); } for (i = 1; i < NFREELISTS; ++i) { p -> ptrfree_freelists[i] = (ptr_t)1; p -> normal_freelists[i] = (ptr_t)1; # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[i] = (ptr_t)1; # endif } /* Set up the size 0 free lists. */ p -> ptrfree_freelists[0] = (ptr_t)(&size_zero_object); p -> normal_freelists[0] = (ptr_t)(&size_zero_object); # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[0] = (ptr_t)(-1); # endif }
/* This call must be made from the new thread. */ GC_INNER void GC_init_thread_local(GC_tlfs p) { int i, j; GC_ASSERT(I_HOLD_LOCK()); if (!EXPECT(keys_initialized, TRUE)) { GC_ASSERT((word)&GC_thread_key % sizeof(word) == 0); if (0 != GC_key_create(&GC_thread_key, reset_thread_key)) { ABORT("Failed to create key for local allocator"); } keys_initialized = TRUE; } if (0 != GC_setspecific(GC_thread_key, p)) { ABORT("Failed to set thread specific allocation pointers"); } for (i = 0; i < MAXOBJKINDS; ++i) { for (j = 1; j < TINY_FREELISTS; ++j) { p->freelists[i][j] = (void *)(word)1; } /* Set up the size 0 free lists. */ /* We now handle most of them like regular free lists, to ensure */ /* That explicit deallocation works. However, allocation of a */ /* size 0 "gcj" object is always an error. */ # ifdef GC_GCJ_SUPPORT if (i == GC_gcj_kind) { p->freelists[i][0] = ERROR_FL; } else { # endif /* else */ { p->freelists[i][0] = (void *)(word)1; } } # ifdef ENABLE_DISCLAIM for (i = 0; i < TINY_FREELISTS; ++i) { p -> finalized_freelists[i] = (void *)(word)1; } p->finalized_freelists[0] = (void *)(word)1; # endif } /* We hold the allocator lock. */ GC_INNER void GC_destroy_thread_local(GC_tlfs p) { int i; /* We currently only do this from the thread itself or from */ /* the fork handler for a child process. */ for (i = 0; i < MAXOBJKINDS; ++i) { return_freelists(p->freelists[i], GC_freelist[i]); } # ifdef ENABLE_DISCLAIM return_freelists(p -> finalized_freelists, (void **)GC_finalized_objfreelist); # endif }
/* This call must be made from the new thread. */ GC_INNER void GC_init_thread_local(GC_tlfs p) { int i; GC_ASSERT(I_HOLD_LOCK()); if (!EXPECT(keys_initialized, TRUE)) { GC_ASSERT((word)&GC_thread_key % sizeof(word) == 0); if (0 != GC_key_create(&GC_thread_key, reset_thread_key)) { ABORT("Failed to create key for local allocator"); } keys_initialized = TRUE; } if (0 != GC_setspecific(GC_thread_key, p)) { ABORT("Failed to set thread specific allocation pointers"); } for (i = 1; i < TINY_FREELISTS; ++i) { p -> ptrfree_freelists[i] = (void *)(word)1; p -> normal_freelists[i] = (void *)(word)1; # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[i] = (void *)(word)1; # endif # ifdef ENABLE_DISCLAIM p -> finalized_freelists[i] = (void *)(word)1; # endif } /* Set up the size 0 free lists. */ /* We now handle most of them like regular free lists, to ensure */ /* That explicit deallocation works. However, allocation of a */ /* size 0 "gcj" object is always an error. */ p -> ptrfree_freelists[0] = (void *)(word)1; p -> normal_freelists[0] = (void *)(word)1; # ifdef GC_GCJ_SUPPORT p -> gcj_freelists[0] = ERROR_FL; # endif # ifdef ENABLE_DISCLAIM p -> finalized_freelists[0] = (void *)(word)1; # endif }