967a6ed47eaeaf68bbde32adf2d39f93ce8d622c
[p5sagit/p5-mst-13.2.git] / ext / threads / threads.xs
1 #define PERL_NO_GET_CONTEXT
2 #include "EXTERN.h"
3 #include "perl.h"
4 #include "XSUB.h"
5 /* Workaround for XSUB.h bug under WIN32 */
6 #ifdef WIN32
7 #  undef setjmp
8 #  if !defined(__BORLANDC__)
9 #    define setjmp(x) _setjmp(x)
10 #  endif
11 #endif
12 #ifdef HAS_PPPORT_H
13 #  define NEED_PL_signals
14 #  define NEED_newRV_noinc
15 #  define NEED_sv_2pv_nolen
16 #  include "ppport.h"
17 #  include "threads.h"
18 #endif
19
20 #ifdef USE_ITHREADS
21
22 #ifdef WIN32
23 #  include <windows.h>
24    /* Supposed to be in Winbase.h */
25 #  ifndef STACK_SIZE_PARAM_IS_A_RESERVATION
26 #    define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
27 #  endif
28 #  include <win32thread.h>
29 #else
30 #  ifdef OS2
31 typedef perl_os_thread pthread_t;
32 #  else
33 #    include <pthread.h>
34 #  endif
35 #  include <thread.h>
36 #  define PERL_THREAD_SETSPECIFIC(k,v) pthread_setspecific(k,v)
37 #  ifdef OLD_PTHREADS_API
38 #    define PERL_THREAD_DETACH(t) pthread_detach(&(t))
39 #  else
40 #    define PERL_THREAD_DETACH(t) pthread_detach((t))
41 #  endif
42 #endif
43 #if !defined(HAS_GETPAGESIZE) && defined(I_SYS_PARAM)
44 #  include <sys/param.h>
45 #endif
46
47 /* Values for 'state' member */
48 #define PERL_ITHR_JOINABLE              0
49 #define PERL_ITHR_DETACHED              1
50 #define PERL_ITHR_JOINED                2
51 #define PERL_ITHR_FINISHED              4
52 #define PERL_ITHR_THREAD_EXIT_ONLY      8
53
54 typedef struct _ithread {
55     struct _ithread *next;      /* Next thread in the list */
56     struct _ithread *prev;      /* Prev thread in the list */
57     PerlInterpreter *interp;    /* The threads interpreter */
58     UV tid;                     /* Threads module's thread id */
59     perl_mutex mutex;           /* Mutex for updating things in this struct */
60     int count;                  /* How many SVs have a reference to us */
61     int state;                  /* Detached, joined, finished, etc. */
62     int gimme;                  /* Context of create */
63     SV *init_function;          /* Code to run */
64     SV *params;                 /* Args to pass function */
65 #ifdef WIN32
66     DWORD  thr;                 /* OS's idea if thread id */
67     HANDLE handle;              /* OS's waitable handle */
68 #else
69     pthread_t thr;              /* OS's handle for the thread */
70 #endif
71     IV stack_size;
72 } ithread;
73
74
75 #define MY_CXT_KEY "threads::_cxt" XS_VERSION
76
77 typedef struct {
78     /* Used by Perl interpreter for thread context switching */
79     ithread *context;
80 } my_cxt_t;
81
82 START_MY_CXT
83
84
85 #define MY_POOL_KEY "threads::_pool" XS_VERSION
86
87 typedef struct {
88     /* Structure for 'main' thread
89      * Also forms the 'base' for the doubly-linked list of threads */
90     ithread main_thread;
91
92     /* Protects the creation and destruction of threads*/
93     perl_mutex create_destruct_mutex;
94
95     UV tid_counter;
96     IV joinable_threads;
97     IV running_threads;
98     IV detached_threads;
99     IV default_stack_size;
100     IV page_size;
101 } my_pool_t;
102
103 #define dMY_POOL \
104     SV *my_pool_sv = *hv_fetch(PL_modglobal, MY_POOL_KEY,               \
105                                sizeof(MY_POOL_KEY)-1, TRUE);            \
106     my_pool_t *my_poolp = INT2PTR(my_pool_t*, SvUV(my_pool_sv))
107
108 #define MY_POOL (*my_poolp)
109
110
111 /* Used by Perl interpreter for thread context switching */
112 STATIC void
113 S_ithread_set(pTHX_ ithread *thread)
114 {
115     dMY_CXT;
116     MY_CXT.context = thread;
117 }
118
119 STATIC ithread *
120 S_ithread_get(pTHX)
121 {
122     dMY_CXT;
123     return (MY_CXT.context);
124 }
125
126
127 /* Free any data (such as the Perl interpreter) attached to an ithread
128  * structure.  This is a bit like undef on SVs, where the SV isn't freed,
129  * but the PVX is.  Must be called with thread->mutex already held.
130  */
131 STATIC void
132 S_ithread_clear(pTHX_ ithread *thread)
133 {
134     PerlInterpreter *interp;
135
136     assert((thread->state & PERL_ITHR_FINISHED) &&
137            (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)));
138
139     interp = thread->interp;
140     if (interp) {
141         dTHXa(interp);
142
143         PERL_SET_CONTEXT(interp);
144         S_ithread_set(aTHX_ thread);
145
146         SvREFCNT_dec(thread->params);
147         thread->params = Nullsv;
148
149         perl_destruct(interp);
150         perl_free(interp);
151         thread->interp = NULL;
152     }
153
154     PERL_SET_CONTEXT(aTHX);
155 }
156
157
158 /* Free an ithread structure and any attached data if its count == 0 */
159 STATIC void
160 S_ithread_destruct(pTHX_ ithread *thread)
161 {
162     dMY_POOL;
163
164 #ifdef WIN32
165     HANDLE handle;
166 #endif
167     /* Return if thread is still being used */
168     if (thread->count != 0) {
169         return;
170     }
171
172     /* Main thread (0) is immortal and should never get here */
173     assert(thread->tid != 0);
174
175     /* Remove from circular list of threads */
176     MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
177     thread->next->prev = thread->prev;
178     thread->prev->next = thread->next;
179     thread->next = NULL;
180     thread->prev = NULL;
181     MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
182
183     /* Thread is now disowned */
184     MUTEX_LOCK(&thread->mutex);
185     S_ithread_clear(aTHX_ thread);
186
187 #ifdef WIN32
188     handle = thread->handle;
189     thread->handle = NULL;
190 #endif
191     MUTEX_UNLOCK(&thread->mutex);
192     MUTEX_DESTROY(&thread->mutex);
193
194 #ifdef WIN32
195     if (handle) {
196         CloseHandle(handle);
197     }
198 #endif
199
200     /* Call PerlMemShared_free() in the context of the "first" interpreter
201      * per http://www.nntp.perl.org/group/perl.perl5.porters/110772
202      */
203     aTHX = MY_POOL.main_thread.interp;
204     PerlMemShared_free(thread);
205 }
206
207
208 /* Warn if exiting with any unjoined threads */
209 STATIC int
210 S_exit_warning(pTHX)
211 {
212     dMY_POOL;
213
214     int veto_cleanup;
215
216     MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
217     veto_cleanup = (MY_POOL.running_threads || MY_POOL.joinable_threads);
218     MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
219
220     if (veto_cleanup) {
221         if (ckWARN_d(WARN_THREADS)) {
222             Perl_warn(aTHX_ "Perl exited with active threads:\n\t%"
223                             IVdf " running and unjoined\n\t%"
224                             IVdf " finished and unjoined\n\t%"
225                             IVdf " running and detached\n",
226                             MY_POOL.running_threads,
227                             MY_POOL.joinable_threads,
228                             MY_POOL.detached_threads);
229         }
230     }
231
232     return (veto_cleanup);
233 }
234
235 /* Called on exit from main thread */
236 int
237 Perl_ithread_hook(pTHX)
238 {
239     dMY_POOL;
240
241     int veto_cleanup = 0;
242
243     if (aTHX == MY_POOL.main_thread.interp) {
244         veto_cleanup = S_exit_warning(aTHX);
245         if (! veto_cleanup) {
246             MUTEX_DESTROY(&MY_POOL.create_destruct_mutex);
247         }
248     }
249
250     return (veto_cleanup);
251 }
252
253
254 /* MAGIC (in mg.h sense) hooks */
255
256 int
257 ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
258 {
259     ithread *thread = (ithread *)mg->mg_ptr;
260     SvIV_set(sv, PTR2IV(thread));
261     SvIOK_on(sv);
262     return (0);
263 }
264
265 int
266 ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
267 {
268     ithread *thread = (ithread *)mg->mg_ptr;
269     int cleanup;
270
271     MUTEX_LOCK(&thread->mutex);
272     cleanup = ((--thread->count == 0) &&
273                (thread->state & PERL_ITHR_FINISHED) &&
274                (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)));
275     MUTEX_UNLOCK(&thread->mutex);
276
277     if (cleanup) {
278         S_ithread_destruct(aTHX_ thread);
279     }
280     return (0);
281 }
282
283 int
284 ithread_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
285 {
286     ithread *thread = (ithread *)mg->mg_ptr;
287     MUTEX_LOCK(&thread->mutex);
288     thread->count++;
289     MUTEX_UNLOCK(&thread->mutex);
290     return (0);
291 }
292
293 MGVTBL ithread_vtbl = {
294     ithread_mg_get,     /* get */
295     0,                  /* set */
296     0,                  /* len */
297     0,                  /* clear */
298     ithread_mg_free,    /* free */
299     0,                  /* copy */
300     ithread_mg_dup      /* dup */
301 };
302
303
304 /* Provided default, minimum and rational stack sizes */
305 STATIC IV
306 S_good_stack_size(pTHX_ IV stack_size)
307 {
308     dMY_POOL;
309
310     /* Use default stack size if no stack size specified */
311     if (! stack_size) {
312         return (MY_POOL.default_stack_size);
313     }
314
315 #ifdef PTHREAD_STACK_MIN
316     /* Can't use less than minimum */
317     if (stack_size < PTHREAD_STACK_MIN) {
318         if (ckWARN(WARN_THREADS)) {
319             Perl_warn(aTHX_ "Using minimum thread stack size of %" IVdf, (IV)PTHREAD_STACK_MIN);
320         }
321         return (PTHREAD_STACK_MIN);
322     }
323 #endif
324
325     /* Round up to page size boundary */
326     if (MY_POOL.page_size <= 0) {
327 #if defined(HAS_SYSCONF) && (defined(_SC_PAGESIZE) || defined(_SC_MMAP_PAGE_SIZE))
328         SETERRNO(0, SS_NORMAL);
329 #  ifdef _SC_PAGESIZE
330         MY_POOL.page_size = sysconf(_SC_PAGESIZE);
331 #  else
332         MY_POOL.page_size = sysconf(_SC_MMAP_PAGE_SIZE);
333 #  endif
334         if ((long)MY_POOL.page_size < 0) {
335             if (errno) {
336                 SV * const error = get_sv("@", FALSE);
337                 (void)SvUPGRADE(error, SVt_PV);
338                 Perl_croak(aTHX_ "PANIC: sysconf: %s", SvPV_nolen(error));
339             } else {
340                 Perl_croak(aTHX_ "PANIC: sysconf: pagesize unknown");
341             }
342         }
343 #else
344 #  ifdef HAS_GETPAGESIZE
345         MY_POOL.page_size = getpagesize();
346 #  else
347 #    if defined(I_SYS_PARAM) && defined(PAGESIZE)
348         MY_POOL.page_size = PAGESIZE;
349 #    else
350         MY_POOL.page_size = 8192;   /* A conservative default */
351 #    endif
352 #  endif
353         if (MY_POOL.page_size <= 0) {
354             Perl_croak(aTHX_ "PANIC: bad pagesize %" IVdf, (IV)MY_POOL.page_size);
355         }
356 #endif
357     }
358     stack_size = ((stack_size + (MY_POOL.page_size - 1)) / MY_POOL.page_size) * MY_POOL.page_size;
359
360     return (stack_size);
361 }
362
363
364 /* Starts executing the thread.
365  * Passed as the C level function to run in the new thread.
366  */
367 #ifdef WIN32
368 STATIC THREAD_RET_TYPE
369 S_ithread_run(LPVOID arg)
370 #else
371 STATIC void *
372 S_ithread_run(void * arg)
373 #endif
374 {
375     ithread *thread = (ithread *)arg;
376     int jmp_rc = 0;
377     I32 oldscope;
378     int exit_app = 0;
379     int exit_code = 0;
380     int cleanup;
381
382     dJMPENV;
383
384     dTHXa(thread->interp);
385
386     dMY_POOL;
387
388     /* Blocked until ->create() call finishes */
389     MUTEX_LOCK(&thread->mutex);
390     MUTEX_UNLOCK(&thread->mutex);
391
392     PERL_SET_CONTEXT(thread->interp);
393     S_ithread_set(aTHX_ thread);
394
395     PL_perl_destruct_level = 2;
396
397     {
398         AV *params = (AV *)SvRV(thread->params);
399         int len = (int)av_len(params)+1;
400         int ii;
401
402         dSP;
403         ENTER;
404         SAVETMPS;
405
406         /* Put args on the stack */
407         PUSHMARK(SP);
408         for (ii=0; ii < len; ii++) {
409             XPUSHs(av_shift(params));
410         }
411         PUTBACK;
412
413         oldscope = PL_scopestack_ix;
414         JMPENV_PUSH(jmp_rc);
415         if (jmp_rc == 0) {
416             /* Run the specified function */
417             len = (int)call_sv(thread->init_function, thread->gimme|G_EVAL);
418         } else if (jmp_rc == 2) {
419             /* Thread exited */
420             exit_app = 1;
421             exit_code = STATUS_CURRENT;
422             while (PL_scopestack_ix > oldscope) {
423                 LEAVE;
424             }
425         }
426         JMPENV_POP;
427
428         /* Remove args from stack and put back in params array */
429         SPAGAIN;
430         for (ii=len-1; ii >= 0; ii--) {
431             SV *sv = POPs;
432             if (jmp_rc == 0) {
433                 av_store(params, ii, SvREFCNT_inc(sv));
434             }
435         }
436
437         FREETMPS;
438         LEAVE;
439
440         /* Check for failure */
441         if (SvTRUE(ERRSV) && ckWARN_d(WARN_THREADS)) {
442             oldscope = PL_scopestack_ix;
443             JMPENV_PUSH(jmp_rc);
444             if (jmp_rc == 0) {
445                 /* Warn that thread died */
446                 Perl_warn(aTHX_ "Thread %" UVuf " terminated abnormally: %" SVf, thread->tid, ERRSV);
447             } else if (jmp_rc == 2) {
448                 /* Warn handler exited */
449                 exit_app = 1;
450                 exit_code = STATUS_CURRENT;
451                 while (PL_scopestack_ix > oldscope) {
452                     LEAVE;
453                 }
454             }
455             JMPENV_POP;
456         }
457
458         /* Release function ref */
459         SvREFCNT_dec(thread->init_function);
460         thread->init_function = Nullsv;
461     }
462
463     PerlIO_flush((PerlIO *)NULL);
464
465     MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
466     MUTEX_LOCK(&thread->mutex);
467     /* Mark as finished */
468     thread->state |= PERL_ITHR_FINISHED;
469     /* Clear exit flag if required */
470     if (thread->state & PERL_ITHR_THREAD_EXIT_ONLY) {
471         exit_app = 0;
472     }
473     /* Cleanup if detached */
474     cleanup = (thread->state & PERL_ITHR_DETACHED);
475     MUTEX_UNLOCK(&thread->mutex);
476
477     /* Adjust thread status counts */
478     if (cleanup) {
479         MY_POOL.detached_threads--;
480     } else {
481         MY_POOL.running_threads--;
482         MY_POOL.joinable_threads++;
483     }
484     MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
485
486     /* Exit application if required */
487     if (exit_app) {
488         oldscope = PL_scopestack_ix;
489         JMPENV_PUSH(jmp_rc);
490         if (jmp_rc == 0) {
491             /* Warn if there are unjoined threads */
492             S_exit_warning(aTHX);
493         } else if (jmp_rc == 2) {
494             /* Warn handler exited */
495             exit_code = STATUS_CURRENT;
496             while (PL_scopestack_ix > oldscope) {
497                 LEAVE;
498             }
499         }
500         JMPENV_POP;
501
502         my_exit(exit_code);
503     }
504
505     /* Clean up detached thread */
506     if (cleanup) {
507         S_ithread_destruct(aTHX_ thread);
508     }
509
510 #ifdef WIN32
511     return ((DWORD)0);
512 #else
513     return (0);
514 #endif
515 }
516
517
518 /* Type conversion helper functions */
519
520 STATIC SV *
521 S_ithread_to_SV(pTHX_ SV *obj, ithread *thread, char *classname, bool inc)
522 {
523     SV *sv;
524     MAGIC *mg;
525
526     /* If incrementing thread ref count, then call within mutex lock */
527     if (inc) {
528         MUTEX_LOCK(&thread->mutex);
529         thread->count++;
530         MUTEX_UNLOCK(&thread->mutex);
531     }
532
533     if (! obj) {
534         obj = newSV(0);
535     }
536
537     sv = newSVrv(obj, classname);
538     sv_setiv(sv, PTR2IV(thread));
539     mg = sv_magicext(sv, Nullsv, PERL_MAGIC_shared_scalar, &ithread_vtbl, (char *)thread, 0);
540     mg->mg_flags |= MGf_DUP;
541     SvREADONLY_on(sv);
542
543     return (obj);
544 }
545
546 STATIC ithread *
547 S_SV_to_ithread(pTHX_ SV *sv)
548 {
549     /* Argument is a thread */
550     if (SvROK(sv)) {
551       return (INT2PTR(ithread *, SvIV(SvRV(sv))));
552     }
553     /* Argument is classname, therefore return current thread */
554     return (S_ithread_get(aTHX));
555 }
556
557
558 /* threads->create()
559  * Called in context of parent thread.
560  * Called with MY_POOL.create_destruct_mutex locked.  (Unlocked on error.)
561  */
562 STATIC ithread *
563 S_ithread_create(
564         pTHX_ SV *init_function,
565         IV        stack_size,
566         int       gimme,
567         int       exit_opt,
568         SV       *params)
569 {
570     dMY_POOL;
571
572     ithread     *thread;
573     CLONE_PARAMS clone_param;
574     ithread     *current_thread = S_ithread_get(aTHX);
575
576     SV         **tmps_tmp = PL_tmps_stack;
577     IV           tmps_ix  = PL_tmps_ix;
578 #ifndef WIN32
579     int          rc_stack_size = 0;
580     int          rc_thread_create = 0;
581 #endif
582
583     /* Allocate thread structure in context of the main threads interpreter */
584     {
585         PERL_SET_CONTEXT(MY_POOL.main_thread.interp);
586         thread = (ithread *)PerlMemShared_malloc(sizeof(ithread));
587     }
588     PERL_SET_CONTEXT(aTHX);
589     if (!thread) {
590         MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
591         PerlLIO_write(PerlIO_fileno(Perl_error_log), PL_no_mem, strlen(PL_no_mem));
592         my_exit(1);
593     }
594     Zero(thread, 1, ithread);
595
596     /* Add to threads list */
597     thread->next = &MY_POOL.main_thread;
598     thread->prev = MY_POOL.main_thread.prev;
599     MY_POOL.main_thread.prev = thread;
600     thread->prev->next = thread;
601
602     /* Set count to 1 immediately in case thread exits before
603      * we return to caller!
604      */
605     thread->count = 1;
606
607     /* Block new thread until ->create() call finishes */
608     MUTEX_INIT(&thread->mutex);
609     MUTEX_LOCK(&thread->mutex);
610
611     thread->tid = MY_POOL.tid_counter++;
612     thread->stack_size = S_good_stack_size(aTHX_ stack_size);
613     thread->gimme = gimme;
614     thread->state = exit_opt;
615
616     /* "Clone" our interpreter into the thread's interpreter.
617      * This gives thread access to "static data" and code.
618      */
619     PerlIO_flush((PerlIO *)NULL);
620     S_ithread_set(aTHX_ thread);
621
622     SAVEBOOL(PL_srand_called); /* Save this so it becomes the correct value */
623     PL_srand_called = FALSE;   /* Set it to false so we can detect if it gets
624                                   set during the clone */
625
626 #ifdef WIN32
627     thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
628 #else
629     thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
630 #endif
631
632     /* perl_clone() leaves us in new interpreter's context.  As it is tricky
633      * to spot an implicit aTHX, create a new scope with aTHX matching the
634      * context for the duration of our work for new interpreter.
635      */
636     {
637         dTHXa(thread->interp);
638
639         MY_CXT_CLONE;
640
641         /* Here we remove END blocks since they should only run in the thread
642          * they are created
643          */
644         SvREFCNT_dec(PL_endav);
645         PL_endav = newAV();
646
647         if (SvPOK(init_function)) {
648             thread->init_function = newSV(0);
649             sv_copypv(thread->init_function, init_function);
650         } else {
651             clone_param.flags = 0;
652             thread->init_function = sv_dup(init_function, &clone_param);
653             if (SvREFCNT(thread->init_function) == 0) {
654                 SvREFCNT_inc_void(thread->init_function);
655             }
656         }
657
658         thread->params = sv_dup(params, &clone_param);
659         SvREFCNT_inc_void(thread->params);
660
661         /* The code below checks that anything living on the tmps stack and
662          * has been cloned (so it lives in the ptr_table) has a refcount
663          * higher than 0.
664          *
665          * If the refcount is 0 it means that a something on the stack/context
666          * was holding a reference to it and since we init_stacks() in
667          * perl_clone that won't get cleaned and we will get a leaked scalar.
668          * The reason it was cloned was that it lived on the @_ stack.
669          *
670          * Example of this can be found in bugreport 15837 where calls in the
671          * parameter list end up as a temp.
672          *
673          * One could argue that this fix should be in perl_clone.
674          */
675         while (tmps_ix > 0) {
676             SV* sv = (SV*)ptr_table_fetch(PL_ptr_table, tmps_tmp[tmps_ix]);
677             tmps_ix--;
678             if (sv && SvREFCNT(sv) == 0) {
679                 SvREFCNT_inc_void(sv);
680                 SvREFCNT_dec(sv);
681             }
682         }
683
684         SvTEMP_off(thread->init_function);
685         ptr_table_free(PL_ptr_table);
686         PL_ptr_table = NULL;
687         PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
688     }
689     S_ithread_set(aTHX_ current_thread);
690     PERL_SET_CONTEXT(aTHX);
691
692     /* Create/start the thread */
693 #ifdef WIN32
694     thread->handle = CreateThread(NULL,
695                                   (DWORD)thread->stack_size,
696                                   S_ithread_run,
697                                   (LPVOID)thread,
698                                   STACK_SIZE_PARAM_IS_A_RESERVATION,
699                                   &thread->thr);
700 #else
701     {
702         STATIC pthread_attr_t attr;
703         STATIC int attr_inited = 0;
704         STATIC int attr_joinable = PTHREAD_CREATE_JOINABLE;
705         if (! attr_inited) {
706             pthread_attr_init(&attr);
707             attr_inited = 1;
708         }
709
710 #  ifdef PTHREAD_ATTR_SETDETACHSTATE
711         /* Threads start out joinable */
712         PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
713 #  endif
714
715 #  ifdef _POSIX_THREAD_ATTR_STACKSIZE
716         /* Set thread's stack size */
717         if (thread->stack_size > 0) {
718             rc_stack_size = pthread_attr_setstacksize(&attr, (size_t)thread->stack_size);
719         }
720 #  endif
721
722         /* Create the thread */
723         if (! rc_stack_size) {
724 #  ifdef OLD_PTHREADS_API
725             rc_thread_create = pthread_create(&thread->thr,
726                                               attr,
727                                               S_ithread_run,
728                                               (void *)thread);
729 #  else
730 #    if defined(HAS_PTHREAD_ATTR_SETSCOPE) && defined(PTHREAD_SCOPE_SYSTEM)
731             pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
732 #    endif
733             rc_thread_create = pthread_create(&thread->thr,
734                                               &attr,
735                                               S_ithread_run,
736                                               (void *)thread);
737 #  endif
738         }
739
740 #  ifdef _POSIX_THREAD_ATTR_STACKSIZE
741         /* Try to get thread's actual stack size */
742         {
743             size_t stacksize;
744 #ifdef HPUX1020
745             stacksize = pthread_attr_getstacksize(attr);
746 #else
747             if (! pthread_attr_getstacksize(&attr, &stacksize))
748 #endif
749                 if (stacksize > 0) {
750                     thread->stack_size = (IV)stacksize;
751                 }
752         }
753 #  endif
754     }
755 #endif
756
757     /* Check for errors */
758 #ifdef WIN32
759     if (thread->handle == NULL) {
760 #else
761     if (rc_stack_size || rc_thread_create) {
762 #endif
763         /* Must unlock mutex for destruct call */
764         MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
765         sv_2mortal(params);
766         S_ithread_destruct(aTHX_ thread);
767 #ifndef WIN32
768         if (ckWARN_d(WARN_THREADS)) {
769             if (rc_stack_size) {
770                 Perl_warn(aTHX_ "Thread creation failed: pthread_attr_setstacksize(%" IVdf ") returned %d", thread->stack_size, rc_stack_size);
771             } else {
772                 Perl_warn(aTHX_ "Thread creation failed: pthread_create returned %d", rc_thread_create);
773             }
774         }
775 #endif
776         return (NULL);
777     }
778
779     MY_POOL.running_threads++;
780     sv_2mortal(params);
781     return (thread);
782 }
783
784 #endif /* USE_ITHREADS */
785
786
787 MODULE = threads    PACKAGE = threads    PREFIX = ithread_
788 PROTOTYPES: DISABLE
789
790 #ifdef USE_ITHREADS
791
792 void
793 ithread_create(...)
794     PREINIT:
795         char *classname;
796         ithread *thread;
797         SV *function_to_call;
798         AV *params;
799         HV *specs;
800         IV stack_size;
801         int context;
802         int exit_opt;
803         SV *thread_exit_only;
804         char *str;
805         int idx;
806         int ii;
807         dMY_POOL;
808     CODE:
809         if ((items >= 2) && SvROK(ST(1)) && SvTYPE(SvRV(ST(1)))==SVt_PVHV) {
810             if (--items < 2) {
811                 Perl_croak(aTHX_ "Usage: threads->create(\\%specs, function, ...)");
812             }
813             specs = (HV*)SvRV(ST(1));
814             idx = 1;
815         } else {
816             if (items < 2) {
817                 Perl_croak(aTHX_ "Usage: threads->create(function, ...)");
818             }
819             specs = NULL;
820             idx = 0;
821         }
822
823         if (sv_isobject(ST(0))) {
824             /* $thr->create() */
825             classname = HvNAME(SvSTASH(SvRV(ST(0))));
826             thread = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
827             stack_size = thread->stack_size;
828             exit_opt = thread->state & PERL_ITHR_THREAD_EXIT_ONLY;
829         } else {
830             /* threads->create() */
831             classname = (char *)SvPV_nolen(ST(0));
832             stack_size = MY_POOL.default_stack_size;
833             thread_exit_only = get_sv("threads::thread_exit_only", TRUE);
834             exit_opt = (SvTRUE(thread_exit_only))
835                                     ? PERL_ITHR_THREAD_EXIT_ONLY : 0;
836         }
837
838         function_to_call = ST(idx+1);
839
840         context = -1;
841         if (specs) {
842             /* stack_size */
843             if (hv_exists(specs, "stack", 5)) {
844                 stack_size = SvIV(*hv_fetch(specs, "stack", 5, 0));
845             } else if (hv_exists(specs, "stacksize", 9)) {
846                 stack_size = SvIV(*hv_fetch(specs, "stacksize", 9, 0));
847             } else if (hv_exists(specs, "stack_size", 10)) {
848                 stack_size = SvIV(*hv_fetch(specs, "stack_size", 10, 0));
849             }
850
851             /* context */
852             if (hv_exists(specs, "context", 7)) {
853                 str = (char *)SvPV_nolen(*hv_fetch(specs, "context", 7, 0));
854                 switch (*str) {
855                     case 'a':
856                     case 'A':
857                         context = G_ARRAY;
858                         break;
859                     case 's':
860                     case 'S':
861                         context = G_SCALAR;
862                         break;
863                     case 'v':
864                     case 'V':
865                         context = G_VOID;
866                         break;
867                     default:
868                         Perl_croak(aTHX_ "Invalid context: %s", str);
869                 }
870             } else if (hv_exists(specs, "array", 5)) {
871                 if (SvTRUE(*hv_fetch(specs, "array", 5, 0))) {
872                     context = G_ARRAY;
873                 }
874             } else if (hv_exists(specs, "scalar", 6)) {
875                 if (SvTRUE(*hv_fetch(specs, "scalar", 6, 0))) {
876                     context = G_SCALAR;
877                 }
878             } else if (hv_exists(specs, "void", 4)) {
879                 if (SvTRUE(*hv_fetch(specs, "void", 4, 0))) {
880                     context = G_VOID;
881                 }
882             }
883
884             /* exit => thread_only */
885             if (hv_exists(specs, "exit", 4)) {
886                 str = (char *)SvPV_nolen(*hv_fetch(specs, "exit", 4, 0));
887                 exit_opt = (*str == 't' || *str == 'T')
888                                     ? PERL_ITHR_THREAD_EXIT_ONLY : 0;
889             }
890         }
891         if (context == -1) {
892             context = GIMME_V;  /* Implicit context */
893         } else {
894             context |= (GIMME_V & (~(G_ARRAY|G_SCALAR|G_VOID)));
895         }
896
897         /* Function args */
898         params = newAV();
899         if (items > 2) {
900             for (ii=2; ii < items ; ii++) {
901                 av_push(params, SvREFCNT_inc(ST(idx+ii)));
902             }
903         }
904
905         /* Create thread */
906         MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
907         thread = S_ithread_create(aTHX_ function_to_call,
908                                         stack_size,
909                                         context,
910                                         exit_opt,
911                                         newRV_noinc((SV*)params));
912         if (! thread) {
913             XSRETURN_UNDEF;     /* Mutex already unlocked */
914         }
915         ST(0) = sv_2mortal(S_ithread_to_SV(aTHX_ Nullsv, thread, classname, FALSE));
916
917         /* Let thread run */
918         MUTEX_UNLOCK(&thread->mutex);
919         MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
920
921         /* XSRETURN(1); - implied */
922
923
924 void
925 ithread_list(...)
926     PREINIT:
927         char *classname;
928         ithread *thread;
929         int list_context;
930         IV count = 0;
931         int want_running;
932         dMY_POOL;
933     PPCODE:
934         /* Class method only */
935         if (SvROK(ST(0))) {
936             Perl_croak(aTHX_ "Usage: threads->list(...)");
937         }
938         classname = (char *)SvPV_nolen(ST(0));
939
940         /* Calling context */
941         list_context = (GIMME_V == G_ARRAY);
942
943         /* Running or joinable parameter */
944         if (items > 1) {
945             want_running = SvTRUE(ST(1));
946         }
947
948         /* Walk through threads list */
949         MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
950         for (thread = MY_POOL.main_thread.next;
951              thread != &MY_POOL.main_thread;
952              thread = thread->next)
953         {
954             /* Ignore detached or joined threads */
955             if (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)) {
956                 continue;
957             }
958
959             /* Filter per parameter */
960             if (items > 1) {
961                 if (want_running) {
962                     if (thread->state & PERL_ITHR_FINISHED) {
963                         continue;   /* Not running */
964                     }
965                 } else {
966                     if (! (thread->state & PERL_ITHR_FINISHED)) {
967                         continue;   /* Still running - not joinable yet */
968                     }
969                 }
970             }
971
972             /* Push object on stack if list context */
973             if (list_context) {
974                 XPUSHs(sv_2mortal(S_ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE)));
975             }
976             count++;
977         }
978         MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
979         /* If scalar context, send back count */
980         if (! list_context) {
981             XSRETURN_IV(count);
982         }
983
984
985 void
986 ithread_self(...)
987     PREINIT:
988         char *classname;
989         ithread *thread;
990     CODE:
991         /* Class method only */
992         if (SvROK(ST(0))) {
993             Perl_croak(aTHX_ "Usage: threads->self()");
994         }
995         classname = (char *)SvPV_nolen(ST(0));
996
997         thread = S_ithread_get(aTHX);
998
999         ST(0) = sv_2mortal(S_ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE));
1000         /* XSRETURN(1); - implied */
1001
1002
1003 void
1004 ithread_tid(...)
1005     PREINIT:
1006         ithread *thread;
1007     CODE:
1008         thread = S_SV_to_ithread(aTHX_ ST(0));
1009         XST_mUV(0, thread->tid);
1010         /* XSRETURN(1); - implied */
1011
1012
1013 void
1014 ithread_join(...)
1015     PREINIT:
1016         ithread *thread;
1017         int join_err;
1018         AV *params;
1019         int len;
1020         int ii;
1021 #ifdef WIN32
1022         DWORD waitcode;
1023 #else
1024         void *retval;
1025 #endif
1026         dMY_POOL;
1027     PPCODE:
1028         /* Object method only */
1029         if (! sv_isobject(ST(0))) {
1030             Perl_croak(aTHX_ "Usage: $thr->join()");
1031         }
1032
1033         /* Check if the thread is joinable */
1034         thread = S_SV_to_ithread(aTHX_ ST(0));
1035         join_err = (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED));
1036         if (join_err) {
1037             if (join_err & PERL_ITHR_DETACHED) {
1038                 Perl_croak(aTHX_ "Cannot join a detached thread");
1039             } else {
1040                 Perl_croak(aTHX_ "Thread already joined");
1041             }
1042         }
1043
1044         /* Join the thread */
1045 #ifdef WIN32
1046         waitcode = WaitForSingleObject(thread->handle, INFINITE);
1047 #else
1048         pthread_join(thread->thr, &retval);
1049 #endif
1050
1051         MUTEX_LOCK(&thread->mutex);
1052         /* Mark as joined */
1053         thread->state |= PERL_ITHR_JOINED;
1054
1055         /* Get the return value from the call_sv */
1056         {
1057             AV *params_copy;
1058             PerlInterpreter *other_perl;
1059             CLONE_PARAMS clone_params;
1060             ithread *current_thread;
1061
1062             params_copy = (AV *)SvRV(thread->params);
1063             other_perl = thread->interp;
1064             clone_params.stashes = newAV();
1065             clone_params.flags = CLONEf_JOIN_IN;
1066             PL_ptr_table = ptr_table_new();
1067             current_thread = S_ithread_get(aTHX);
1068             S_ithread_set(aTHX_ thread);
1069             /* Ensure 'meaningful' addresses retain their meaning */
1070             ptr_table_store(PL_ptr_table, &other_perl->Isv_undef, &PL_sv_undef);
1071             ptr_table_store(PL_ptr_table, &other_perl->Isv_no, &PL_sv_no);
1072             ptr_table_store(PL_ptr_table, &other_perl->Isv_yes, &PL_sv_yes);
1073             params = (AV *)sv_dup((SV*)params_copy, &clone_params);
1074             S_ithread_set(aTHX_ current_thread);
1075             SvREFCNT_dec(clone_params.stashes);
1076             SvREFCNT_inc_void(params);
1077             ptr_table_free(PL_ptr_table);
1078             PL_ptr_table = NULL;
1079         }
1080
1081         /* We are finished with the thread */
1082         S_ithread_clear(aTHX_ thread);
1083         MUTEX_UNLOCK(&thread->mutex);
1084
1085         MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
1086         if (! (thread->state & PERL_ITHR_DETACHED)) {
1087             MY_POOL.joinable_threads--;
1088         }
1089         MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
1090
1091         /* If no return values, then just return */
1092         if (! params) {
1093             XSRETURN_UNDEF;
1094         }
1095
1096         /* Put return values on stack */
1097         len = (int)AvFILL(params);
1098         for (ii=0; ii <= len; ii++) {
1099             SV* param = av_shift(params);
1100             XPUSHs(sv_2mortal(param));
1101         }
1102
1103         /* Free return value array */
1104         SvREFCNT_dec(params);
1105
1106
1107 void
1108 ithread_yield(...)
1109     CODE:
1110         YIELD;
1111
1112
1113 void
1114 ithread_detach(...)
1115     PREINIT:
1116         ithread *thread;
1117         int detach_err;
1118         int cleanup;
1119         dMY_POOL;
1120     CODE:
1121         /* Check if the thread is detachable */
1122         thread = S_SV_to_ithread(aTHX_ ST(0));
1123         if ((detach_err = (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)))) {
1124             if (detach_err & PERL_ITHR_DETACHED) {
1125                 Perl_croak(aTHX_ "Thread already detached");
1126             } else {
1127                 Perl_croak(aTHX_ "Cannot detach a joined thread");
1128             }
1129         }
1130
1131         /* Detach the thread */
1132         MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
1133         MUTEX_LOCK(&thread->mutex);
1134         thread->state |= PERL_ITHR_DETACHED;
1135 #ifdef WIN32
1136         /* Windows has no 'detach thread' function */
1137 #else
1138         PERL_THREAD_DETACH(thread->thr);
1139 #endif
1140         /* Cleanup if finished */
1141         cleanup = (thread->state & PERL_ITHR_FINISHED);
1142         MUTEX_UNLOCK(&thread->mutex);
1143
1144         if (cleanup) {
1145             MY_POOL.joinable_threads--;
1146         } else {
1147             MY_POOL.running_threads--;
1148             MY_POOL.detached_threads++;
1149         }
1150         MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
1151
1152         if (cleanup) {
1153             S_ithread_destruct(aTHX_ thread);
1154         }
1155
1156
1157 void
1158 ithread_kill(...)
1159     PREINIT:
1160         ithread *thread;
1161         char *sig_name;
1162         IV signal;
1163     CODE:
1164         /* Must have safe signals */
1165         if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG) {
1166             Perl_croak(aTHX_ "Cannot signal threads without safe signals");
1167         }
1168
1169         /* Object method only */
1170         if (! sv_isobject(ST(0))) {
1171             Perl_croak(aTHX_ "Usage: $thr->kill('SIG...')");
1172         }
1173
1174         /* Get signal */
1175         sig_name = SvPV_nolen(ST(1));
1176         if (isALPHA(*sig_name)) {
1177             if (*sig_name == 'S' && sig_name[1] == 'I' && sig_name[2] == 'G') {
1178                 sig_name += 3;
1179             }
1180             if ((signal = whichsig(sig_name)) < 0) {
1181                 Perl_croak(aTHX_ "Unrecognized signal name: %s", sig_name);
1182             }
1183         } else {
1184             signal = SvIV(ST(1));
1185         }
1186
1187         /* Set the signal for the thread */
1188         thread = S_SV_to_ithread(aTHX_ ST(0));
1189         MUTEX_LOCK(&thread->mutex);
1190         if (thread->interp) {
1191             dTHXa(thread->interp);
1192             PL_psig_pend[signal]++;
1193             PL_sig_pending = 1;
1194         }
1195         MUTEX_UNLOCK(&thread->mutex);
1196
1197         /* Return the thread to allow for method chaining */
1198         ST(0) = ST(0);
1199         /* XSRETURN(1); - implied */
1200
1201
1202 void
1203 ithread_DESTROY(...)
1204     CODE:
1205         sv_unmagic(SvRV(ST(0)), PERL_MAGIC_shared_scalar);
1206
1207
1208 void
1209 ithread_equal(...)
1210     PREINIT:
1211         int are_equal = 0;
1212     CODE:
1213         /* Compares TIDs to determine thread equality */
1214         if (sv_isobject(ST(0)) && sv_isobject(ST(1))) {
1215             ithread *thr1 = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
1216             ithread *thr2 = INT2PTR(ithread *, SvIV(SvRV(ST(1))));
1217             are_equal = (thr1->tid == thr2->tid);
1218         }
1219         if (are_equal) {
1220             XST_mYES(0);
1221         } else {
1222             /* Return 0 on false for backward compatibility */
1223             XST_mIV(0, 0);
1224         }
1225         /* XSRETURN(1); - implied */
1226
1227
1228 void
1229 ithread_object(...)
1230     PREINIT:
1231         char *classname;
1232         UV tid;
1233         ithread *thread;
1234         int have_obj = 0;
1235         dMY_POOL;
1236     CODE:
1237         /* Class method only */
1238         if (SvROK(ST(0))) {
1239             Perl_croak(aTHX_ "Usage: threads->object($tid)");
1240         }
1241         classname = (char *)SvPV_nolen(ST(0));
1242
1243         if ((items < 2) || ! SvOK(ST(1))) {
1244             XSRETURN_UNDEF;
1245         }
1246
1247         /* threads->object($tid) */
1248         tid = SvUV(ST(1));
1249
1250         /* Walk through threads list */
1251         MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
1252         for (thread = MY_POOL.main_thread.next;
1253              thread != &MY_POOL.main_thread;
1254              thread = thread->next)
1255         {
1256             /* Look for TID */
1257             if (thread->tid == tid) {
1258                 /* Ignore if detached or joined */
1259                 if (! (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED))) {
1260                     /* Put object on stack */
1261                     ST(0) = sv_2mortal(S_ithread_to_SV(aTHX_ Nullsv, thread, classname, TRUE));
1262                     have_obj = 1;
1263                 }
1264                 break;
1265             }
1266         }
1267         MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
1268
1269         if (! have_obj) {
1270             XSRETURN_UNDEF;
1271         }
1272         /* XSRETURN(1); - implied */
1273
1274
1275 void
1276 ithread__handle(...);
1277     PREINIT:
1278         ithread *thread;
1279     CODE:
1280         thread = S_SV_to_ithread(aTHX_ ST(0));
1281 #ifdef WIN32
1282         XST_mUV(0, PTR2UV(&thread->handle));
1283 #else
1284         XST_mUV(0, PTR2UV(&thread->thr));
1285 #endif
1286         /* XSRETURN(1); - implied */
1287
1288
1289 void
1290 ithread_get_stack_size(...)
1291     PREINIT:
1292         IV stack_size;
1293         dMY_POOL;
1294     CODE:
1295         if (sv_isobject(ST(0))) {
1296             /* $thr->get_stack_size() */
1297             ithread *thread = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
1298             stack_size = thread->stack_size;
1299         } else {
1300             /* threads->get_stack_size() */
1301             stack_size = MY_POOL.default_stack_size;
1302         }
1303         XST_mIV(0, stack_size);
1304         /* XSRETURN(1); - implied */
1305
1306
1307 void
1308 ithread_set_stack_size(...)
1309     PREINIT:
1310         IV old_size;
1311         dMY_POOL;
1312     CODE:
1313         if (items != 2) {
1314             Perl_croak(aTHX_ "Usage: threads->set_stack_size($size)");
1315         }
1316         if (sv_isobject(ST(0))) {
1317             Perl_croak(aTHX_ "Cannot change stack size of an existing thread");
1318         }
1319
1320         old_size = MY_POOL.default_stack_size;
1321         MY_POOL.default_stack_size = S_good_stack_size(aTHX_ SvIV(ST(1)));
1322         XST_mIV(0, old_size);
1323         /* XSRETURN(1); - implied */
1324
1325
1326 void
1327 ithread_is_running(...)
1328     PREINIT:
1329         ithread *thread;
1330     CODE:
1331         /* Object method only */
1332         if (! sv_isobject(ST(0))) {
1333             Perl_croak(aTHX_ "Usage: $thr->is_running()");
1334         }
1335
1336         thread = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
1337         ST(0) = (thread->state & PERL_ITHR_FINISHED) ? &PL_sv_no : &PL_sv_yes;
1338         /* XSRETURN(1); - implied */
1339
1340
1341 void
1342 ithread_is_detached(...)
1343     PREINIT:
1344         ithread *thread;
1345     CODE:
1346         thread = S_SV_to_ithread(aTHX_ ST(0));
1347         ST(0) = (thread->state & PERL_ITHR_DETACHED) ? &PL_sv_yes : &PL_sv_no;
1348         /* XSRETURN(1); - implied */
1349
1350
1351 void
1352 ithread_is_joinable(...)
1353     PREINIT:
1354         ithread *thread;
1355     CODE:
1356         /* Object method only */
1357         if (! sv_isobject(ST(0))) {
1358             Perl_croak(aTHX_ "Usage: $thr->is_joinable()");
1359         }
1360
1361         thread = INT2PTR(ithread *, SvIV(SvRV(ST(0))));
1362         MUTEX_LOCK(&thread->mutex);
1363         ST(0) = ((thread->state & PERL_ITHR_FINISHED) &&
1364                  ! (thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED)))
1365             ? &PL_sv_yes : &PL_sv_no;
1366         MUTEX_UNLOCK(&thread->mutex);
1367         /* XSRETURN(1); - implied */
1368
1369
1370 void
1371 ithread_wantarray(...)
1372     PREINIT:
1373         ithread *thread;
1374     CODE:
1375         thread = S_SV_to_ithread(aTHX_ ST(0));
1376         ST(0) = (thread->gimme & G_ARRAY) ? &PL_sv_yes :
1377                 (thread->gimme & G_VOID)  ? &PL_sv_undef
1378                            /* G_SCALAR */ : &PL_sv_no;
1379         /* XSRETURN(1); - implied */
1380
1381
1382 void
1383 ithread_set_thread_exit_only(...)
1384     PREINIT:
1385         ithread *thread;
1386     CODE:
1387         if (items != 2) {
1388             Perl_croak(aTHX_ "Usage: ->set_thread_exit_only(boolean)");
1389         }
1390         thread = S_SV_to_ithread(aTHX_ ST(0));
1391         MUTEX_LOCK(&thread->mutex);
1392         if (SvTRUE(ST(1))) {
1393             thread->state |= PERL_ITHR_THREAD_EXIT_ONLY;
1394         } else {
1395             thread->state &= ~PERL_ITHR_THREAD_EXIT_ONLY;
1396         }
1397         MUTEX_UNLOCK(&thread->mutex);
1398
1399 #endif /* USE_ITHREADS */
1400
1401
1402 BOOT:
1403 {
1404 #ifdef USE_ITHREADS
1405     SV *my_pool_sv = *hv_fetch(PL_modglobal, MY_POOL_KEY,
1406                                sizeof(MY_POOL_KEY)-1, TRUE);
1407     my_pool_t *my_poolp = (my_pool_t*)SvPVX(newSV(sizeof(my_pool_t)-1));
1408
1409     MY_CXT_INIT;
1410
1411     Zero(my_poolp, 1, my_pool_t);
1412     sv_setuv(my_pool_sv, PTR2UV(my_poolp));
1413
1414     PL_perl_destruct_level = 2;
1415     MUTEX_INIT(&MY_POOL.create_destruct_mutex);
1416     MUTEX_LOCK(&MY_POOL.create_destruct_mutex);
1417
1418     PL_threadhook = &Perl_ithread_hook;
1419
1420     MY_POOL.tid_counter = 1;
1421 #  ifdef THREAD_CREATE_NEEDS_STACK
1422     MY_POOL.default_stack_size = THREAD_CREATE_NEEDS_STACK;
1423 #  endif
1424
1425     /* The 'main' thread is thread 0.
1426      * It is detached (unjoinable) and immortal.
1427      */
1428
1429     MUTEX_INIT(&MY_POOL.main_thread.mutex);
1430
1431     /* Head of the threads list */
1432     MY_POOL.main_thread.next = &MY_POOL.main_thread;
1433     MY_POOL.main_thread.prev = &MY_POOL.main_thread;
1434
1435     MY_POOL.main_thread.count = 1;                  /* Immortal */
1436
1437     MY_POOL.main_thread.interp = aTHX;
1438     MY_POOL.main_thread.state = PERL_ITHR_DETACHED; /* Detached */
1439     MY_POOL.main_thread.stack_size = MY_POOL.default_stack_size;
1440 #  ifdef WIN32
1441     MY_POOL.main_thread.thr = GetCurrentThreadId();
1442 #  else
1443     MY_POOL.main_thread.thr = pthread_self();
1444 #  endif
1445
1446     S_ithread_set(aTHX_ &MY_POOL.main_thread);
1447     MUTEX_UNLOCK(&MY_POOL.create_destruct_mutex);
1448 #endif /* USE_ITHREADS */
1449 }