Each thread structure must be initialized. */ This call must be made from the new thread. */ Caller holds allocation lock. */
| 75 | /* This call must be made from the new thread. */ |
| 76 | /* Caller holds allocation lock. */ |
| 77 | void GC_init_thread_local(GC_tlfs p) |
| 78 | { |
| 79 | int i; |
| 80 | |
| 81 | if (!keys_initialized) { |
| 82 | if (0 != GC_key_create(&GC_thread_key, 0)) { |
| 83 | ABORT("Failed to create key for local allocator"); |
| 84 | } |
| 85 | keys_initialized = TRUE; |
| 86 | } |
| 87 | if (0 != GC_setspecific(GC_thread_key, p)) { |
| 88 | ABORT("Failed to set thread specific allocation pointers"); |
| 89 | } |
| 90 | for (i = 1; i < TINY_FREELISTS; ++i) { |
| 91 | p -> ptrfree_freelists[i] = (void *)1; |
| 92 | p -> normal_freelists[i] = (void *)1; |
| 93 | # ifdef GC_GCJ_SUPPORT |
| 94 | p -> gcj_freelists[i] = (void *)1; |
| 95 | # endif |
| 96 | } |
| 97 | /* Set up the size 0 free lists. */ |
| 98 | /* We now handle most of them like regular free lists, to ensure */ |
| 99 | /* That explicit deallocation works. However, allocation of a */ |
| 100 | /* size 0 "gcj" object is always an error. */ |
| 101 | p -> ptrfree_freelists[0] = (void *)1; |
| 102 | p -> normal_freelists[0] = (void *)1; |
| 103 | # ifdef GC_GCJ_SUPPORT |
| 104 | p -> gcj_freelists[0] = ERROR_FL; |
| 105 | # endif |
| 106 | } |
| 107 | |
| 108 | #ifdef GC_GCJ_SUPPORT |
| 109 | extern void ** GC_gcjobjfreelist; |
no outgoing calls
no test coverage detected