pthread_support.c 50 KB

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