]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef GC_PTHREAD_SUPPORT_H |
2 | #define GC_PTHREAD_SUPPORT_H | |
3 | ||
4 | # include "private/gc_priv.h" | |
5 | ||
6 | # if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) | |
7 | ||
8 | #if defined(GC_DARWIN_THREADS) | |
9 | # include "private/darwin_stop_world.h" | |
10 | #else | |
11 | # include "private/pthread_stop_world.h" | |
12 | #endif | |
13 | ||
14 | #ifdef THREAD_LOCAL_ALLOC | |
15 | # include "thread_local_alloc.h" | |
16 | #endif /* THREAD_LOCAL_ALLOC */ | |
17 | ||
18 | /* We use the allocation lock to protect thread-related data structures. */ | |
19 | ||
20 | /* The set of all known threads. We intercept thread creation and */ | |
21 | /* joins. */ | |
22 | /* Protected by allocation/GC lock. */ | |
23 | /* Some of this should be declared volatile, but that's inconsistent */ | |
24 | /* with some library routine declarations. */ | |
25 | typedef struct GC_Thread_Rep { | |
26 | struct GC_Thread_Rep * next; /* More recently allocated threads */ | |
27 | /* with a given pthread id come */ | |
28 | /* first. (All but the first are */ | |
29 | /* guaranteed to be dead, but we may */ | |
30 | /* not yet have registered the join.) */ | |
31 | pthread_t id; | |
32 | /* Extra bookkeeping information the stopping code uses */ | |
33 | struct thread_stop_info stop_info; | |
34 | ||
35 | short flags; | |
36 | # define FINISHED 1 /* Thread has exited. */ | |
37 | # define DETACHED 2 /* Thread is treated as detached. */ | |
38 | /* Thread may really be detached, or */ | |
39 | /* it may have have been explicitly */ | |
40 | /* registered, in which case we can */ | |
41 | /* deallocate its GC_Thread_Rep once */ | |
42 | /* it unregisters itself, since it */ | |
43 | /* may not return a GC pointer. */ | |
44 | # define MAIN_THREAD 4 /* True for the original thread only. */ | |
45 | short thread_blocked; /* Protected by GC lock. */ | |
46 | /* Treated as a boolean value. If set, */ | |
47 | /* thread will acquire GC lock before */ | |
48 | /* doing any pointer manipulations, and */ | |
49 | /* has set its sp value. Thus it does */ | |
50 | /* not need to be sent a signal to stop */ | |
51 | /* it. */ | |
52 | ptr_t stack_end; /* Cold end of the stack. */ | |
53 | # ifdef IA64 | |
54 | ptr_t backing_store_end; | |
55 | ptr_t backing_store_ptr; | |
56 | # endif | |
57 | void * status; /* The value returned from the thread. */ | |
58 | /* Used only to avoid premature */ | |
59 | /* reclamation of any data it might */ | |
60 | /* reference. */ | |
61 | /* This is unfortunately also the */ | |
62 | /* reason we need to intercept join */ | |
63 | /* and detach. */ | |
64 | # ifdef THREAD_LOCAL_ALLOC | |
65 | struct thread_local_freelists tlfs; | |
66 | # endif | |
67 | } * GC_thread; | |
68 | ||
69 | # define THREAD_TABLE_SZ 256 /* Must be power of 2 */ | |
70 | extern volatile GC_thread GC_threads[THREAD_TABLE_SZ]; | |
71 | ||
72 | extern GC_bool GC_thr_initialized; | |
73 | ||
74 | GC_thread GC_lookup_thread(pthread_t id); | |
75 | ||
76 | void GC_stop_init(); | |
77 | ||
78 | extern GC_bool GC_in_thread_creation; | |
79 | /* We may currently be in thread creation or destruction. */ | |
80 | /* Only set to TRUE while allocation lock is held. */ | |
81 | /* When set, it is OK to run GC from unknown thread. */ | |
82 | ||
83 | #endif /* GC_PTHREADS && !GC_SOLARIS_THREADS.... etc */ | |
84 | #endif /* GC_PTHREAD_SUPPORT_H */ |