10 Starts executing the thread. Needs to clean up memory a tad better.
14 THREAD_RET_TYPE Perl_thread_run(LPVOID arg) {
16 void* Perl_thread_run(void * arg) {
18 ithread* thread = (ithread*) arg;
21 dTHXa(thread->interp);
22 PERL_SET_CONTEXT(thread->interp);
25 thread->thr = GetCurrentThreadId();
27 thread->thr = pthread_self();
30 SHAREDSvLOCK(threads);
31 SHAREDSvEDIT(threads);
32 thread_tid_ptr = Perl_newSViv(PL_sharedsv_space, (IV) thread->thr);
33 thread_ptr = Perl_newSViv(PL_sharedsv_space, (IV) thread);
34 hv_store_ent((HV*)SHAREDSvGET(threads), thread_tid_ptr, thread_ptr,0);
35 SvREFCNT_dec(thread_tid_ptr);
36 SHAREDSvRELEASE(threads);
37 SHAREDSvUNLOCK(threads);
38 PL_perl_destruct_level = 2;
46 params = (AV*) SvRV(thread->params);
52 for(i = 0; i < len + 1; i++) {
53 XPUSHs(av_shift(params));
57 call_sv(thread->init_function, G_DISCARD);
66 MUTEX_LOCK(&thread->mutex);
67 perl_destruct(thread->interp);
68 perl_free(thread->interp);
69 if(thread->detached == 1) {
70 MUTEX_UNLOCK(&thread->mutex);
71 Perl_thread_destruct(thread);
73 MUTEX_UNLOCK(&thread->mutex);
89 SV* Perl_thread_create(char* class, SV* init_function, SV* params) {
90 ithread* thread = malloc(sizeof(ithread));
95 PerlInterpreter *current_perl;
97 MUTEX_LOCK(&create_mutex);
99 obj = newSVrv(obj_ref, class);
100 sv_setiv(obj, (IV)thread);
104 current_perl = PERL_GET_CONTEXT;
107 here we put the values of params and function to call onto namespace, this is so perl will properly clone them when we call perl_clone.
112 temp_store = Perl_get_sv(current_perl, "threads::paramtempstore", TRUE | GV_ADDMULTI);
113 Perl_sv_setsv(current_perl, temp_store,params);
117 temp_store = Perl_get_sv(current_perl, "threads::calltempstore", TRUE | GV_ADDMULTI);
118 Perl_sv_setsv(current_perl,temp_store, init_function);
119 init_function = NULL;
124 thread->interp = perl_clone(current_perl,4);
126 thread->interp = perl_clone(current_perl,0);
129 thread->init_function = newSVsv(Perl_get_sv(thread->interp, "threads::calltempstore",FALSE));
130 thread->params = newSVsv(Perl_get_sv(thread->interp, "threads::paramtempstore",FALSE));
137 And here we make sure we clean up the data we put in the namespace of iThread, both in the new and the calling inteprreter
142 temp_store = Perl_get_sv(thread->interp,"threads::paramtempstore",FALSE);
143 Perl_sv_setsv(thread->interp,temp_store, &PL_sv_undef);
145 temp_store = Perl_get_sv(thread->interp,"threads::calltempstore",FALSE);
146 Perl_sv_setsv(thread->interp,temp_store, &PL_sv_undef);
148 PERL_SET_CONTEXT(current_perl);
150 temp_store = Perl_get_sv(current_perl,"threads::paramtempstore",FALSE);
151 Perl_sv_setsv(current_perl, temp_store, &PL_sv_undef);
153 temp_store = Perl_get_sv(current_perl,"threads::calltempstore",FALSE);
154 Perl_sv_setsv(current_perl, temp_store, &PL_sv_undef);
156 /* lets init the thread */
162 MUTEX_INIT(&thread->mutex);
163 thread->tid = tid_counter++;
164 thread->detached = 0;
169 thread->handle = CreateThread(NULL, 0, Perl_thread_run,
170 (LPVOID)thread, 0, &thread->thr);
173 pthread_create( &thread->thr, NULL, Perl_thread_run, thread);
175 MUTEX_UNLOCK(&create_mutex);
183 returns the id of the thread
185 I32 Perl_thread_tid (SV* obj) {
188 obj = Perl_thread_self(SvPV_nolen(obj));
189 thread = (ithread*)SvIV(SvRV(obj));
192 thread = (ithread*)SvIV(SvRV(obj));
197 SV* Perl_thread_self (char* class) {
204 PerlInterpreter *old_context = PERL_GET_CONTEXT;
208 SHAREDSvLOCK(threads);
209 SHAREDSvEDIT(threads);
211 thread_tid_ptr = Perl_newSViv(PL_sharedsv_space, (IV) GetCurrentThreadId());
213 thread_tid_ptr = Perl_newSViv(PL_sharedsv_space, (IV) pthread_self());
215 thread_entry = Perl_hv_fetch_ent(PL_sharedsv_space,(HV*) SHAREDSvGET(threads), thread_tid_ptr, 0,0);
216 thread_ptr = HeVAL(thread_entry);
217 SvREFCNT_dec(thread_tid_ptr);
218 SHAREDSvRELEASE(threads);
219 SHAREDSvUNLOCK(threads);
223 obj_ref = newSViv(0);
224 obj = newSVrv(obj_ref, class);
225 sv_setsv(obj, thread_ptr);
232 this code needs to take the returnvalue from the call_sv and send it back
235 void Perl_thread_join(SV* obj) {
236 ithread* thread = (ithread*)SvIV(SvRV(obj));
239 waitcode = WaitForSingleObject(thread->handle, INFINITE);
242 pthread_join(thread->thr,&retval);
249 needs to better clean up memory
252 void Perl_thread_detach(SV* obj) {
253 ithread* thread = (ithread*)SvIV(SvRV(obj));
254 MUTEX_LOCK(&thread->mutex);
255 thread->detached = 1;
257 pthread_detach(thread->thr);
259 MUTEX_UNLOCK(&thread->mutex);
264 void Perl_thread_DESTROY (SV* obj) {
265 ithread* thread = (ithread*)SvIV(SvRV(obj));
267 MUTEX_LOCK(&thread->mutex);
269 MUTEX_UNLOCK(&thread->mutex);
270 Perl_thread_destruct(thread);
274 void Perl_thread_destruct (ithread* thread) {
276 MUTEX_LOCK(&thread->mutex);
277 if(thread->count != 0) {
278 MUTEX_UNLOCK(&thread->mutex);
281 MUTEX_UNLOCK(&thread->mutex);
282 /* it is safe noone is holding a ref to this */
283 /*printf("proper destruction!\n");*/
287 MODULE = threads PACKAGE = threads
289 Perl_sharedsv_init(aTHX);
290 PL_perl_destruct_level = 2;
291 threads = Perl_sharedsv_new(aTHX);
292 SHAREDSvEDIT(threads);
293 SHAREDSvGET(threads) = (SV *)newHV();
294 SHAREDSvRELEASE(threads);
298 SV* temp = get_sv("threads::sharedsv_space", TRUE | GV_ADDMULTI);
299 SV* temp2 = newSViv((IV)PL_sharedsv_space );
300 sv_setsv( temp , temp2 );
303 ithread* thread = malloc(sizeof(ithread));
306 MUTEX_INIT(&thread->mutex);
309 thread->thr = GetCurrentThreadId();
311 thread->thr = pthread_self();
313 thread_tid_ptr = Perl_newSViv(PL_sharedsv_space, (IV) thread->thr);
314 thread_ptr = Perl_newSViv(PL_sharedsv_space, (IV) thread);
315 SHAREDSvEDIT(threads);
316 hv_store_ent((HV*) SHAREDSvGET(threads), thread_tid_ptr, thread_ptr,0);
317 SHAREDSvRELEASE(threads);
318 SvREFCNT_dec(thread_tid_ptr);
320 MUTEX_INIT(&create_mutex);
327 create (class, function_to_call, ...)
329 SV * function_to_call
331 AV* params = newAV();
334 for(i = 2; i < items ; i++) {
335 av_push(params, ST(i));
338 RETVAL = Perl_thread_create(class, function_to_call, newRV_noinc((SV*) params));
346 RETVAL = Perl_thread_self(class);
354 RETVAL = Perl_thread_tid(obj);
364 temp = PL_markstack_ptr++;
365 Perl_thread_join(obj);
366 if (PL_markstack_ptr != temp) {
367 /* truly void, because dXSARGS not invoked */
368 PL_markstack_ptr = temp;
369 XSRETURN_EMPTY; /* return empty stack */
371 /* must have used dXSARGS; list context implied */
372 return; /* assume stack size is correct */
380 temp = PL_markstack_ptr++;
381 Perl_thread_detach(obj);
382 if (PL_markstack_ptr != temp) {
383 /* truly void, because dXSARGS not invoked */
384 PL_markstack_ptr = temp;
385 XSRETURN_EMPTY; /* return empty stack */
387 /* must have used dXSARGS; list context implied */
388 return; /* assume stack size is correct */
400 temp = PL_markstack_ptr++;
401 Perl_thread_DESTROY(obj);
402 if (PL_markstack_ptr != temp) {
403 /* truly void, because dXSARGS not invoked */
404 PL_markstack_ptr = temp;
405 XSRETURN_EMPTY; /* return empty stack */
407 /* must have used dXSARGS; list context implied */
408 return; /* assume stack size is correct */