OSDN Git Service

* include/gc_pthread_redirects.h: Generalize test to use GC_PTHREADS.
[pf3gnuchains/gcc-fork.git] / boehm-gc / linux_threads.c
1 /* 
2  * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
3  * Copyright (c) 1996 by Silicon Graphics.  All rights reserved.
4  * Copyright (c) 1998 by Fergus Henderson.  All rights reserved.
5  * Copyright (c) 2000-2001 by Hewlett-Packard Company.  All rights reserved.
6  *
7  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
8  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
9  *
10  * Permission is hereby granted to use or copy this program
11  * for any purpose,  provided the above notices are retained on all copies.
12  * Permission to modify the code and to distribute modified code is granted,
13  * provided the above notices are retained, and a notice that the code was
14  * modified is included with the above copyright notice.
15  */
16 /*
17  * Support code for LinuxThreads, the clone()-based kernel
18  * thread package for Linux which is included in libc6.
19  *
20  * This code relies on implementation details of LinuxThreads,
21  * (i.e. properties not guaranteed by the Pthread standard),
22  * though this version now does less of that than the other Pthreads
23  * support code.
24  *
25  * Note that there is a lot of code duplication between linux_threads.c
26  * and thread support for some of the other Posix platforms; any changes
27  * made here may need to be reflected there too.
28  */
29 /*
30  * Linux_threads.c now also includes some code to support HPUX and
31  * OSF1 (Compaq Tru64 Unix, really).  The OSF1 support is not yet
32  * functional.  The OSF1 code is based on Eric Benson's
33  * patch, though that was originally against hpux_irix_threads.  The code
34  * here is completely untested.  With 0.0000001% probability, it might
35  * actually work.
36  *
37  * Eric also suggested an alternate basis for a lock implementation in
38  * his code:
39  * + #elif defined(OSF1)
40  * +    unsigned long GC_allocate_lock = 0;
41  * +    msemaphore GC_allocate_semaphore;
42  * + #  define GC_TRY_LOCK() \
43  * +    ((msem_lock(&GC_allocate_semaphore, MSEM_IF_NOWAIT) == 0) \
44  * +     ? (GC_allocate_lock = 1) \
45  * +     : 0)
46  * + #  define GC_LOCK_TAKEN GC_allocate_lock
47  */
48
49 /* #define DEBUG_THREADS 1 */
50
51 /* ANSI C requires that a compilation unit contains something */
52
53 # include "gc.h"
54
55 # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
56      && !defined(GC_IRIX_THREADS)
57
58 # include "private/gc_priv.h"
59
60 # if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \
61      && !defined(USE_HPUX_TLS)
62 #   define USE_HPUX_TLS
63 # endif
64
65 # ifdef THREAD_LOCAL_ALLOC
66 #   if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_HPUX_TLS)
67 #     include "private/specific.h"
68 #   endif
69 #   if defined(USE_PTHREAD_SPECIFIC)
70 #     define GC_getspecific pthread_getspecific
71 #     define GC_setspecific pthread_setspecific
72 #     define GC_key_create pthread_key_create
73       typedef pthread_key_t GC_key_t;
74 #   endif
75 #   if defined(USE_HPUX_TLS)
76 #     define GC_getspecific(x) (x)
77 #     define GC_setspecific(key, v) ((key) = (v), 0)
78 #     define GC_key_create(key, d) 0
79       typedef void * GC_key_t;
80 #   endif
81 # endif
82 # include <stdlib.h>
83 # include <pthread.h>
84 # include <sched.h>
85 # include <time.h>
86 # include <errno.h>
87 # include <unistd.h>
88 # include <sys/mman.h>
89 # include <sys/time.h>
90 # include <semaphore.h>
91 # include <signal.h>
92 # include <sys/types.h>
93 # include <sys/stat.h>
94 # include <fcntl.h>
95
96 #ifndef __GNUC__
97 #   define __inline__
98 #endif
99
100 #ifdef GC_USE_LD_WRAP
101 #   define WRAP_FUNC(f) __wrap_##f
102 #   define REAL_FUNC(f) __real_##f
103 #else
104 #   define WRAP_FUNC(f) GC_##f
105 #   define REAL_FUNC(f) f
106 #   undef pthread_create
107 #   undef pthread_sigmask
108 #   undef pthread_join
109 #   undef pthread_detach
110 #endif
111
112
113 void GC_thr_init();
114
115 #if 0
116 void GC_print_sig_mask()
117 {
118     sigset_t blocked;
119     int i;
120
121     if (pthread_sigmask(SIG_BLOCK, NULL, &blocked) != 0)
122         ABORT("pthread_sigmask");
123     GC_printf0("Blocked: ");
124     for (i = 1; i <= MAXSIG; i++) {
125         if (sigismember(&blocked, i)) { GC_printf1("%ld ",(long) i); }
126     }
127     GC_printf0("\n");
128 }
129 #endif
130
131
132 /* We use the allocation lock to protect thread-related data structures. */
133
134 /* The set of all known threads.  We intercept thread creation and      */
135 /* joins.                                                               */
136 /* Protected by allocation/GC lock.                                     */
137 /* Some of this should be declared volatile, but that's inconsistent    */
138 /* with some library routine declarations.                              */
139 typedef struct GC_Thread_Rep {
140     struct GC_Thread_Rep * next;  /* More recently allocated threads    */
141                                   /* with a given pthread id come       */
142                                   /* first.  (All but the first are     */
143                                   /* guaranteed to be dead, but we may  */
144                                   /* not yet have registered the join.) */
145     pthread_t id;
146     short flags;
147 #       define FINISHED 1       /* Thread has exited.   */
148 #       define DETACHED 2       /* Thread is intended to be detached.   */
149 #       define MAIN_THREAD 4    /* True for the original thread only.   */
150     short thread_blocked;       /* Protected by GC lock.                */
151                                 /* Treated as a boolean value.  If set, */
152                                 /* thread will acquire GC lock before   */
153                                 /* doing any pointer manipulations, and */
154                                 /* has set its sp value.  Thus it does  */
155                                 /* not need to be sent a signal to stop */
156                                 /* it.                                  */
157     ptr_t stack_end;            /* Cold end of the stack.               */
158     ptr_t stack_ptr;            /* Valid only when stopped.             */
159 #   ifdef IA64
160         ptr_t backing_store_end;
161         ptr_t backing_store_ptr;
162 #   endif
163     int signal;
164     void * status;              /* The value returned from the thread.  */
165                                 /* Used only to avoid premature         */
166                                 /* reclamation of any data it might     */
167                                 /* reference.                           */
168 #   ifdef THREAD_LOCAL_ALLOC
169 #       if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE)
170 #           define GRANULARITY 16
171 #           define NFREELISTS 49
172 #       else
173 #           define GRANULARITY 8
174 #           define NFREELISTS 65
175 #       endif
176         /* The ith free list corresponds to size i*GRANULARITY */
177 #       define INDEX_FROM_BYTES(n) ((ADD_SLOP(n) + GRANULARITY - 1)/GRANULARITY)
178 #       define BYTES_FROM_INDEX(i) ((i) * GRANULARITY - EXTRA_BYTES)
179 #       define SMALL_ENOUGH(bytes) (ADD_SLOP(bytes) <= \
180                                     (NFREELISTS-1)*GRANULARITY)
181         ptr_t ptrfree_freelists[NFREELISTS];
182         ptr_t normal_freelists[NFREELISTS];
183 #       ifdef GC_GCJ_SUPPORT
184           ptr_t gcj_freelists[NFREELISTS];
185 #       endif
186                 /* Free lists contain either a pointer or a small count */
187                 /* reflecting the number of granules allocated at that  */
188                 /* size.                                                */
189                 /* 0 ==> thread-local allocation in use, free list      */
190                 /*       empty.                                         */
191                 /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
192                 /*       too few objects of this size have been         */
193                 /*       allocated by this thread.                      */
194                 /* >= HBLKSIZE  => pointer to nonempty free list.       */
195                 /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to      */
196                 /*    local alloc, equivalent to 0.                     */
197 #       define DIRECT_GRANULES (HBLKSIZE/GRANULARITY)
198                 /* Don't use local free lists for up to this much       */
199                 /* allocation.                                          */
200 #   endif
201 } * GC_thread;
202
203 GC_thread GC_lookup_thread(pthread_t id);
204
205 static GC_bool parallel_initialized = FALSE;
206
207 # if defined(__GNUC__)
208     void GC_init_parallel() __attribute__ ((constructor));
209 # else
210     void GC_init_parallel();
211 # endif
212
213 # if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
214
215 /* We don't really support thread-local allocation with DBG_HDRS_ALL */
216
217 #ifdef USE_HPUX_TLS
218   __thread
219 #endif
220 GC_key_t GC_thread_key;
221
222 static GC_bool keys_initialized;
223
224 /* Recover the contents of the freelist array fl into the global one gfl.*/
225 /* Note that the indexing scheme differs, in that gfl has finer size    */
226 /* resolution, even if not all entries are used.                        */
227 /* We hold the allocator lock.                                          */
228 static void return_freelists(ptr_t *fl, ptr_t *gfl)
229 {
230     int i;
231     ptr_t q, *qptr;
232     size_t nwords;
233
234     for (i = 1; i < NFREELISTS; ++i) {
235         nwords = i * (GRANULARITY/sizeof(word));
236         qptr = fl + i;  
237         q = *qptr;
238         if ((word)q < HBLKSIZE) continue;
239         if (gfl[nwords] == 0) {
240             gfl[nwords] = q;
241         } else {
242             /* Concatenate: */
243             for (; (word)q >= HBLKSIZE; qptr = &(obj_link(q)), q = *qptr);
244             GC_ASSERT(0 == q);
245             *qptr = gfl[nwords];
246             gfl[nwords] = fl[i];
247         }
248         /* Clear fl[i], since the thread structure may hang around.     */
249         /* Do it in a way that is likely to trap if we access it.       */
250         fl[i] = (ptr_t)HBLKSIZE;
251     }
252 }
253
254 /* We statically allocate a single "size 0" object. It is linked to     */
255 /* itself, and is thus repeatedly reused for all size 0 allocation      */
256 /* requests.  (Size 0 gcj allocation requests are incorrect, and        */
257 /* we arrange for those to fault asap.)                                 */
258 static ptr_t size_zero_object = (ptr_t)(&size_zero_object);
259
260 /* Each thread structure must be initialized.   */
261 /* This call must be made from the new thread.  */
262 /* Caller holds allocation lock.                */
263 void GC_init_thread_local(GC_thread p)
264 {
265     int i;
266
267     if (!keys_initialized) {
268         if (0 != GC_key_create(&GC_thread_key, 0)) {
269             ABORT("Failed to create key for local allocator");
270         }
271         keys_initialized = TRUE;
272     }
273     if (0 != GC_setspecific(GC_thread_key, p)) {
274         ABORT("Failed to set thread specific allocation pointers");
275     }
276     for (i = 1; i < NFREELISTS; ++i) {
277         p -> ptrfree_freelists[i] = (ptr_t)1;
278         p -> normal_freelists[i] = (ptr_t)1;
279 #       ifdef GC_GCJ_SUPPORT
280           p -> gcj_freelists[i] = (ptr_t)1;
281 #       endif
282     }   
283     /* Set up the size 0 free lists.    */
284     p -> ptrfree_freelists[0] = (ptr_t)(&size_zero_object);
285     p -> normal_freelists[0] = (ptr_t)(&size_zero_object);
286 #   ifdef GC_GCJ_SUPPORT
287         p -> gcj_freelists[0] = (ptr_t)(-1);
288 #   endif
289 }
290
291 #ifdef GC_GCJ_SUPPORT
292   extern ptr_t * GC_gcjobjfreelist;
293 #endif
294
295 /* We hold the allocator lock.  */
296 void GC_destroy_thread_local(GC_thread p)
297 {
298     /* We currently only do this from the thread itself.        */
299         GC_ASSERT(GC_getspecific(GC_thread_key) == (void *)p);
300     return_freelists(p -> ptrfree_freelists, GC_aobjfreelist);
301     return_freelists(p -> normal_freelists, GC_objfreelist);
302 #   ifdef GC_GCJ_SUPPORT
303         return_freelists(p -> gcj_freelists, GC_gcjobjfreelist);
304 #   endif
305 }
306
307 extern GC_PTR GC_generic_malloc_many();
308
309 GC_PTR GC_local_malloc(size_t bytes)
310 {
311     if (EXPECT(!SMALL_ENOUGH(bytes),0)) {
312         return(GC_malloc(bytes));
313     } else {
314         int index = INDEX_FROM_BYTES(bytes);
315         ptr_t * my_fl;
316         ptr_t my_entry;
317         GC_key_t k = GC_thread_key;
318         void * tsd;
319
320 #       if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC) \
321            || !defined(__GNUC__)
322             if (EXPECT(0 == k, 0)) {
323                 /* This can happen if we get called when the world is   */
324                 /* being initialized.  Whether we can actually complete */
325                 /* the initialization then is unclear.                  */
326                 GC_init_parallel();
327                 k = GC_thread_key;
328             }
329 #       endif
330         tsd = GC_getspecific(GC_thread_key);
331 #       ifdef GC_ASSERTIONS
332           LOCK();
333           GC_ASSERT(tsd == (void *)GC_lookup_thread(pthread_self()));
334           UNLOCK();
335 #       endif
336         my_fl = ((GC_thread)tsd) -> normal_freelists + index;
337         my_entry = *my_fl;
338         if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
339             ptr_t next = obj_link(my_entry);
340             GC_PTR result = (GC_PTR)my_entry;
341             *my_fl = next;
342             obj_link(my_entry) = 0;
343             PREFETCH_FOR_WRITE(next);
344             return result;
345         } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
346             *my_fl = my_entry + index + 1;
347             return GC_malloc(bytes);
348         } else {
349             GC_generic_malloc_many(BYTES_FROM_INDEX(index), NORMAL, my_fl);
350             if (*my_fl == 0) return GC_oom_fn(bytes);
351             return GC_local_malloc(bytes);
352         }
353     }
354 }
355
356 GC_PTR GC_local_malloc_atomic(size_t bytes)
357 {
358     if (EXPECT(!SMALL_ENOUGH(bytes), 0)) {
359         return(GC_malloc_atomic(bytes));
360     } else {
361         int index = INDEX_FROM_BYTES(bytes);
362         ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
363                         -> ptrfree_freelists + index;
364         ptr_t my_entry = *my_fl;
365         if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
366             GC_PTR result = (GC_PTR)my_entry;
367             *my_fl = obj_link(my_entry);
368             return result;
369         } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
370             *my_fl = my_entry + index + 1;
371             return GC_malloc_atomic(bytes);
372         } else {
373             GC_generic_malloc_many(BYTES_FROM_INDEX(index), PTRFREE, my_fl);
374             /* *my_fl is updated while the collector is excluded;       */
375             /* the free list is always visible to the collector as      */
376             /* such.                                                    */
377             if (*my_fl == 0) return GC_oom_fn(bytes);
378             return GC_local_malloc_atomic(bytes);
379         }
380     }
381 }
382
383 #ifdef GC_GCJ_SUPPORT
384
385 #include "include/gc_gcj.h"
386
387 #ifdef GC_ASSERTIONS
388   extern GC_bool GC_gcj_malloc_initialized;
389 #endif
390
391 extern int GC_gcj_kind;
392
393 GC_PTR GC_local_gcj_malloc(size_t bytes,
394                            void * ptr_to_struct_containing_descr)
395 {
396     GC_ASSERT(GC_gcj_malloc_initialized);
397     if (EXPECT(!SMALL_ENOUGH(bytes), 0)) {
398         return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
399     } else {
400         int index = INDEX_FROM_BYTES(bytes);
401         ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
402                         -> gcj_freelists + index;
403         ptr_t my_entry = *my_fl;
404         if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
405             GC_PTR result = (GC_PTR)my_entry;
406             GC_ASSERT(!GC_incremental);
407             /* We assert that any concurrent marker will stop us.       */
408             /* Thus it is impossible for a mark procedure to see the    */
409             /* allocation of the next object, but to see this object    */
410             /* still containing a free list pointer.  Otherwise the     */
411             /* marker might find a random "mark descriptor".            */
412             *(volatile ptr_t *)my_fl = obj_link(my_entry);
413             /* We must update the freelist before we store the pointer. */
414             /* Otherwise a GC at this point would see a corrupted       */
415             /* free list.                                               */
416             /* A memory barrier is probably never needed, since the     */
417             /* action of stopping this thread will cause prior writes   */
418             /* to complete.                                             */
419             *(void * volatile *)result = ptr_to_struct_containing_descr; 
420             return result;
421         } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
422             *my_fl = my_entry + index + 1;
423             return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
424         } else {
425             GC_generic_malloc_many(BYTES_FROM_INDEX(index), GC_gcj_kind, my_fl);
426             if (*my_fl == 0) return GC_oom_fn(bytes);
427             return GC_local_gcj_malloc(bytes, ptr_to_struct_containing_descr);
428         }
429     }
430 }
431
432 #endif /* GC_GCJ_SUPPORT */
433
434 # else  /* !THREAD_LOCAL_ALLOC  && !DBG_HDRS_ALL */
435
436 #   define GC_destroy_thread_local(t)
437
438 # endif /* !THREAD_LOCAL_ALLOC */
439
440 /*
441  * We use signals to stop threads during GC.
442  * 
443  * Suspended threads wait in signal handler for SIG_THR_RESTART.
444  * That's more portable than semaphores or condition variables.
445  * (We do use sem_post from a signal handler, but that should be portable.)
446  *
447  * The thread suspension signal SIG_SUSPEND is now defined in gc_priv.h.
448  * Note that we can't just stop a thread; we need it to save its stack
449  * pointer(s) and acknowledge.
450  */
451
452 #ifndef SIG_THR_RESTART
453 #  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
454 #   define SIG_THR_RESTART _SIGRTMIN + 5
455 #  else
456 #   define SIG_THR_RESTART SIGXCPU
457 #  endif
458 #endif
459
460 sem_t GC_suspend_ack_sem;
461
462 #if 0
463 /*
464 To make sure that we're using LinuxThreads and not some other thread
465 package, we generate a dummy reference to `pthread_kill_other_threads_np'
466 (was `__pthread_initial_thread_bos' but that disappeared),
467 which is a symbol defined in LinuxThreads, but (hopefully) not in other
468 thread packages.
469
470 We no longer do this, since this code is now portable enough that it might
471 actually work for something else.
472 */
473 void (*dummy_var_to_force_linux_threads)() = pthread_kill_other_threads_np;
474 #endif /* 0 */
475
476 #if defined(SPARC) || defined(IA64)
477   extern word GC_save_regs_in_stack();
478 #endif
479
480 long GC_nprocs = 1;     /* Number of processors.  We may not have       */
481                         /* access to all of them, but this is as good   */
482                         /* a guess as any ...                           */
483
484 #ifdef PARALLEL_MARK
485
486 # ifndef MAX_MARKERS
487 #   define MAX_MARKERS 16
488 # endif
489
490 static ptr_t marker_sp[MAX_MARKERS] = {0};
491
492 void * GC_mark_thread(void * id)
493 {
494   word my_mark_no = 0;
495
496   marker_sp[(word)id] = GC_approx_sp();
497   for (;; ++my_mark_no) {
498     /* GC_mark_no is passed only to allow GC_help_marker to terminate   */
499     /* promptly.  This is important if it were called from the signal   */
500     /* handler or from the GC lock acquisition code.  Under Linux, it's */
501     /* not safe to call it from a signal handler, since it uses mutexes */
502     /* and condition variables.  Since it is called only here, the      */
503     /* argument is unnecessary.                                         */
504     if (my_mark_no < GC_mark_no || my_mark_no > GC_mark_no + 2) {
505         /* resynchronize if we get far off, e.g. because GC_mark_no     */
506         /* wrapped.                                                     */
507         my_mark_no = GC_mark_no;
508     }
509 #   ifdef DEBUG_THREADS
510         GC_printf1("Starting mark helper for mark number %ld\n", my_mark_no);
511 #   endif
512     GC_help_marker(my_mark_no);
513   }
514 }
515
516 extern long GC_markers;         /* Number of mark threads we would      */
517                                 /* like to have.  Includes the          */
518                                 /* initiating thread.                   */
519
520 pthread_t GC_mark_threads[MAX_MARKERS];
521
522 #define PTHREAD_CREATE REAL_FUNC(pthread_create)
523
524 static void start_mark_threads()
525 {
526     unsigned i;
527     pthread_attr_t attr;
528
529     if (GC_markers > MAX_MARKERS) {
530         WARN("Limiting number of mark threads\n", 0);
531         GC_markers = MAX_MARKERS;
532     }
533     if (0 != pthread_attr_init(&attr)) ABORT("pthread_attr_init failed");
534         
535     if (0 != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
536         ABORT("pthread_attr_setdetachstate failed");
537
538 #   ifdef HPUX
539       /* Default stack size is usually too small: fix it. */
540       /* Otherwise marker threads or GC may run out of    */
541       /* space.                                           */
542 #     define MIN_STACK_SIZE (8*HBLKSIZE*sizeof(word))
543       {
544         size_t old_size;
545         int code;
546
547         if (pthread_attr_getstacksize(&attr, &old_size) != 0)
548           ABORT("pthread_attr_getstacksize failed\n");
549         if (old_size < MIN_STACK_SIZE) {
550           if (pthread_attr_setstacksize(&attr, MIN_STACK_SIZE) != 0)
551             ABORT("pthread_attr_getstacksize failed\n");
552         }
553       }
554 #   endif /* HPUX */
555 #   ifdef CONDPRINT
556       if (GC_print_stats) {
557         GC_printf1("Starting %ld marker threads\n", GC_markers - 1);
558       }
559 #   endif
560     for (i = 0; i < GC_markers - 1; ++i) {
561       if (0 != PTHREAD_CREATE(GC_mark_threads + i, &attr,
562                               GC_mark_thread, (void *)(word)i)) {
563         WARN("Marker thread creation failed, errno = %ld.\n", errno);
564       }
565     }
566 }
567
568 #else  /* !PARALLEL_MARK */
569
570 static __inline__ void start_mark_threads()
571 {
572 }
573
574 #endif /* !PARALLEL_MARK */
575
576 void GC_suspend_handler(int sig)
577 {
578     int dummy;
579     pthread_t my_thread = pthread_self();
580     GC_thread me;
581     sigset_t all_sigs;
582     sigset_t old_sigs;
583     int i;
584     sigset_t mask;
585 #   ifdef PARALLEL_MARK
586         word my_mark_no = GC_mark_no;
587         /* Marker can't proceed until we acknowledge.  Thus this is     */
588         /* guaranteed to be the mark_no correspending to our            */
589         /* suspension, i.e. the marker can't have incremented it yet.   */
590 #   endif
591
592     if (sig != SIG_SUSPEND) ABORT("Bad signal in suspend_handler");
593
594 #if DEBUG_THREADS
595     GC_printf1("Suspending 0x%x\n", my_thread);
596 #endif
597
598     me = GC_lookup_thread(my_thread);
599     /* The lookup here is safe, since I'm doing this on behalf  */
600     /* of a thread which holds the allocation lock in order     */
601     /* to stop the world.  Thus concurrent modification of the  */
602     /* data structure is impossible.                            */
603 #   ifdef SPARC
604         me -> stack_ptr = (ptr_t)GC_save_regs_in_stack();
605 #   else
606         me -> stack_ptr = (ptr_t)(&dummy);
607 #   endif
608 #   ifdef IA64
609         me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack();
610 #   endif
611
612     /* Tell the thread that wants to stop the world that this   */
613     /* thread has been stopped.  Note that sem_post() is        */
614     /* the only async-signal-safe primitive in LinuxThreads.    */
615     sem_post(&GC_suspend_ack_sem);
616
617     /* Wait until that thread tells us to restart by sending    */
618     /* this thread a SIG_THR_RESTART signal.                    */
619     /* SIG_THR_RESTART should be masked at this point.  Thus there      */
620     /* is no race.                                              */
621     if (sigfillset(&mask) != 0) ABORT("sigfillset() failed");
622     if (sigdelset(&mask, SIG_THR_RESTART) != 0) ABORT("sigdelset() failed");
623 #   ifdef NO_SIGNALS
624       if (sigdelset(&mask, SIGINT) != 0) ABORT("sigdelset() failed");
625       if (sigdelset(&mask, SIGQUIT) != 0) ABORT("sigdelset() failed");
626       if (sigdelset(&mask, SIGTERM) != 0) ABORT("sigdelset() failed");
627       if (sigdelset(&mask, SIGABRT) != 0) ABORT("sigdelset() failed");
628 #   endif
629     do {
630             me->signal = 0;
631             sigsuspend(&mask);             /* Wait for signal */
632     } while (me->signal != SIG_THR_RESTART);
633
634 #if DEBUG_THREADS
635     GC_printf1("Continuing 0x%x\n", my_thread);
636 #endif
637 }
638
639 void GC_restart_handler(int sig)
640 {
641     GC_thread me;
642
643     if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler");
644
645     /* Let the GC_suspend_handler() know that we got a SIG_THR_RESTART. */
646     /* The lookup here is safe, since I'm doing this on behalf  */
647     /* of a thread which holds the allocation lock in order     */
648     /* to stop the world.  Thus concurrent modification of the  */
649     /* data structure is impossible.                            */
650     me = GC_lookup_thread(pthread_self());
651     me->signal = SIG_THR_RESTART;
652
653     /*
654     ** Note: even if we didn't do anything useful here,
655     ** it would still be necessary to have a signal handler,
656     ** rather than ignoring the signals, otherwise
657     ** the signals will not be delivered at all, and
658     ** will thus not interrupt the sigsuspend() above.
659     */
660
661 #if DEBUG_THREADS
662     GC_printf1("In GC_restart_handler for 0x%x\n", pthread_self());
663 #endif
664 }
665
666 /* Defining INSTALL_LOOPING_SEGV_HANDLER causes SIGSEGV and SIGBUS to   */
667 /* result in an infinite loop in a signal handler.  This can be very    */
668 /* useful for debugging, since (as of RH7) gdb still seems to have      */
669 /* serious problems with threads.                                       */
670 #ifdef INSTALL_LOOPING_SEGV_HANDLER
671 void GC_looping_handler(int sig)
672 {
673     GC_printf3("Signal %ld in thread %lx, pid %ld\n",
674                sig, pthread_self(), getpid());
675     for (;;);
676 }
677 #endif
678
679 GC_bool GC_thr_initialized = FALSE;
680
681 # define THREAD_TABLE_SZ 128    /* Must be power of 2   */
682 volatile GC_thread GC_threads[THREAD_TABLE_SZ];
683
684 void GC_push_thread_structures GC_PROTO((void))
685 {
686     GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads));
687 }
688
689 #ifdef THREAD_LOCAL_ALLOC
690 /* We must explicitly mark ptrfree and gcj free lists, since the free   */
691 /* list links wouldn't otherwise be found.  We also set them in the     */
692 /* normal free lists, since that involves touching less memory than if  */
693 /* we scanned them normally.                                            */
694 void GC_mark_thread_local_free_lists(void)
695 {
696     int i, j;
697     GC_thread p;
698     ptr_t q;
699     
700     for (i = 0; i < THREAD_TABLE_SZ; ++i) {
701       for (p = GC_threads[i]; 0 != p; p = p -> next) {
702         for (j = 1; j < NFREELISTS; ++j) {
703           q = p -> ptrfree_freelists[j];
704           if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
705           q = p -> normal_freelists[j];
706           if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
707 #         ifdef GC_GCJ_SUPPORT
708             q = p -> gcj_freelists[j];
709             if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
710 #         endif /* GC_GCJ_SUPPORT */
711         }
712       }
713     }
714 }
715 #endif /* THREAD_LOCAL_ALLOC */
716
717 /* Add a thread to GC_threads.  We assume it wasn't already there.      */
718 /* Caller holds allocation lock.                                        */
719 GC_thread GC_new_thread(pthread_t id)
720 {
721     int hv = ((word)id) % THREAD_TABLE_SZ;
722     GC_thread result;
723     static struct GC_Thread_Rep first_thread;
724     static GC_bool first_thread_used = FALSE;
725     
726     if (!first_thread_used) {
727         result = &first_thread;
728         first_thread_used = TRUE;
729     } else {
730         result = (struct GC_Thread_Rep *)
731                  GC_INTERNAL_MALLOC(sizeof(struct GC_Thread_Rep), NORMAL);
732     }
733     if (result == 0) return(0);
734     result -> id = id;
735     result -> next = GC_threads[hv];
736     GC_threads[hv] = result;
737     GC_ASSERT(result -> flags == 0 && result -> thread_blocked == 0);
738     return(result);
739 }
740
741 /* Delete a thread from GC_threads.  We assume it is there.     */
742 /* (The code intentionally traps if it wasn't.)                 */
743 /* Caller holds allocation lock.                                */
744 void GC_delete_thread(pthread_t id)
745 {
746     int hv = ((word)id) % THREAD_TABLE_SZ;
747     register GC_thread p = GC_threads[hv];
748     register GC_thread prev = 0;
749     
750     while (!pthread_equal(p -> id, id)) {
751         prev = p;
752         p = p -> next;
753     }
754     if (prev == 0) {
755         GC_threads[hv] = p -> next;
756     } else {
757         prev -> next = p -> next;
758     }
759     GC_INTERNAL_FREE(p);
760 }
761
762 /* If a thread has been joined, but we have not yet             */
763 /* been notified, then there may be more than one thread        */
764 /* in the table with the same pthread id.                       */
765 /* This is OK, but we need a way to delete a specific one.      */
766 void GC_delete_gc_thread(pthread_t id, GC_thread gc_id)
767 {
768     int hv = ((word)id) % THREAD_TABLE_SZ;
769     register GC_thread p = GC_threads[hv];
770     register GC_thread prev = 0;
771
772     while (p != gc_id) {
773         prev = p;
774         p = p -> next;
775     }
776     if (prev == 0) {
777         GC_threads[hv] = p -> next;
778     } else {
779         prev -> next = p -> next;
780     }
781     GC_INTERNAL_FREE(p);
782 }
783
784 /* Return a GC_thread corresponding to a given thread_t.        */
785 /* Returns 0 if it's not there.                                 */
786 /* Caller holds  allocation lock or otherwise inhibits          */
787 /* updates.                                                     */
788 /* If there is more than one thread with the given id we        */
789 /* return the most recent one.                                  */
790 GC_thread GC_lookup_thread(pthread_t id)
791 {
792     int hv = ((word)id) % THREAD_TABLE_SZ;
793     register GC_thread p = GC_threads[hv];
794     
795     while (p != 0 && !pthread_equal(p -> id, id)) p = p -> next;
796     return(p);
797 }
798
799 /* There seems to be a very rare thread stopping problem.  To help us  */
800 /* debug that, we save the ids of the stopping thread. */
801 pthread_t GC_stopping_thread;
802 int GC_stopping_pid;
803
804 /* Caller holds allocation lock.        */
805 void GC_stop_world()
806 {
807     pthread_t my_thread = pthread_self();
808     register int i;
809     register GC_thread p;
810     register int n_live_threads = 0;
811     register int result;
812
813     GC_stopping_thread = my_thread;    /* debugging only.      */
814     GC_stopping_pid = getpid();                /* debugging only.      */
815     /* Make sure all free list construction has stopped before we start. */
816     /* No new construction can start, since free list construction is   */
817     /* required to acquire and release the GC lock before it starts,    */
818     /* and we have the lock.                                            */
819 #   ifdef PARALLEL_MARK
820       GC_acquire_mark_lock();
821       GC_ASSERT(GC_fl_builder_count == 0);
822       /* We should have previously waited for it to become zero. */
823 #   endif /* PARALLEL_MARK */
824     for (i = 0; i < THREAD_TABLE_SZ; i++) {
825       for (p = GC_threads[i]; p != 0; p = p -> next) {
826         if (p -> id != my_thread) {
827             if (p -> flags & FINISHED) continue;
828             if (p -> thread_blocked) /* Will wait */ continue;
829             n_live_threads++;
830             #if DEBUG_THREADS
831               GC_printf1("Sending suspend signal to 0x%x\n", p -> id);
832             #endif
833             result = pthread_kill(p -> id, SIG_SUSPEND);
834             switch(result) {
835                 case ESRCH:
836                     /* Not really there anymore.  Possible? */
837                     n_live_threads--;
838                     break;
839                 case 0:
840                     break;
841                 default:
842                     ABORT("pthread_kill failed");
843             }
844         }
845       }
846     }
847     for (i = 0; i < n_live_threads; i++) {
848         if (0 != sem_wait(&GC_suspend_ack_sem))
849             ABORT("sem_wait in handler failed");
850     }
851 #   ifdef PARALLEL_MARK
852       GC_release_mark_lock();
853 #   endif
854     #if DEBUG_THREADS
855       GC_printf1("World stopped 0x%x\n", pthread_self());
856     #endif
857     GC_stopping_thread = 0;  /* debugging only */
858 }
859
860 /* Caller holds allocation lock, and has held it continuously since     */
861 /* the world stopped.                                                   */
862 void GC_start_world()
863 {
864     pthread_t my_thread = pthread_self();
865     register int i;
866     register GC_thread p;
867     register int n_live_threads = 0;
868     register int result;
869     
870 #   if DEBUG_THREADS
871       GC_printf0("World starting\n");
872 #   endif
873
874     for (i = 0; i < THREAD_TABLE_SZ; i++) {
875       for (p = GC_threads[i]; p != 0; p = p -> next) {
876         if (p -> id != my_thread) {
877             if (p -> flags & FINISHED) continue;
878             if (p -> thread_blocked) continue;
879             n_live_threads++;
880             #if DEBUG_THREADS
881               GC_printf1("Sending restart signal to 0x%x\n", p -> id);
882             #endif
883             result = pthread_kill(p -> id, SIG_THR_RESTART);
884             switch(result) {
885                 case ESRCH:
886                     /* Not really there anymore.  Possible? */
887                     n_live_threads--;
888                     break;
889                 case 0:
890                     break;
891                 default:
892                     ABORT("pthread_kill failed");
893             }
894         }
895       }
896     }
897     #if DEBUG_THREADS
898       GC_printf0("World started\n");
899     #endif
900     GC_stopping_thread = 0;  /* debugging only */
901 }
902
903 # ifdef IA64
904 #   define IF_IA64(x) x
905 # else
906 #   define IF_IA64(x)
907 # endif
908 /* We hold allocation lock.  Should do exactly the right thing if the   */
909 /* world is stopped.  Should not fail if it isn't.                      */
910 void GC_push_all_stacks()
911 {
912     int i;
913     GC_thread p;
914     ptr_t sp = GC_approx_sp();
915     ptr_t lo, hi;
916     /* On IA64, we also need to scan the register backing store. */
917     IF_IA64(ptr_t bs_lo; ptr_t bs_hi;)
918     pthread_t me = pthread_self();
919     
920     if (!GC_thr_initialized) GC_thr_init();
921     #if DEBUG_THREADS
922         GC_printf1("Pushing stacks from thread 0x%lx\n", (unsigned long) me);
923     #endif
924     for (i = 0; i < THREAD_TABLE_SZ; i++) {
925       for (p = GC_threads[i]; p != 0; p = p -> next) {
926         if (p -> flags & FINISHED) continue;
927         if (pthread_equal(p -> id, me)) {
928 #           ifdef SPARC
929                 lo = (ptr_t)GC_save_regs_in_stack();
930 #           else
931                 lo = GC_approx_sp();
932 #           endif
933             IF_IA64(bs_hi = (ptr_t)GC_save_regs_in_stack();)
934         } else {
935             lo = p -> stack_ptr;
936             IF_IA64(bs_hi = p -> backing_store_ptr;)
937         }
938         if ((p -> flags & MAIN_THREAD) == 0) {
939             hi = p -> stack_end;
940             IF_IA64(bs_lo = p -> backing_store_end);
941         } else {
942             /* The original stack. */
943             hi = GC_stackbottom;
944             IF_IA64(bs_lo = BACKING_STORE_BASE;)
945         }
946         #if DEBUG_THREADS
947             GC_printf3("Stack for thread 0x%lx = [%lx,%lx)\n",
948                 (unsigned long) p -> id,
949                 (unsigned long) lo, (unsigned long) hi);
950         #endif
951         if (0 == lo) ABORT("GC_push_all_stacks: sp not set!\n");
952 #       ifdef STACK_GROWS_UP
953           /* We got them backwards! */
954           GC_push_all_stack(hi, lo);
955 #       else
956           GC_push_all_stack(lo, hi);
957 #       endif
958 #       ifdef IA64
959           if (pthread_equal(p -> id, me)) {
960             GC_push_all_eager(bs_lo, bs_hi);
961           } else {
962             GC_push_all_stack(bs_lo, bs_hi);
963           }
964 #       endif
965       }
966     }
967 }
968
969 #ifdef USE_PROC_FOR_LIBRARIES
970 int GC_segment_is_thread_stack(ptr_t lo, ptr_t hi)
971 {
972     int i;
973     GC_thread p;
974     
975 #   ifdef PARALLEL_MARK
976       for (i = 0; i < GC_markers; ++i) {
977         if (marker_sp[i] > lo & marker_sp[i] < hi) return 1;
978       }
979 #   endif
980     for (i = 0; i < THREAD_TABLE_SZ; i++) {
981       for (p = GC_threads[i]; p != 0; p = p -> next) {
982         if (0 != p -> stack_end) {
983 #         ifdef STACK_GROWS_UP
984             if (p -> stack_end >= lo && p -> stack_end < hi) return 1;
985 #         else /* STACK_GROWS_DOWN */
986             if (p -> stack_end > lo && p -> stack_end <= hi) return 1;
987 #         endif
988         }
989       }
990     }
991     return 0;
992 }
993 #endif /* USE_PROC_FOR_LIBRARIES */
994
995 #ifdef GC_LINUX_THREADS
996 /* Return the number of processors, or i<= 0 if it can't be determined. */
997 int GC_get_nprocs()
998 {
999     /* Should be "return sysconf(_SC_NPROCESSORS_ONLN);" but that       */
1000     /* appears to be buggy in many cases.                               */
1001     /* We look for lines "cpu<n>" in /proc/stat.                        */
1002 #   define STAT_BUF_SIZE 4096
1003 #   if defined(GC_USE_LD_WRAP)
1004 #       define STAT_READ __real_read
1005 #   else
1006 #       define STAT_READ read
1007 #   endif    
1008     char stat_buf[STAT_BUF_SIZE];
1009     int f;
1010     char c;
1011     word result = 1;
1012         /* Some old kernels only have a single "cpu nnnn ..."   */
1013         /* entry in /proc/stat.  We identify those as           */
1014         /* uniprocessors.                                       */
1015     size_t i, len = 0;
1016
1017     f = open("/proc/stat", O_RDONLY);
1018     if (f < 0 || (len = STAT_READ(f, stat_buf, STAT_BUF_SIZE)) < 100) {
1019         WARN("Couldn't read /proc/stat\n", 0);
1020         return -1;
1021     }
1022     for (i = 0; i < len - 100; ++i) {
1023         if (stat_buf[i] == '\n' && stat_buf[i+1] == 'c'
1024             && stat_buf[i+2] == 'p' && stat_buf[i+3] == 'u') {
1025             int cpu_no = atoi(stat_buf + i + 4);
1026             if (cpu_no >= result) result = cpu_no + 1;
1027         }
1028     }
1029     return result;
1030 }
1031 #endif /* GC_LINUX_THREADS */
1032
1033 /* We hold the allocation lock. */
1034 void GC_thr_init()
1035 {
1036     int dummy;
1037     GC_thread t;
1038     struct sigaction act;
1039
1040     if (GC_thr_initialized) return;
1041     GC_thr_initialized = TRUE;
1042
1043     if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
1044         ABORT("sem_init failed");
1045
1046     act.sa_flags = SA_RESTART;
1047     if (sigfillset(&act.sa_mask) != 0) {
1048         ABORT("sigfillset() failed");
1049     }
1050 #   ifdef NO_SIGNALS
1051       if (sigdelset(&act.sa_mask, SIGINT) != 0
1052           || sigdelset(&act.sa_mask, SIGQUIT != 0)
1053           || sigdelset(&act.sa_mask, SIGABRT != 0)
1054           || sigdelset(&act.sa_mask, SIGTERM != 0)) {
1055         ABORT("sigdelset() failed");
1056       }
1057 #   endif
1058
1059     /* SIG_THR_RESTART is unmasked by the handler when necessary.       */
1060     act.sa_handler = GC_suspend_handler;
1061     if (sigaction(SIG_SUSPEND, &act, NULL) != 0) {
1062         ABORT("Cannot set SIG_SUSPEND handler");
1063     }
1064
1065     act.sa_handler = GC_restart_handler;
1066     if (sigaction(SIG_THR_RESTART, &act, NULL) != 0) {
1067         ABORT("Cannot set SIG_THR_RESTART handler");
1068     }
1069 #   ifdef INSTALL_LOOPING_SEGV_HANDLER
1070         act.sa_handler = GC_looping_handler;
1071         if (sigaction(SIGSEGV, &act, NULL) != 0
1072             || sigaction(SIGBUS, &act, NULL) != 0) {
1073             ABORT("Cannot set SIGSEGV or SIGBUS looping handler");
1074         }
1075 #   endif  /* INSTALL_LOOPING_SEGV_HANDLER */
1076
1077     /* Add the initial thread, so we can stop it.       */
1078       t = GC_new_thread(pthread_self());
1079       t -> stack_ptr = (ptr_t)(&dummy);
1080       t -> flags = DETACHED | MAIN_THREAD;
1081
1082     /* Set GC_nprocs.  */
1083       {
1084         char * nprocs_string = GETENV("GC_NPROCS");
1085         GC_nprocs = -1;
1086         if (nprocs_string != NULL) GC_nprocs = atoi(nprocs_string);
1087       }
1088       if (GC_nprocs <= 0) {
1089 #       if defined(GC_HPUX_THREADS)
1090           GC_nprocs = pthread_num_processors_np();
1091 #       endif
1092 #       if defined(GC_OSF1_THREADS) || defined(GC_FREEBSD_THREADS)
1093           GC_nprocs = 1;
1094 #       endif
1095 #       if defined(GC_LINUX_THREADS)
1096           GC_nprocs = GC_get_nprocs();
1097 #       endif
1098       }
1099       if (GC_nprocs <= 0) {
1100         WARN("GC_get_nprocs() returned %ld\n", GC_nprocs);
1101         GC_nprocs = 2;
1102 #       ifdef PARALLEL_MARK
1103           GC_markers = 1;
1104 #       endif
1105       } else {
1106 #       ifdef PARALLEL_MARK
1107           GC_markers = GC_nprocs;
1108 #       endif
1109       }
1110 #   ifdef PARALLEL_MARK
1111 #     ifdef CONDPRINT
1112         if (GC_print_stats) {
1113           GC_printf2("Number of processors = %ld, "
1114                  "number of marker threads = %ld\n", GC_nprocs, GC_markers);
1115         }
1116 #     endif
1117       if (GC_markers == 1) {
1118         GC_parallel = FALSE;
1119 #       ifdef CONDPRINT
1120           if (GC_print_stats) {
1121             GC_printf0("Single marker thread, turning off parallel marking\n");
1122           }
1123 #       endif
1124       } else {
1125         GC_parallel = TRUE;
1126       }
1127 #   endif
1128 }
1129
1130
1131 /* Perform all initializations, including those that    */
1132 /* may require allocation.                              */
1133 /* Called as constructor without allocation lock.       */
1134 /* Must be called before a second thread is created.    */
1135 /* Called without allocation lock.                      */
1136 void GC_init_parallel()
1137 {
1138     if (parallel_initialized) return;
1139     parallel_initialized = TRUE;
1140         /* GC_init() calls us back, so set flag first.  */
1141     if (!GC_is_initialized) GC_init();
1142     /* If we are using a parallel marker, start the helper threads.  */
1143 #     ifdef PARALLEL_MARK
1144         if (GC_parallel) start_mark_threads();
1145 #     endif
1146     /* Initialize thread local free lists if used.      */
1147 #   if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
1148       LOCK();
1149       GC_init_thread_local(GC_lookup_thread(pthread_self()));
1150       UNLOCK();
1151 #   endif
1152 }
1153
1154
1155 int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset)
1156 {
1157     sigset_t fudged_set;
1158     
1159     if (set != NULL && (how == SIG_BLOCK || how == SIG_SETMASK)) {
1160         fudged_set = *set;
1161         sigdelset(&fudged_set, SIG_SUSPEND);
1162         set = &fudged_set;
1163     }
1164     return(REAL_FUNC(pthread_sigmask)(how, set, oset));
1165 }
1166
1167 /* Wrappers for functions that are likely to block for an appreciable   */
1168 /* length of time.  Must be called in pairs, if at all.                 */
1169 /* Nothing much beyond the system call itself should be executed        */
1170 /* between these.                                                       */
1171
1172 void GC_start_blocking(void) {
1173 #   define SP_SLOP 128
1174     GC_thread me;
1175     LOCK();
1176     me = GC_lookup_thread(pthread_self());
1177     GC_ASSERT(!(me -> thread_blocked));
1178 #   ifdef SPARC
1179         me -> stack_ptr = (ptr_t)GC_save_regs_in_stack();
1180 #   else
1181         me -> stack_ptr = (ptr_t)GC_approx_sp();
1182 #   endif
1183 #   ifdef IA64
1184         me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack() + SP_SLOP;
1185 #   endif
1186     /* Add some slop to the stack pointer, since the wrapped call may   */
1187     /* end up pushing more callee-save registers.                       */
1188 #   ifdef STACK_GROWS_UP
1189         me -> stack_ptr += SP_SLOP;
1190 #   else
1191         me -> stack_ptr -= SP_SLOP;
1192 #   endif
1193     me -> thread_blocked = TRUE;
1194     UNLOCK();
1195 }
1196
1197 GC_end_blocking(void) {
1198     GC_thread me;
1199     LOCK();   /* This will block if the world is stopped.       */
1200     me = GC_lookup_thread(pthread_self());
1201     GC_ASSERT(me -> thread_blocked);
1202     me -> thread_blocked = FALSE;
1203     UNLOCK();
1204 }
1205     
1206 /* A wrapper for the standard C sleep function  */
1207 int WRAP_FUNC(sleep) (unsigned int seconds)
1208 {
1209     int result;
1210
1211     GC_start_blocking();
1212     result = REAL_FUNC(sleep)(seconds);
1213     GC_end_blocking();
1214     return result;
1215 }
1216
1217 struct start_info {
1218     void *(*start_routine)(void *);
1219     void *arg;
1220     word flags;
1221     sem_t registered;           /* 1 ==> in our thread table, but       */
1222                                 /* parent hasn't yet noticed.           */
1223 };
1224
1225 /* Called at thread exit.                               */
1226 /* Never called for main thread.  That's OK, since it   */
1227 /* results in at most a tiny one-time leak.  And        */
1228 /* linuxthreads doesn't reclaim the main threads        */
1229 /* resources or id anyway.                              */
1230 void GC_thread_exit_proc(void *arg)
1231 {
1232     GC_thread me;
1233
1234     LOCK();
1235     me = GC_lookup_thread(pthread_self());
1236     GC_destroy_thread_local(me);
1237     if (me -> flags & DETACHED) {
1238         GC_delete_thread(pthread_self());
1239     } else {
1240         me -> flags |= FINISHED;
1241     }
1242 #   if defined(THREAD_LOCAL_ALLOC) && !defined(USE_PTHREAD_SPECIFIC) \
1243        && !defined(USE_HPUX_TLS) && !defined(DBG_HDRS_ALL)
1244       GC_remove_specific(GC_thread_key);
1245 #   endif
1246     if (GC_incremental && GC_collection_in_progress()) {
1247         int old_gc_no = GC_gc_no;
1248
1249         /* Make sure that no part of our stack is still on the mark stack, */
1250         /* since it's about to be unmapped.                                */
1251         while (GC_incremental && GC_collection_in_progress()
1252                && old_gc_no == GC_gc_no) {
1253             ENTER_GC();
1254             GC_collect_a_little_inner(1);
1255             EXIT_GC();
1256             UNLOCK();
1257             sched_yield();
1258             LOCK();
1259         }
1260     }
1261     UNLOCK();
1262 }
1263
1264 int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval)
1265 {
1266     int result;
1267     GC_thread thread_gc_id;
1268     
1269     LOCK();
1270     thread_gc_id = GC_lookup_thread(thread);
1271     /* This is guaranteed to be the intended one, since the thread id   */
1272     /* cant have been recycled by pthreads.                             */
1273     UNLOCK();
1274     result = REAL_FUNC(pthread_join)(thread, retval);
1275 # if defined (GC_FREEBSD_THREADS)
1276     /* On FreeBSD, the wrapped pthread_join() sometimes returns (what
1277        appears to be) a spurious EINTR which caused the test and real code
1278        to gratuitously fail.  Having looked at system pthread library source
1279        code, I see how this return code may be generated.  In one path of
1280        code, pthread_join() just returns the errno setting of the thread
1281        being joined.  This does not match the POSIX specification or the
1282        local man pages thus I have taken the liberty to catch this one
1283        spurious return value properly conditionalized on GC_FREEBSD_THREADS. */
1284     if (result == EINTR) result = 0;
1285 # endif
1286     if (result == 0) {
1287         LOCK();
1288         /* Here the pthread thread id may have been recycled. */
1289         GC_delete_gc_thread(thread, thread_gc_id);
1290         UNLOCK();
1291     }
1292     return result;
1293 }
1294
1295 int
1296 WRAP_FUNC(pthread_detach)(pthread_t thread)
1297 {
1298     int result;
1299     GC_thread thread_gc_id;
1300     
1301     LOCK();
1302     thread_gc_id = GC_lookup_thread(thread);
1303     UNLOCK();
1304     result = REAL_FUNC(pthread_detach)(thread);
1305     if (result == 0) {
1306       LOCK();
1307       thread_gc_id -> flags |= DETACHED;
1308       /* Here the pthread thread id may have been recycled. */
1309       if (thread_gc_id -> flags & FINISHED) {
1310         GC_delete_gc_thread(thread, thread_gc_id);
1311       }
1312       UNLOCK();
1313     }
1314     return result;
1315 }
1316
1317 void * GC_start_routine(void * arg)
1318 {
1319     int dummy;
1320     struct start_info * si = arg;
1321     void * result;
1322     GC_thread me;
1323     pthread_t my_pthread;
1324     void *(*start)(void *);
1325     void *start_arg;
1326
1327     my_pthread = pthread_self();
1328 #   ifdef DEBUG_THREADS
1329         GC_printf1("Starting thread 0x%lx\n", my_pthread);
1330         GC_printf1("pid = %ld\n", (long) getpid());
1331         GC_printf1("sp = 0x%lx\n", (long) &arg);
1332 #   endif
1333     LOCK();
1334     me = GC_new_thread(my_pthread);
1335     me -> flags = si -> flags;
1336     me -> stack_ptr = 0;
1337     /* me -> stack_end = GC_linux_stack_base(); -- currently (11/99)    */
1338     /* doesn't work because the stack base in /proc/self/stat is the    */
1339     /* one for the main thread.  There is a strong argument that that's */
1340     /* a kernel bug, but a pervasive one.                               */
1341 #   ifdef STACK_GROWS_DOWN
1342       me -> stack_end = (ptr_t)(((word)(&dummy) + (GC_page_size - 1))
1343                                 & ~(GC_page_size - 1));
1344       me -> stack_ptr = me -> stack_end - 0x10;
1345         /* Needs to be plausible, since an asynchronous stack mark      */
1346         /* should not crash.                                            */
1347 #   else
1348       me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1));
1349       me -> stack_ptr = me -> stack_end + 0x10;
1350 #   endif
1351     /* This is dubious, since we may be more than a page into the stack, */
1352     /* and hence skip some of it, though it's not clear that matters.    */
1353 #   ifdef IA64
1354       me -> backing_store_end = (ptr_t)
1355                         (GC_save_regs_in_stack() & ~(GC_page_size - 1));
1356       /* This is also < 100% convincing.  We should also read this      */
1357       /* from /proc, but the hook to do so isn't there yet.             */
1358 #   endif /* IA64 */
1359     UNLOCK();
1360     start = si -> start_routine;
1361 #   ifdef DEBUG_THREADS
1362         GC_printf1("start_routine = 0x%lx\n", start);
1363 #   endif
1364     start_arg = si -> arg;
1365     sem_post(&(si -> registered));      /* Last action on si.   */
1366                                         /* OK to deallocate.    */
1367     pthread_cleanup_push(GC_thread_exit_proc, 0);
1368 #   if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
1369         LOCK();
1370         GC_init_thread_local(me);
1371         UNLOCK();
1372 #   endif
1373     result = (*start)(start_arg);
1374 #if DEBUG_THREADS
1375         GC_printf1("Finishing thread 0x%x\n", pthread_self());
1376 #endif
1377     me -> status = result;
1378     me -> flags |= FINISHED;
1379     pthread_cleanup_pop(1);
1380     /* Cleanup acquires lock, ensuring that we can't exit               */
1381     /* while a collection that thinks we're alive is trying to stop     */
1382     /* us.                                                              */
1383     return(result);
1384 }
1385
1386 int
1387 WRAP_FUNC(pthread_create)(pthread_t *new_thread,
1388                   const pthread_attr_t *attr,
1389                   void *(*start_routine)(void *), void *arg)
1390 {
1391     int result;
1392     GC_thread t;
1393     pthread_t my_new_thread;
1394     int detachstate;
1395     word my_flags = 0;
1396     struct start_info * si; 
1397         /* This is otherwise saved only in an area mmapped by the thread */
1398         /* library, which isn't visible to the collector.                */
1399  
1400     LOCK();
1401     si = (struct start_info *)GC_INTERNAL_MALLOC(sizeof(struct start_info), NORMAL);
1402     UNLOCK();
1403     if (!parallel_initialized) GC_init_parallel();
1404     if (0 == si) return(ENOMEM);
1405     sem_init(&(si -> registered), 0, 0);
1406     si -> start_routine = start_routine;
1407     si -> arg = arg;
1408     LOCK();
1409     if (!GC_thr_initialized) GC_thr_init();
1410     if (NULL == attr) {
1411         detachstate = PTHREAD_CREATE_JOINABLE;
1412     } else {
1413         pthread_attr_getdetachstate(attr, &detachstate);
1414     }
1415     if (PTHREAD_CREATE_DETACHED == detachstate) my_flags |= DETACHED;
1416     si -> flags = my_flags;
1417     UNLOCK();
1418 #   ifdef DEBUG_THREADS
1419         GC_printf1("About to start new thread from thread 0x%X\n",
1420                    pthread_self());
1421 #   endif
1422     result = REAL_FUNC(pthread_create)(new_thread, attr, GC_start_routine, si);
1423 #   ifdef DEBUG_THREADS
1424         GC_printf1("Started thread 0x%X\n", *new_thread);
1425 #   endif
1426     /* Wait until child has been added to the thread table.             */
1427     /* This also ensures that we hold onto si until the child is done   */
1428     /* with it.  Thus it doesn't matter whether it is otherwise         */
1429     /* visible to the collector.                                        */
1430         while (0 != sem_wait(&(si -> registered))) {
1431             if (EINTR != errno) ABORT("sem_wait failed");
1432         }
1433         sem_destroy(&(si -> registered));
1434         LOCK();
1435         GC_INTERNAL_FREE(si);
1436         UNLOCK();
1437     return(result);
1438 }
1439
1440 #ifdef GENERIC_COMPARE_AND_SWAP
1441   pthread_mutex_t GC_compare_and_swap_lock = PTHREAD_MUTEX_INITIALIZER;
1442
1443   GC_bool GC_compare_and_exchange(volatile GC_word *addr,
1444                                   GC_word old, GC_word new_val)
1445   {
1446     GC_bool result;
1447     pthread_mutex_lock(&GC_compare_and_swap_lock);
1448     if (*addr == old) {
1449       *addr = new_val;
1450       result = TRUE;
1451     } else {
1452       result = FALSE;
1453     }
1454     pthread_mutex_unlock(&GC_compare_and_swap_lock);
1455     return result;
1456   }
1457   
1458   GC_word GC_atomic_add(volatile GC_word *addr, GC_word how_much)
1459   {
1460     GC_word old;
1461     pthread_mutex_lock(&GC_compare_and_swap_lock);
1462     old = *addr;
1463     *addr = old + how_much;
1464     pthread_mutex_unlock(&GC_compare_and_swap_lock);
1465     return old;
1466   }
1467
1468 #endif /* GENERIC_COMPARE_AND_SWAP */
1469 /* Spend a few cycles in a way that can't introduce contention with     */
1470 /* othre threads.                                                       */
1471 void GC_pause()
1472 {
1473     int i;
1474     volatile word dummy = 0;
1475
1476     for (i = 0; i < 10; ++i) { 
1477 #     ifdef __GNUC__
1478         __asm__ __volatile__ (" " : : : "memory");
1479 #     else
1480         /* Something that's unlikely to be optimized away. */
1481         GC_noop(++dummy);
1482 #     endif
1483     }
1484 }
1485     
1486 #define SPIN_MAX 1024   /* Maximum number of calls to GC_pause before   */
1487                         /* give up.                                     */
1488
1489 VOLATILE GC_bool GC_collecting = 0;
1490                         /* A hint that we're in the collector and       */
1491                         /* holding the allocation lock for an           */
1492                         /* extended period.                             */
1493
1494 #if !defined(USE_SPIN_LOCK) || defined(PARALLEL_MARK)
1495 /* If we don't want to use the below spinlock implementation, either    */
1496 /* because we don't have a GC_test_and_set implementation, or because   */
1497 /* we don't want to risk sleeping, we can still try spinning on         */
1498 /* pthread_mutex_trylock for a while.  This appears to be very          */
1499 /* beneficial in many cases.                                            */
1500 /* I suspect that under high contention this is nearly always better    */
1501 /* than the spin lock.  But it's a bit slower on a uniprocessor.        */
1502 /* Hence we still default to the spin lock.                             */
1503 /* This is also used to acquire the mark lock for the parallel          */
1504 /* marker.                                                              */
1505
1506 /* Here we use a strict exponential backoff scheme.  I don't know       */
1507 /* whether that's better or worse than the above.  We eventually        */
1508 /* yield by calling pthread_mutex_lock(); it never makes sense to       */
1509 /* explicitly sleep.                                                    */
1510
1511 void GC_generic_lock(pthread_mutex_t * lock)
1512 {
1513     unsigned pause_length = 1;
1514     unsigned i;
1515     
1516     if (0 == pthread_mutex_trylock(lock)) return;
1517     for (; pause_length <= SPIN_MAX; pause_length <<= 1) {
1518         for (i = 0; i < pause_length; ++i) {
1519             GC_pause();
1520         }
1521         switch(pthread_mutex_trylock(lock)) {
1522             case 0:
1523                 return;
1524             case EBUSY:
1525                 break;
1526             default:
1527                 ABORT("Unexpected error from pthread_mutex_trylock");
1528         }
1529     }
1530     pthread_mutex_lock(lock);
1531 }
1532
1533 #endif /* !USE_SPIN_LOCK || PARALLEL_MARK */
1534
1535 #if defined(USE_SPIN_LOCK)
1536
1537 /* Reasonably fast spin locks.  Basically the same implementation */
1538 /* as STL alloc.h.  This isn't really the right way to do this.   */
1539 /* but until the POSIX scheduling mess gets straightened out ...  */
1540
1541 volatile unsigned int GC_allocate_lock = 0;
1542
1543
1544 void GC_lock()
1545 {
1546 #   define low_spin_max 30  /* spin cycles if we suspect uniprocessor */
1547 #   define high_spin_max SPIN_MAX /* spin cycles for multiprocessor */
1548     static unsigned spin_max = low_spin_max;
1549     unsigned my_spin_max;
1550     static unsigned last_spins = 0;
1551     unsigned my_last_spins;
1552     int i;
1553
1554     if (!GC_test_and_set(&GC_allocate_lock)) {
1555         return;
1556     }
1557     my_spin_max = spin_max;
1558     my_last_spins = last_spins;
1559     for (i = 0; i < my_spin_max; i++) {
1560         if (GC_collecting || GC_nprocs == 1) goto yield;
1561         if (i < my_last_spins/2 || GC_allocate_lock) {
1562             GC_pause();
1563             continue;
1564         }
1565         if (!GC_test_and_set(&GC_allocate_lock)) {
1566             /*
1567              * got it!
1568              * Spinning worked.  Thus we're probably not being scheduled
1569              * against the other process with which we were contending.
1570              * Thus it makes sense to spin longer the next time.
1571              */
1572             last_spins = i;
1573             spin_max = high_spin_max;
1574             return;
1575         }
1576     }
1577     /* We are probably being scheduled against the other process.  Sleep. */
1578     spin_max = low_spin_max;
1579 yield:
1580     for (i = 0;; ++i) {
1581         if (!GC_test_and_set(&GC_allocate_lock)) {
1582             return;
1583         }
1584 #       define SLEEP_THRESHOLD 12
1585                 /* nanosleep(<= 2ms) just spins under Linux.  We        */
1586                 /* want to be careful to avoid that behavior.           */
1587         if (i < SLEEP_THRESHOLD) {
1588             sched_yield();
1589         } else {
1590             struct timespec ts;
1591         
1592             if (i > 24) i = 24;
1593                         /* Don't wait for more than about 15msecs, even */
1594                         /* under extreme contention.                    */
1595             ts.tv_sec = 0;
1596             ts.tv_nsec = 1 << i;
1597             nanosleep(&ts, 0);
1598         }
1599     }
1600 }
1601
1602 #else  /* !USE_SPINLOCK */
1603
1604 void GC_lock()
1605 {
1606     if (1 == GC_nprocs || GC_collecting) {
1607         pthread_mutex_lock(&GC_allocate_ml);
1608     } else {
1609         GC_generic_lock(&GC_allocate_ml);
1610     }
1611 }
1612
1613 #endif /* !USE_SPINLOCK */
1614
1615 #if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
1616
1617 #ifdef GC_ASSERTIONS
1618   pthread_t GC_mark_lock_holder = NO_THREAD;
1619 #endif
1620
1621 #if 0
1622   /* Ugly workaround for a linux threads bug in the final versions      */
1623   /* of glibc2.1.  Pthread_mutex_trylock sets the mutex owner           */
1624   /* field even when it fails to acquire the mutex.  This causes        */
1625   /* pthread_cond_wait to die.  Remove for glibc2.2.                    */
1626   /* According to the man page, we should use                           */
1627   /* PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, but that isn't actually   */
1628   /* defined.                                                           */
1629   static pthread_mutex_t mark_mutex =
1630         {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}};
1631 #else
1632   static pthread_mutex_t mark_mutex = PTHREAD_MUTEX_INITIALIZER;
1633 #endif
1634
1635 static pthread_cond_t builder_cv = PTHREAD_COND_INITIALIZER;
1636
1637 void GC_acquire_mark_lock()
1638 {
1639 /*
1640     if (pthread_mutex_lock(&mark_mutex) != 0) {
1641         ABORT("pthread_mutex_lock failed");
1642     }
1643 */
1644     GC_generic_lock(&mark_mutex);
1645 #   ifdef GC_ASSERTIONS
1646         GC_mark_lock_holder = pthread_self();
1647 #   endif
1648 }
1649
1650 void GC_release_mark_lock()
1651 {
1652     GC_ASSERT(GC_mark_lock_holder == pthread_self());
1653 #   ifdef GC_ASSERTIONS
1654         GC_mark_lock_holder = NO_THREAD;
1655 #   endif
1656     if (pthread_mutex_unlock(&mark_mutex) != 0) {
1657         ABORT("pthread_mutex_unlock failed");
1658     }
1659 }
1660
1661 /* Collector must wait for a freelist builders for 2 reasons:           */
1662 /* 1) Mark bits may still be getting examined without lock.             */
1663 /* 2) Partial free lists referenced only by locals may not be scanned   */
1664 /*    correctly, e.g. if they contain "pointer-free" objects, since the */
1665 /*    free-list link may be ignored.                                    */
1666 void GC_wait_builder()
1667 {
1668     GC_ASSERT(GC_mark_lock_holder == pthread_self());
1669 #   ifdef GC_ASSERTIONS
1670         GC_mark_lock_holder = NO_THREAD;
1671 #   endif
1672     if (pthread_cond_wait(&builder_cv, &mark_mutex) != 0) {
1673         ABORT("pthread_cond_wait failed");
1674     }
1675     GC_ASSERT(GC_mark_lock_holder == NO_THREAD);
1676 #   ifdef GC_ASSERTIONS
1677         GC_mark_lock_holder = pthread_self();
1678 #   endif
1679 }
1680
1681 void GC_wait_for_reclaim()
1682 {
1683     GC_acquire_mark_lock();
1684     while (GC_fl_builder_count > 0) {
1685         GC_wait_builder();
1686     }
1687     GC_release_mark_lock();
1688 }
1689
1690 void GC_notify_all_builder()
1691 {
1692     GC_ASSERT(GC_mark_lock_holder == pthread_self());
1693     if (pthread_cond_broadcast(&builder_cv) != 0) {
1694         ABORT("pthread_cond_broadcast failed");
1695     }
1696 }
1697
1698 #endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */
1699
1700 #ifdef PARALLEL_MARK
1701
1702 static pthread_cond_t mark_cv = PTHREAD_COND_INITIALIZER;
1703
1704 void GC_wait_marker()
1705 {
1706     GC_ASSERT(GC_mark_lock_holder == pthread_self());
1707 #   ifdef GC_ASSERTIONS
1708         GC_mark_lock_holder = NO_THREAD;
1709 #   endif
1710     if (pthread_cond_wait(&mark_cv, &mark_mutex) != 0) {
1711         ABORT("pthread_cond_wait failed");
1712     }
1713     GC_ASSERT(GC_mark_lock_holder == NO_THREAD);
1714 #   ifdef GC_ASSERTIONS
1715         GC_mark_lock_holder = pthread_self();
1716 #   endif
1717 }
1718
1719 void GC_notify_all_marker()
1720 {
1721     if (pthread_cond_broadcast(&mark_cv) != 0) {
1722         ABORT("pthread_cond_broadcast failed");
1723     }
1724 }
1725
1726 #endif /* PARALLEL_MARK */
1727
1728 # endif /* GC_LINUX_THREADS and friends */
1729