137
104
# define __inline__
107
/* Undefine macros used to redirect pthread primitives. */
108
# undef pthread_create
109
# if !defined(GC_DARWIN_THREADS)
110
# undef pthread_sigmask
113
# undef pthread_detach
114
# if defined(GC_OSF1_THREADS) && defined(_PTHREAD_USE_MANGLED_NAMES_) \
115
&& !defined(_PTHREAD_USE_PTDNAM_)
116
/* Restore the original mangled names on Tru64 UNIX. */
117
# define pthread_create __pthread_create
118
# define pthread_join __pthread_join
119
# define pthread_detach __pthread_detach
140
122
#ifdef GC_USE_LD_WRAP
141
123
# define WRAP_FUNC(f) __wrap_##f
142
124
# define REAL_FUNC(f) __real_##f
144
# define WRAP_FUNC(f) GC_##f
145
# if !defined(GC_DGUX386_THREADS)
146
# define REAL_FUNC(f) f
147
# else /* GC_DGUX386_THREADS */
148
# define REAL_FUNC(f) __d10_##f
149
# endif /* GC_DGUX386_THREADS */
150
# undef pthread_create
151
# if !defined(GC_DARWIN_THREADS)
152
# undef pthread_sigmask
155
# undef pthread_detach
156
# if defined(GC_OSF1_THREADS) && defined(_PTHREAD_USE_MANGLED_NAMES_) \
157
&& !defined(_PTHREAD_USE_PTDNAM_)
158
/* Restore the original mangled names on Tru64 UNIX. */
159
# define pthread_create __pthread_create
160
# define pthread_join __pthread_join
161
# define pthread_detach __pthread_detach
126
# ifdef GC_USE_DLOPEN_WRAP
128
# define WRAP_FUNC(f) f
129
# define REAL_FUNC(f) GC_real_##f
130
/* We define both GC_f and plain f to be the wrapped function. */
131
/* In that way plain calls work, as do calls from files that */
132
/* included gc.h, wich redefined f to GC_f. */
133
/* FIXME: Needs work for DARWIN and True64 (OSF1) */
134
typedef int (* GC_pthread_create_t)(pthread_t *, const pthread_attr_t *,
135
void * (*)(void *), void *);
136
static GC_pthread_create_t GC_real_pthread_create;
137
typedef int (* GC_pthread_sigmask_t)(int, const sigset_t *, sigset_t *);
138
static GC_pthread_sigmask_t GC_real_pthread_sigmask;
139
typedef int (* GC_pthread_join_t)(pthread_t, void **);
140
static GC_pthread_join_t GC_real_pthread_join;
141
typedef int (* GC_pthread_detach_t)(pthread_t);
142
static GC_pthread_detach_t GC_real_pthread_detach;
144
# define WRAP_FUNC(f) GC_##f
145
# if !defined(GC_DGUX386_THREADS)
146
# define REAL_FUNC(f) f
147
# else /* GC_DGUX386_THREADS */
148
# define REAL_FUNC(f) __d10_##f
149
# endif /* GC_DGUX386_THREADS */
153
#if defined(GC_USE_DL_WRAP) || defined(GC_USE_DLOPEN_WRAP)
154
/* Define GC_ functions as aliases for the plain ones, which will */
155
/* be intercepted. This allows files which include gc.h, and hence */
156
/* generate references to the GC_ symbols, to see the right symbols. */
157
int GC_pthread_create(pthread_t * t, const pthread_attr_t * a,
158
void * (* fn)(void *), void * arg) {
159
return pthread_create(t, a, fn, arg);
161
int GC_pthread_sigmask(int how, const sigset_t *mask, sigset_t *old) {
162
return pthread_sigmask(how, mask, old);
164
int GC_pthread_join(pthread_t t, void **res) {
165
return pthread_join(t, res);
167
int GC_pthread_detach(pthread_t t) {
168
return pthread_detach(t);
170
#endif /* Linker-based interception. */
172
#ifdef GC_USE_DLOPEN_WRAP
173
static GC_bool GC_syms_initialized = FALSE;
175
void GC_init_real_syms(void)
178
# define LIBPTHREAD_NAME "libpthread.so.0"
179
# define LIBPTHREAD_NAME_LEN 16 /* incl. trailing 0 */
180
size_t len = LIBPTHREAD_NAME_LEN - 1;
181
char namebuf[LIBPTHREAD_NAME_LEN];
182
static char *libpthread_name = LIBPTHREAD_NAME;
184
if (GC_syms_initialized) return;
186
dl_handle = RTLD_NEXT;
188
dl_handle = dlopen(libpthread_name, RTLD_LAZY);
189
if (NULL == dl_handle) {
190
while (isdigit(libpthread_name[len-1])) --len;
191
if (libpthread_name[len-1] == '.') --len;
192
memcpy(namebuf, libpthread_name, len);
194
dl_handle = dlopen(namebuf, RTLD_LAZY);
196
if (NULL == dl_handle) ABORT("Couldn't open libpthread\n");
198
GC_real_pthread_create = (GC_pthread_create_t)
199
dlsym(dl_handle, "pthread_create");
200
GC_real_pthread_sigmask = (GC_pthread_sigmask_t)
201
dlsym(dl_handle, "pthread_sigmask");
202
GC_real_pthread_join = (GC_pthread_join_t)
203
dlsym(dl_handle, "pthread_join");
204
GC_real_pthread_detach = (GC_pthread_detach_t)
205
dlsym(dl_handle, "pthread_detach");
206
GC_syms_initialized = TRUE;
209
# define INIT_REAL_SYMS() if (!GC_syms_initialized) GC_init_real_syms();
211
# define INIT_REAL_SYMS()
214
void GC_thr_init(void);
167
216
static GC_bool parallel_initialized = FALSE;
169
void GC_init_parallel();
171
# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
173
/* We don't really support thread-local allocation with DBG_HDRS_ALL */
175
#ifdef USE_COMPILER_TLS
178
GC_key_t GC_thread_key;
180
static GC_bool keys_initialized;
182
/* Recover the contents of the freelist array fl into the global one gfl.*/
183
/* Note that the indexing scheme differs, in that gfl has finer size */
184
/* resolution, even if not all entries are used. */
185
/* We hold the allocator lock. */
186
static void return_freelists(ptr_t *fl, ptr_t *gfl)
192
for (i = 1; i < NFREELISTS; ++i) {
193
nwords = i * (GRANULARITY/sizeof(word));
196
if ((word)q >= HBLKSIZE) {
197
if (gfl[nwords] == 0) {
201
for (; (word)q >= HBLKSIZE; qptr = &(obj_link(q)), q = *qptr);
207
/* Clear fl[i], since the thread structure may hang around. */
208
/* Do it in a way that is likely to trap if we access it. */
209
fl[i] = (ptr_t)HBLKSIZE;
213
/* We statically allocate a single "size 0" object. It is linked to */
214
/* itself, and is thus repeatedly reused for all size 0 allocation */
215
/* requests. (Size 0 gcj allocation requests are incorrect, and */
216
/* we arrange for those to fault asap.) */
217
static ptr_t size_zero_object = (ptr_t)(&size_zero_object);
219
/* Each thread structure must be initialized. */
220
/* This call must be made from the new thread. */
221
/* Caller holds allocation lock. */
222
void GC_init_thread_local(GC_thread p)
226
if (!keys_initialized) {
227
if (0 != GC_key_create(&GC_thread_key, 0)) {
228
ABORT("Failed to create key for local allocator");
230
keys_initialized = TRUE;
232
if (0 != GC_setspecific(GC_thread_key, p)) {
233
ABORT("Failed to set thread specific allocation pointers");
235
for (i = 1; i < NFREELISTS; ++i) {
236
p -> ptrfree_freelists[i] = (ptr_t)1;
237
p -> normal_freelists[i] = (ptr_t)1;
238
# ifdef GC_GCJ_SUPPORT
239
p -> gcj_freelists[i] = (ptr_t)1;
242
/* Set up the size 0 free lists. */
243
p -> ptrfree_freelists[0] = (ptr_t)(&size_zero_object);
244
p -> normal_freelists[0] = (ptr_t)(&size_zero_object);
245
# ifdef GC_GCJ_SUPPORT
246
p -> gcj_freelists[0] = (ptr_t)(-1);
250
#ifdef GC_GCJ_SUPPORT
251
extern ptr_t * GC_gcjobjfreelist;
254
/* We hold the allocator lock. */
255
void GC_destroy_thread_local(GC_thread p)
257
/* We currently only do this from the thread itself or from */
258
/* the fork handler for a child process. */
260
GC_ASSERT(GC_getspecific(GC_thread_key) == (void *)p);
262
return_freelists(p -> ptrfree_freelists, GC_aobjfreelist);
263
return_freelists(p -> normal_freelists, GC_objfreelist);
264
# ifdef GC_GCJ_SUPPORT
265
return_freelists(p -> gcj_freelists, GC_gcjobjfreelist);
269
extern GC_PTR GC_generic_malloc_many();
271
GC_PTR GC_local_malloc(size_t bytes)
273
if (EXPECT(!SMALL_ENOUGH(bytes),0)) {
274
return(GC_malloc(bytes));
276
int index = INDEX_FROM_BYTES(bytes);
279
# if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
280
GC_key_t k = GC_thread_key;
284
# if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
285
if (EXPECT(0 == k, 0)) {
286
/* This can happen if we get called when the world is */
287
/* being initialized. Whether we can actually complete */
288
/* the initialization then is unclear. */
293
tsd = GC_getspecific(GC_thread_key);
294
# ifdef GC_ASSERTIONS
296
GC_ASSERT(tsd == (void *)GC_lookup_thread(pthread_self()));
299
my_fl = ((GC_thread)tsd) -> normal_freelists + index;
301
if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
302
ptr_t next = obj_link(my_entry);
303
GC_PTR result = (GC_PTR)my_entry;
305
obj_link(my_entry) = 0;
306
PREFETCH_FOR_WRITE(next);
308
} else if ((word)my_entry - 1 < DIRECT_GRANULES) {
309
*my_fl = my_entry + index + 1;
310
return GC_malloc(bytes);
312
GC_generic_malloc_many(BYTES_FROM_INDEX(index), NORMAL, my_fl);
313
if (*my_fl == 0) return GC_oom_fn(bytes);
314
return GC_local_malloc(bytes);
319
GC_PTR GC_local_malloc_atomic(size_t bytes)
321
if (EXPECT(!SMALL_ENOUGH(bytes), 0)) {
322
return(GC_malloc_atomic(bytes));
324
int index = INDEX_FROM_BYTES(bytes);
325
ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
326
-> ptrfree_freelists + index;
327
ptr_t my_entry = *my_fl;
329
if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
330
GC_PTR result = (GC_PTR)my_entry;
331
*my_fl = obj_link(my_entry);
333
} else if ((word)my_entry - 1 < DIRECT_GRANULES) {
334
*my_fl = my_entry + index + 1;
335
return GC_malloc_atomic(bytes);
337
GC_generic_malloc_many(BYTES_FROM_INDEX(index), PTRFREE, my_fl);
338
/* *my_fl is updated while the collector is excluded; */
339
/* the free list is always visible to the collector as */
341
if (*my_fl == 0) return GC_oom_fn(bytes);
342
return GC_local_malloc_atomic(bytes);
347
#ifdef GC_GCJ_SUPPORT
349
#include "include/gc_gcj.h"
352
extern GC_bool GC_gcj_malloc_initialized;
355
extern int GC_gcj_kind;
357
GC_PTR GC_local_gcj_malloc(size_t bytes,
358
void * ptr_to_struct_containing_descr)
360
GC_ASSERT(GC_gcj_malloc_initialized);
361
if (EXPECT(!SMALL_ENOUGH(bytes), 0)) {
362
return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
364
int index = INDEX_FROM_BYTES(bytes);
365
ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
366
-> gcj_freelists + index;
367
ptr_t my_entry = *my_fl;
368
if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
369
GC_PTR result = (GC_PTR)my_entry;
370
GC_ASSERT(!GC_incremental);
371
/* We assert that any concurrent marker will stop us. */
372
/* Thus it is impossible for a mark procedure to see the */
373
/* allocation of the next object, but to see this object */
374
/* still containing a free list pointer. Otherwise the */
375
/* marker might find a random "mark descriptor". */
376
*(volatile ptr_t *)my_fl = obj_link(my_entry);
377
/* We must update the freelist before we store the pointer. */
378
/* Otherwise a GC at this point would see a corrupted */
380
/* A memory barrier is probably never needed, since the */
381
/* action of stopping this thread will cause prior writes */
383
GC_ASSERT(((void * volatile *)result)[1] == 0);
384
*(void * volatile *)result = ptr_to_struct_containing_descr;
386
} else if ((word)my_entry - 1 < DIRECT_GRANULES) {
387
if (!GC_incremental) *my_fl = my_entry + index + 1;
388
/* In the incremental case, we always have to take this */
389
/* path. Thus we leave the counter alone. */
390
return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
392
GC_generic_malloc_many(BYTES_FROM_INDEX(index), GC_gcj_kind, my_fl);
393
if (*my_fl == 0) return GC_oom_fn(bytes);
394
return GC_local_gcj_malloc(bytes, ptr_to_struct_containing_descr);
399
#endif /* GC_GCJ_SUPPORT */
401
# else /* !THREAD_LOCAL_ALLOC && !DBG_HDRS_ALL */
403
# define GC_destroy_thread_local(t)
405
# endif /* !THREAD_LOCAL_ALLOC */
409
To make sure that we're using LinuxThreads and not some other thread
410
package, we generate a dummy reference to `pthread_kill_other_threads_np'
411
(was `__pthread_initial_thread_bos' but that disappeared),
412
which is a symbol defined in LinuxThreads, but (hopefully) not in other
415
We no longer do this, since this code is now portable enough that it might
416
actually work for something else.
418
void (*dummy_var_to_force_linux_threads)() = pthread_kill_other_threads_np;
218
GC_bool GC_need_to_lock = FALSE;
220
void GC_init_parallel(void);
421
222
long GC_nprocs = 1; /* Number of processors. We may not have */
422
223
/* access to all of them, but this is as good */
423
224
/* a guess as any ... */
226
#ifdef THREAD_LOCAL_ALLOC
227
/* We must explicitly mark ptrfree and gcj free lists, since the free */
228
/* list links wouldn't otherwise be found. We also set them in the */
229
/* normal free lists, since that involves touching less memory than if */
230
/* we scanned them normally. */
231
void GC_mark_thread_local_free_lists(void)
236
for (i = 0; i < THREAD_TABLE_SZ; ++i) {
237
for (p = GC_threads[i]; 0 != p; p = p -> next) {
238
GC_mark_thread_local_fls_for(&(p->tlfs));
243
#if defined(GC_ASSERTIONS)
244
/* Check that all thread-local free-lists are completely marked. */
245
/* also check that thread-specific-data structures are marked. */
246
void GC_check_tls(void) {
250
for (i = 0; i < THREAD_TABLE_SZ; ++i) {
251
for (p = GC_threads[i]; 0 != p; p = p -> next) {
252
GC_check_tls_for(&(p->tlfs));
255
# if defined(USE_CUSTOM_SPECIFIC)
256
if (GC_thread_key != 0)
257
GC_check_tsd_marks(GC_thread_key);
260
#endif /* GC_ASSERTIONS */
262
#endif /* Thread_local_alloc */
425
264
#ifdef PARALLEL_MARK
427
266
# ifndef MAX_MARKERS
1158
1050
my_pthread = pthread_self();
1159
1051
# ifdef DEBUG_THREADS
1160
GC_printf1("Starting thread 0x%lx\n", my_pthread);
1161
GC_printf1("pid = %ld\n", (long) getpid());
1162
GC_printf1("sp = 0x%lx\n", (long) &arg);
1052
GC_printf("Starting thread 0x%x\n", (unsigned)my_pthread);
1053
GC_printf("pid = %ld\n", (long) getpid());
1054
GC_printf("sp = 0x%lx\n", (long) &arg);
1165
GC_in_thread_creation = TRUE;
1166
me = GC_new_thread(my_pthread);
1167
GC_in_thread_creation = FALSE;
1168
#ifdef GC_DARWIN_THREADS
1169
me -> stop_info.mach_thread = mach_thread_self();
1171
me -> stop_info.stack_ptr = 0;
1057
me = GC_register_my_thread_inner(sb, my_pthread);
1173
1058
me -> flags = si -> flags;
1174
/* me -> stack_end = GC_linux_stack_base(); -- currently (11/99) */
1175
/* doesn't work because the stack base in /proc/self/stat is the */
1176
/* one for the main thread. There is a strong argument that that's */
1177
/* a kernel bug, but a pervasive one. */
1178
# ifdef STACK_GROWS_DOWN
1179
me -> stack_end = (ptr_t)(((word)(&dummy) + (GC_page_size - 1))
1180
& ~(GC_page_size - 1));
1181
# ifndef GC_DARWIN_THREADS
1182
me -> stop_info.stack_ptr = me -> stack_end - 0x10;
1184
/* Needs to be plausible, since an asynchronous stack mark */
1185
/* should not crash. */
1187
me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1));
1188
me -> stop_info.stack_ptr = me -> stack_end + 0x10;
1190
/* This is dubious, since we may be more than a page into the stack, */
1191
/* and hence skip some of it, though it's not clear that matters. */
1193
me -> backing_store_end = (ptr_t)
1194
(GC_save_regs_in_stack() & ~(GC_page_size - 1));
1195
/* This is also < 100% convincing. We should also read this */
1196
/* from /proc, but the hook to do so isn't there yet. */
1199
1060
start = si -> start_routine;
1200
1061
# ifdef DEBUG_THREADS
1201
GC_printf1("start_routine = 0x%lx\n", start);
1062
GC_printf("start_routine = %p\n", (void *)start);
1203
1064
start_arg = si -> arg;
1204
1065
sem_post(&(si -> registered)); /* Last action on si. */
1205
1066
/* OK to deallocate. */
1206
1067
pthread_cleanup_push(GC_thread_exit_proc, 0);
1207
# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
1068
# if defined(THREAD_LOCAL_ALLOC)
1209
GC_init_thread_local(me);
1070
GC_init_thread_local(&(me->tlfs));
1212
1073
result = (*start)(start_arg);
1214
GC_printf1("Finishing thread 0x%x\n", pthread_self());
1075
GC_printf("Finishing thread 0x%x\n", (unsigned)pthread_self());
1216
1077
me -> status = result;
1217
1078
pthread_cleanup_pop(1);
1218
1079
/* Cleanup acquires lock, ensuring that we can't exit */