1 #define PERL_NO_GET_CONTEXT
10 #include <win32thread.h>
11 #define PERL_THREAD_SETSPECIFIC(k,v) TlsSetValue(k,v)
12 #define PERL_THREAD_GETSPECIFIC(k,v) v = TlsGetValue(k)
13 #define PERL_THREAD_ALLOC_SPECIFIC(k) \
15 if((k = TlsAlloc()) == TLS_OUT_OF_INDEXES) {\
16 PerlIO_printf(PerlIO_stderr(), "panic threads.xs: TlsAlloc");\
22 typedef perl_os_thread pthread_t;
28 #define PERL_THREAD_SETSPECIFIC(k,v) pthread_setspecific(k,v)
29 #ifdef OLD_PTHREADS_API
30 #define PERL_THREAD_DETACH(t) pthread_detach(&(t))
31 #define PERL_THREAD_GETSPECIFIC(k,v) pthread_getspecific(k,&v)
32 #define PERL_THREAD_ALLOC_SPECIFIC(k) STMT_START {\
33 if(pthread_keycreate(&(k),0)) {\
34 PerlIO_printf(PerlIO_stderr(), "panic threads.xs: pthread_key_create");\
39 #define PERL_THREAD_DETACH(t) pthread_detach((t))
40 #define PERL_THREAD_GETSPECIFIC(k,v) v = pthread_getspecific(k)
41 #define PERL_THREAD_ALLOC_SPECIFIC(k) STMT_START {\
42 if(pthread_key_create(&(k),0)) {\
43 PerlIO_printf(PerlIO_stderr(), "panic threads.xs: pthread_key_create");\
50 /* Values for 'state' member */
51 #define PERL_ITHR_JOINABLE 0
52 #define PERL_ITHR_DETACHED 1
53 #define PERL_ITHR_FINISHED 4
54 #define PERL_ITHR_JOINED 2
56 typedef struct ithread_s {
57 struct ithread_s *next; /* Next thread in the list */
58 struct ithread_s *prev; /* Prev thread in the list */
59 PerlInterpreter *interp; /* The threads interpreter */
60 I32 tid; /* Threads module's thread id */
61 perl_mutex mutex; /* Mutex for updating things in this struct */
62 I32 count; /* How many SVs have a reference to us */
63 signed char state; /* Are we detached ? */
64 int gimme; /* Context of create */
65 SV* init_function; /* Code to run */
66 SV* params; /* Args to pass function */
68 DWORD thr; /* OS's idea if thread id */
69 HANDLE handle; /* OS's waitable handle */
71 pthread_t thr; /* OS's handle for the thread */
77 /* Macros to supply the aTHX_ in an embed.h like manner */
78 #define ithread_join(thread) Perl_ithread_join(aTHX_ thread)
79 #define ithread_DESTROY(thread) Perl_ithread_DESTROY(aTHX_ thread)
80 #define ithread_CLONE(thread) Perl_ithread_CLONE(aTHX_ thread)
81 #define ithread_detach(thread) Perl_ithread_detach(aTHX_ thread)
82 #define ithread_tid(thread) ((thread)->tid)
83 #define ithread_yield(thread) (YIELD);
85 static perl_mutex create_destruct_mutex; /* protects the creation and destruction of threads*/
88 I32 known_threads = 0;
89 I32 active_threads = 0;
93 * Clear up after thread is done with
96 Perl_ithread_destruct (pTHX_ ithread* thread, const char *why)
98 MUTEX_LOCK(&thread->mutex);
100 Perl_croak(aTHX_ "panic: destruct destroyed thread %p (%s)",thread, why);
102 if (thread->count != 0) {
103 MUTEX_UNLOCK(&thread->mutex);
106 MUTEX_LOCK(&create_destruct_mutex);
107 /* Remove from circular list of threads */
108 if (thread->next == thread) {
109 /* last one should never get here ? */
113 thread->next->prev = thread->prev;
114 thread->prev->next = thread->next;
115 if (threads == thread) {
116 threads = thread->next;
122 assert( known_threads >= 0 );
124 Perl_warn(aTHX_ "destruct %d @ %p by %p now %d",
125 thread->tid,thread->interp,aTHX, known_threads);
127 MUTEX_UNLOCK(&create_destruct_mutex);
128 /* Thread is now disowned */
131 dTHXa(thread->interp);
132 ithread* current_thread;
136 PERL_SET_CONTEXT(thread->interp);
138 PERL_THREAD_GETSPECIFIC(self_key,ptr);
139 current_thread = (ithread *) ptr;
141 PERL_THREAD_GETSPECIFIC(self_key,current_thread);
143 PERL_THREAD_SETSPECIFIC(self_key,thread);
147 SvREFCNT_dec(thread->params);
151 thread->params = Nullsv;
152 perl_destruct(thread->interp);
153 perl_free(thread->interp);
154 thread->interp = NULL;
155 PERL_THREAD_SETSPECIFIC(self_key,current_thread);
158 MUTEX_UNLOCK(&thread->mutex);
159 MUTEX_DESTROY(&thread->mutex);
160 PerlMemShared_free(thread);
162 PERL_SET_CONTEXT(aTHX);
166 Perl_ithread_hook(pTHX)
168 int veto_cleanup = 0;
169 MUTEX_LOCK(&create_destruct_mutex);
170 if (aTHX == PL_curinterp && active_threads != 1) {
171 Perl_warn(aTHX_ "A thread exited while %" IVdf " threads were running",
175 MUTEX_UNLOCK(&create_destruct_mutex);
180 Perl_ithread_detach(pTHX_ ithread *thread)
182 MUTEX_LOCK(&thread->mutex);
183 if (!(thread->state & (PERL_ITHR_DETACHED|PERL_ITHR_JOINED))) {
184 thread->state |= PERL_ITHR_DETACHED;
186 CloseHandle(thread->handle);
189 PERL_THREAD_DETACH(thread->thr);
192 if ((thread->state & PERL_ITHR_FINISHED) &&
193 (thread->state & PERL_ITHR_DETACHED)) {
194 MUTEX_UNLOCK(&thread->mutex);
195 Perl_ithread_destruct(aTHX_ thread, "detach");
198 MUTEX_UNLOCK(&thread->mutex);
202 /* MAGIC (in mg.h sense) hooks */
205 ithread_mg_get(pTHX_ SV *sv, MAGIC *mg)
207 ithread *thread = (ithread *) mg->mg_ptr;
208 SvIVX(sv) = PTR2IV(thread);
214 ithread_mg_free(pTHX_ SV *sv, MAGIC *mg)
216 ithread *thread = (ithread *) mg->mg_ptr;
217 MUTEX_LOCK(&thread->mutex);
219 if (thread->count == 0) {
220 if(thread->state & PERL_ITHR_FINISHED &&
221 (thread->state & PERL_ITHR_DETACHED ||
222 thread->state & PERL_ITHR_JOINED))
224 MUTEX_UNLOCK(&thread->mutex);
225 Perl_ithread_destruct(aTHX_ thread, "no reference");
228 MUTEX_UNLOCK(&thread->mutex);
232 MUTEX_UNLOCK(&thread->mutex);
238 ithread_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
240 ithread *thread = (ithread *) mg->mg_ptr;
241 MUTEX_LOCK(&thread->mutex);
243 MUTEX_UNLOCK(&thread->mutex);
247 MGVTBL ithread_vtbl = {
248 ithread_mg_get, /* get */
252 ithread_mg_free, /* free */
254 ithread_mg_dup /* dup */
259 * Starts executing the thread. Needs to clean up memory a tad better.
260 * Passed as the C level function to run in the new thread
265 Perl_ithread_run(LPVOID arg) {
268 Perl_ithread_run(void * arg) {
270 ithread* thread = (ithread*) arg;
271 dTHXa(thread->interp);
272 PERL_SET_CONTEXT(thread->interp);
273 PERL_THREAD_SETSPECIFIC(self_key,thread);
276 /* Far from clear messing with ->thr child-side is a good idea */
277 MUTEX_LOCK(&thread->mutex);
279 thread->thr = GetCurrentThreadId();
281 thread->thr = pthread_self();
283 MUTEX_UNLOCK(&thread->mutex);
286 PL_perl_destruct_level = 2;
289 AV* params = (AV*) SvRV(thread->params);
290 I32 len = av_len(params)+1;
296 for(i = 0; i < len; i++) {
297 XPUSHs(av_shift(params));
300 len = call_sv(thread->init_function, thread->gimme|G_EVAL);
303 for (i=len-1; i >= 0; i--) {
305 av_store(params, i, SvREFCNT_inc(sv));
308 Perl_warn(aTHX_ "thread failed to start: %" SVf, ERRSV);
312 SvREFCNT_dec(thread->init_function);
315 PerlIO_flush((PerlIO*)NULL);
316 MUTEX_LOCK(&thread->mutex);
317 thread->state |= PERL_ITHR_FINISHED;
319 if (thread->state & PERL_ITHR_DETACHED) {
320 MUTEX_UNLOCK(&thread->mutex);
321 Perl_ithread_destruct(aTHX_ thread, "detached finish");
323 MUTEX_UNLOCK(&thread->mutex);
325 MUTEX_LOCK(&create_destruct_mutex);
327 assert( active_threads >= 0 );
328 MUTEX_UNLOCK(&create_destruct_mutex);
338 ithread_to_SV(pTHX_ SV *obj, ithread *thread, char *classname, bool inc)
343 MUTEX_LOCK(&thread->mutex);
345 MUTEX_UNLOCK(&thread->mutex);
349 sv = newSVrv(obj,classname);
350 sv_setiv(sv,PTR2IV(thread));
351 mg = sv_magicext(sv,Nullsv,PERL_MAGIC_shared_scalar,&ithread_vtbl,(char *)thread,0);
352 mg->mg_flags |= MGf_DUP;
358 SV_to_ithread(pTHX_ SV *sv)
366 thread = INT2PTR(ithread*, SvIV(SvRV(sv)));
371 PERL_THREAD_GETSPECIFIC(self_key,ptr);
372 thread = (ithread *) ptr;
374 PERL_THREAD_GETSPECIFIC(self_key,thread);
381 * ithread->create(); ( aka ithread->new() )
382 * Called in context of parent thread
386 Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* params)
389 CLONE_PARAMS clone_param;
390 ithread* current_thread;
392 SV** tmps_tmp = PL_tmps_stack;
393 I32 tmps_ix = PL_tmps_ix;
395 PERL_THREAD_GETSPECIFIC(self_key,current_thread);
396 MUTEX_LOCK(&create_destruct_mutex);
397 thread = PerlMemShared_malloc(sizeof(ithread));
398 Zero(thread,1,ithread);
399 thread->next = threads;
400 thread->prev = threads->prev;
401 threads->prev = thread;
402 thread->prev->next = thread;
403 /* Set count to 1 immediately in case thread exits before
404 * we return to caller !
407 MUTEX_INIT(&thread->mutex);
408 thread->tid = tid_counter++;
409 thread->gimme = GIMME_V;
411 /* "Clone" our interpreter into the thread's interpreter
412 * This gives thread access to "static data" and code.
415 PerlIO_flush((PerlIO*)NULL);
416 PERL_THREAD_SETSPECIFIC(self_key,thread);
418 SAVEBOOL(PL_srand_called); /* Save this so it becomes the correct
420 PL_srand_called = FALSE; /* Set it to false so we can detect
421 if it gets set during the clone */
424 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
426 thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE);
428 /* perl_clone leaves us in new interpreter's context.
429 As it is tricky to spot an implicit aTHX, create a new scope
430 with aTHX matching the context for the duration of
431 our work for new interpreter.
434 dTHXa(thread->interp);
436 /* Here we remove END blocks since they should only run
437 in the thread they are created
439 SvREFCNT_dec(PL_endav);
441 clone_param.flags = 0;
442 thread->init_function = sv_dup(init_function, &clone_param);
443 if (SvREFCNT(thread->init_function) == 0) {
444 SvREFCNT_inc(thread->init_function);
449 thread->params = sv_dup(params, &clone_param);
450 SvREFCNT_inc(thread->params);
453 /* The code below checks that anything living on
454 the tmps stack and has been cloned (so it lives in the
455 ptr_table) has a refcount higher than 0
457 If the refcount is 0 it means that a something on the
458 stack/context was holding a reference to it and
459 since we init_stacks() in perl_clone that won't get
460 cleaned and we will get a leaked scalar.
461 The reason it was cloned was that it lived on the
464 Example of this can be found in bugreport 15837
465 where calls in the parameter list end up as a temp
467 One could argue that this fix should be in perl_clone
471 while (tmps_ix > 0) {
472 SV* sv = (SV*)ptr_table_fetch(PL_ptr_table, tmps_tmp[tmps_ix]);
474 if (sv && SvREFCNT(sv) == 0) {
482 SvTEMP_off(thread->init_function);
483 ptr_table_free(PL_ptr_table);
485 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
487 PERL_THREAD_SETSPECIFIC(self_key,current_thread);
488 PERL_SET_CONTEXT(aTHX);
490 /* Start the thread */
494 thread->handle = CreateThread(NULL, 0, Perl_ithread_run,
495 (LPVOID)thread, 0, &thread->thr);
499 static pthread_attr_t attr;
500 static int attr_inited = 0;
501 static int attr_joinable = PTHREAD_CREATE_JOINABLE;
504 pthread_attr_init(&attr);
506 # ifdef PTHREAD_ATTR_SETDETACHSTATE
507 PTHREAD_ATTR_SETDETACHSTATE(&attr, attr_joinable);
509 # ifdef THREAD_CREATE_NEEDS_STACK
510 if(pthread_attr_setstacksize(&attr, THREAD_CREATE_NEEDS_STACK))
511 Perl_croak(aTHX_ "panic: pthread_attr_setstacksize failed");
514 #ifdef OLD_PTHREADS_API
515 pthread_create( &thread->thr, attr, Perl_ithread_run, (void *)thread);
517 # if defined(HAS_PTHREAD_ATTR_SETSCOPE) && defined(PTHREAD_SCOPE_SYSTEM)
518 pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
520 pthread_create( &thread->thr, &attr, Perl_ithread_run, (void *)thread);
526 MUTEX_UNLOCK(&create_destruct_mutex);
529 return ithread_to_SV(aTHX_ obj, thread, classname, FALSE);
533 Perl_ithread_self (pTHX_ SV *obj, char* Class)
538 PERL_THREAD_GETSPECIFIC(self_key,ptr);
539 thread = (ithread *) ptr;
541 PERL_THREAD_GETSPECIFIC(self_key,thread);
544 return ithread_to_SV(aTHX_ obj, thread, Class, TRUE);
546 Perl_croak(aTHX_ "panic: cannot find thread data");
550 * Joins the thread this code needs to take the returnvalue from the
551 * call_sv and send it back
555 Perl_ithread_CLONE(pTHX_ SV *obj)
559 ithread *thread = SV_to_ithread(aTHX_ obj);
563 Perl_warn(aTHX_ "CLONE %" SVf,obj);
568 Perl_ithread_join(pTHX_ SV *obj)
570 ithread *thread = SV_to_ithread(aTHX_ obj);
571 MUTEX_LOCK(&thread->mutex);
572 if (thread->state & PERL_ITHR_DETACHED) {
573 MUTEX_UNLOCK(&thread->mutex);
574 Perl_croak(aTHX_ "Cannot join a detached thread");
576 else if (thread->state & PERL_ITHR_JOINED) {
577 MUTEX_UNLOCK(&thread->mutex);
578 Perl_croak(aTHX_ "Thread already joined");
587 MUTEX_UNLOCK(&thread->mutex);
589 waitcode = WaitForSingleObject(thread->handle, INFINITE);
591 pthread_join(thread->thr,&retval);
593 MUTEX_LOCK(&thread->mutex);
595 /* sv_dup over the args */
597 ithread* current_thread;
598 AV* params = (AV*) SvRV(thread->params);
599 CLONE_PARAMS clone_params;
600 clone_params.stashes = newAV();
601 clone_params.flags |= CLONEf_JOIN_IN;
602 PL_ptr_table = ptr_table_new();
603 PERL_THREAD_GETSPECIFIC(self_key,current_thread);
604 PERL_THREAD_SETSPECIFIC(self_key,thread);
608 I32 len = av_len(params)+1;
610 for(i = 0; i < len; i++) {
611 sv_dump(SvRV(AvARRAY(params)[i]));
615 retparam = (AV*) sv_dup((SV*)params, &clone_params);
618 I32 len = av_len(retparam)+1;
620 for(i = 0; i < len; i++) {
621 sv_dump(SvRV(AvARRAY(retparam)[i]));
625 PERL_THREAD_SETSPECIFIC(self_key,current_thread);
626 SvREFCNT_dec(clone_params.stashes);
627 SvREFCNT_inc(retparam);
628 ptr_table_free(PL_ptr_table);
632 /* We are finished with it */
633 thread->state |= PERL_ITHR_JOINED;
634 MUTEX_UNLOCK(&thread->mutex);
642 Perl_ithread_DESTROY(pTHX_ SV *sv)
644 ithread *thread = SV_to_ithread(aTHX_ sv);
645 sv_unmagic(SvRV(sv),PERL_MAGIC_shared_scalar);
648 #endif /* USE_ITHREADS */
650 MODULE = threads PACKAGE = threads PREFIX = ithread_
656 ithread_new (classname, function_to_call, ...)
658 SV * function_to_call
661 AV* params = newAV();
664 for(i = 2; i < items ; i++) {
665 av_push(params, SvREFCNT_inc(ST(i)));
668 ST(0) = sv_2mortal(Perl_ithread_create(aTHX_ Nullsv, classname, function_to_call, newRV_noinc((SV*) params)));
673 ithread_list(char *classname)
676 ithread *curr_thread;
677 MUTEX_LOCK(&create_destruct_mutex);
678 curr_thread = threads;
679 if(curr_thread->tid != 0)
680 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
682 curr_thread = curr_thread->next;
683 if(curr_thread == threads)
685 if(curr_thread->state & PERL_ITHR_DETACHED ||
686 curr_thread->state & PERL_ITHR_JOINED)
688 XPUSHs( sv_2mortal(ithread_to_SV(aTHX_ NULL, curr_thread, classname, TRUE)));
690 MUTEX_UNLOCK(&create_destruct_mutex);
695 ithread_self(char *classname)
698 ST(0) = sv_2mortal(Perl_ithread_self(aTHX_ Nullsv,classname));
703 ithread_tid(ithread *thread)
706 ithread_join(SV *obj)
709 AV* params = Perl_ithread_join(aTHX_ obj);
711 I32 len = AvFILL(params);
712 for (i = 0; i <= len; i++) {
713 SV* tmp = av_shift(params);
717 SvREFCNT_dec(params);
729 ithread_detach(ithread *thread)
732 ithread_DESTROY(SV *thread)
734 #endif /* USE_ITHREADS */
740 PL_perl_destruct_level = 2;
741 PERL_THREAD_ALLOC_SPECIFIC(self_key);
742 MUTEX_INIT(&create_destruct_mutex);
743 MUTEX_LOCK(&create_destruct_mutex);
744 PL_threadhook = &Perl_ithread_hook;
745 thread = PerlMemShared_malloc(sizeof(ithread));
746 Zero(thread,1,ithread);
747 PL_perl_destruct_level = 2;
748 MUTEX_INIT(&thread->mutex);
750 thread->next = thread;
751 thread->prev = thread;
752 thread->interp = aTHX;
753 thread->count = 1; /* Immortal. */
754 thread->tid = tid_counter++;
757 thread->state = PERL_ITHR_DETACHED;
759 thread->thr = GetCurrentThreadId();
761 thread->thr = pthread_self();
764 PERL_THREAD_SETSPECIFIC(self_key,thread);
765 MUTEX_UNLOCK(&create_destruct_mutex);
766 #endif /* USE_ITHREADS */