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