3 * Copyright (c) 2001, Larry Wall
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
12 * "Hand any two wizards a piece of rope and they would instinctively pull in
13 * opposite directions."
16 * Contributed by Arthur Bergman arthur@contiller.se
17 * pulled in the (an)other direction by Nick Ing-Simmons nick@ing-simmons.net
20 #define PERL_NO_GET_CONTEXT
25 #define SHAREDSvPTR(a) ((a)->sv)
28 * The shared things need an intepreter to live in ...
30 PerlInterpreter *PL_sharedsv_space; /* The shared sv space */
31 /* To access shared space we fake aTHX in this scope and thread's context */
32 #define SHARED_CONTEXT PERL_SET_CONTEXT((aTHX = PL_sharedsv_space))
34 /* So we need a way to switch back to the caller's context... */
35 /* So we declare _another_ copy of the aTHX variable ... */
36 #define dTHXc PerlInterpreter *caller_perl = aTHX
37 /* and use it to switch back */
38 #define CALLER_CONTEXT PERL_SET_CONTEXT((aTHX = caller_perl))
41 * Only one thread at a time is allowed to mess with shared space.
43 perl_mutex PL_sharedsv_space_mutex; /* Mutex protecting the shared sv space */
45 #define SHARED_LOCK MUTEX_LOCK(&PL_sharedsv_space_mutex)
46 #define SHARED_UNLOCK MUTEX_UNLOCK(&PL_sharedsv_space_mutex)
48 /* A common idiom is to acquire access and switch in ... */
49 #define SHARED_EDIT STMT_START { \
54 /* then switch out and release access. */
55 #define SHARED_RELEASE STMT_START { \
65 Shared SV is a structure for keeping the backend storage
68 Shared-ness really only needs the SV * - the rest is for locks.
69 (Which suggests further space optimization ... )
74 SV *sv; /* The actual SV - in shared space */
75 perl_mutex mutex; /* Our mutex */
76 perl_cond cond; /* Our condition variable */
77 perl_cond user_cond; /* For user-level conditions */
78 IV locks; /* Number of locks held */
79 PerlInterpreter *owner; /* Who owns the lock? */
82 /* The SV in shared-space has a back-pointer to the shared_sv
83 struct associated with it PERL_MAGIC_ext.
85 The vtable used has just one entry - when the SV goes away
86 we free the memory for the above.
91 sharedsv_shared_mg_free(pTHX_ SV *sv, MAGIC *mg)
93 shared_sv *shared = (shared_sv *) mg->mg_ptr;
95 PerlMemShared_free(shared);
102 MGVTBL sharedsv_shared_vtbl = {
107 sharedsv_shared_mg_free, /* free */
112 /* Access to shared things is heavily based on MAGIC - in mg.h/mg.c/sv.c sense */
114 /* In any thread that has access to a shared thing there is a "proxy"
115 for it in its own space which has 'MAGIC' associated which accesses
119 MGVTBL sharedsv_scalar_vtbl; /* scalars have this vtable */
120 MGVTBL sharedsv_array_vtbl; /* hashes and arrays have this - like 'tie' */
121 MGVTBL sharedsv_elem_vtbl; /* elements of hashes and arrays have this
122 _AS WELL AS_ the scalar magic */
124 /* The sharedsv_elem_vtbl associates the element with the array/hash and
125 the sharedsv_scalar_vtbl associates it with the value
128 =for apidoc sharedsv_find
130 Given a private side SV tries to find if a given SV has a shared backend,
131 by looking for the magic.
136 Perl_sharedsv_find(pTHX_ SV *sv)
142 if ((mg = mg_find(sv, PERL_MAGIC_tied))
143 && mg->mg_virtual == &sharedsv_array_vtbl) {
144 return (shared_sv *) mg->mg_ptr;
148 if ((mg = mg_find(sv, PERL_MAGIC_shared_scalar))
149 && mg->mg_virtual == &sharedsv_scalar_vtbl) {
150 return (shared_sv *) mg->mg_ptr;
157 * Almost all the pain is in this routine.
162 Perl_sharedsv_associate(pTHX_ SV **psv, SV *ssv, shared_sv *data)
164 /* First try and get global data structure */
168 if (aTHX == PL_sharedsv_space) {
169 croak("panic:Cannot associate from within shared space");
173 /* Try shared SV as 1st choice */
175 if (mg = mg_find(ssv, PERL_MAGIC_ext)) {
176 data = (shared_sv *) mg->mg_ptr;
179 /* Next try private SV */
180 if (!data && psv && *psv) {
181 data = Perl_sharedsv_find(aTHX_ *psv);
183 /* If neither of those then create a new one */
185 data = PerlMemShared_malloc(sizeof(shared_sv));
186 Zero(data,1,shared_sv);
187 MUTEX_INIT(&data->mutex);
188 COND_INIT(&data->cond);
189 COND_INIT(&data->user_cond);
195 ssv = SHAREDSvPTR(data);
197 /* If we know type allocate shared side SV */
198 if (psv && *psv && !ssv) {
201 sv_upgrade(ssv, SvTYPE(*psv));
202 /* Tag shared side SV with data pointer */
203 sv_magicext(ssv, ssv, PERL_MAGIC_ext, &sharedsv_shared_vtbl,
208 if (!SHAREDSvPTR(data))
209 SHAREDSvPTR(data) = ssv;
211 /* Now if requested allocate private SV */
212 if (psv && !*psv && ssv) {
214 sv_upgrade(sv, SvTYPE(SHAREDSvPTR(data)));
218 /* Finally if private SV exists check and add magic */
225 if (!(mg = mg_find(sv, PERL_MAGIC_tied))
226 || mg->mg_virtual != &sharedsv_array_vtbl) {
228 sv_unmagic(sv, PERL_MAGIC_tied);
229 mg = sv_magicext(sv, sv, PERL_MAGIC_tied, &sharedsv_array_vtbl,
231 mg->mg_flags |= (MGf_COPY|MGf_DUP);
236 if (!(mg = mg_find(sv, PERL_MAGIC_shared_scalar)) ||
237 mg->mg_virtual != &sharedsv_scalar_vtbl) {
239 sv_unmagic(sv, PERL_MAGIC_shared_scalar);
240 mg = sv_magicext(sv, Nullsv, PERL_MAGIC_shared_scalar,
241 &sharedsv_scalar_vtbl, (char *)data, 0);
242 mg->mg_flags |= (MGf_COPY|MGf_DUP);
252 Perl_sharedsv_free(pTHX_ shared_sv *shared)
257 SvREFCNT_dec(SHAREDSvPTR(shared));
263 Perl_sharedsv_share(pTHX_ SV *sv)
267 Perl_croak(aTHX_ "Cannot share globs yet");
271 Perl_croak(aTHX_ "Cannot share subs yet");
275 Perl_sharedsv_associate(aTHX_ &sv, 0, 0);
279 /* MAGIC (in mg.h sense) hooks */
282 sharedsv_scalar_mg_get(pTHX_ SV *sv, MAGIC *mg)
284 shared_sv *shared = (shared_sv *) mg->mg_ptr;
288 if (SHAREDSvPTR(shared)) {
289 if (SvROK(SHAREDSvPTR(shared))) {
290 SV *rv = newRV(Nullsv);
291 Perl_sharedsv_associate(aTHX_ &SvRV(rv), SvRV(SHAREDSvPTR(shared)), NULL);
295 sv_setsv(sv, SHAREDSvPTR(shared));
303 sharedsv_scalar_mg_set(pTHX_ SV *sv, MAGIC *mg)
306 shared_sv *shared = Perl_sharedsv_associate(aTHX_ &sv, Nullsv,
307 (shared_sv *) mg->mg_ptr);
312 shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(sv));
314 SV *tmp = newRV(SHAREDSvPTR(target));
315 sv_setsv(SHAREDSvPTR(shared), tmp);
323 sv_setsv(SHAREDSvPTR(shared), sv);
328 Perl_croak(aTHX_ "Invalid value for shared scalar");
334 sharedsv_scalar_mg_free(pTHX_ SV *sv, MAGIC *mg)
336 Perl_sharedsv_free(aTHX_ (shared_sv *) mg->mg_ptr);
341 * Called during cloning of new threads
344 sharedsv_scalar_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
346 shared_sv *shared = (shared_sv *) mg->mg_ptr;
348 SvREFCNT_inc(SHAREDSvPTR(shared));
353 MGVTBL sharedsv_scalar_vtbl = {
354 sharedsv_scalar_mg_get, /* get */
355 sharedsv_scalar_mg_set, /* set */
358 sharedsv_scalar_mg_free, /* free */
360 sharedsv_scalar_mg_dup /* dup */
363 /* Now the arrays/hashes stuff */
366 sharedsv_elem_mg_FETCH(pTHX_ SV *sv, MAGIC *mg)
369 shared_sv *shared = Perl_sharedsv_find(aTHX_ mg->mg_obj);
370 shared_sv *target = Perl_sharedsv_find(aTHX_ sv);
374 if (SvTYPE(SHAREDSvPTR(shared)) == SVt_PVAV) {
375 svp = av_fetch((AV*) SHAREDSvPTR(shared), mg->mg_len, 0);
378 svp = hv_fetch((HV*) SHAREDSvPTR(shared), mg->mg_ptr, mg->mg_len, 0);
382 if (SHAREDSvPTR(target) != *svp) {
383 if (SHAREDSvPTR(target)) {
384 SvREFCNT_dec(SHAREDSvPTR(target));
386 SHAREDSvPTR(target) = SvREFCNT_inc(*svp);
390 if (SHAREDSvPTR(target)) {
391 SvREFCNT_dec(SHAREDSvPTR(target));
393 SHAREDSvPTR(target) = Nullsv;
400 sharedsv_elem_mg_STORE(pTHX_ SV *sv, MAGIC *mg)
403 shared_sv *shared = Perl_sharedsv_find(aTHX_ mg->mg_obj);
404 shared_sv *target = Perl_sharedsv_associate(aTHX_ &sv, Nullsv, 0);
405 /* Theory - SV itself is magically shared - and we have ordered the
406 magic such that by the time we get here it has been stored
407 to its shared counterpart
410 if (SvTYPE(SHAREDSvPTR(shared)) == SVt_PVAV) {
411 av_store((AV*) SHAREDSvPTR(shared), mg->mg_len, SHAREDSvPTR(target));
414 hv_store((HV*) SHAREDSvPTR(shared), mg->mg_ptr, mg->mg_len,
415 SHAREDSvPTR(target), 0);
422 sharedsv_elem_mg_DELETE(pTHX_ SV *sv, MAGIC *mg)
425 shared_sv *shared = Perl_sharedsv_find(aTHX_ mg->mg_obj);
428 if (SvTYPE(SHAREDSvPTR(shared)) == SVt_PVAV) {
429 ssv = av_delete((AV*) SHAREDSvPTR(shared), mg->mg_len, 0);
432 ssv = hv_delete((HV*) SHAREDSvPTR(shared), mg->mg_ptr, mg->mg_len, 0);
435 /* It is no longer in the array - so remove that magic */
436 sv_unmagic(sv, PERL_MAGIC_tiedelem);
437 Perl_sharedsv_associate(aTHX_ &sv, ssv, 0);
443 sharedsv_elem_mg_free(pTHX_ SV *sv, MAGIC *mg)
445 Perl_sharedsv_free(aTHX_ Perl_sharedsv_find(aTHX_ mg->mg_obj));
450 sharedsv_elem_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
452 shared_sv *shared = Perl_sharedsv_find(aTHX_ mg->mg_obj);
453 SvREFCNT_inc(SHAREDSvPTR(shared));
454 mg->mg_flags |= MGf_DUP;
458 MGVTBL sharedsv_elem_vtbl = {
459 sharedsv_elem_mg_FETCH, /* get */
460 sharedsv_elem_mg_STORE, /* set */
462 sharedsv_elem_mg_DELETE, /* clear */
463 sharedsv_elem_mg_free, /* free */
465 sharedsv_elem_mg_dup /* dup */
469 sharedsv_array_mg_FETCHSIZE(pTHX_ SV *sv, MAGIC *mg)
472 shared_sv *shared = (shared_sv *) mg->mg_ptr;
475 if (SvTYPE(SHAREDSvPTR(shared)) == SVt_PVAV) {
476 val = av_len((AV*) SHAREDSvPTR(shared));
479 /* not actually defined by tie API but ... */
480 val = HvKEYS((HV*) SHAREDSvPTR(shared));
487 sharedsv_array_mg_CLEAR(pTHX_ SV *sv, MAGIC *mg)
490 shared_sv *shared = (shared_sv *) mg->mg_ptr;
492 if (SvTYPE(SHAREDSvPTR(shared)) == SVt_PVAV) {
493 av_clear((AV*) SHAREDSvPTR(shared));
496 hv_clear((HV*) SHAREDSvPTR(shared));
503 sharedsv_array_mg_free(pTHX_ SV *sv, MAGIC *mg)
505 Perl_sharedsv_free(aTHX_ (shared_sv *) mg->mg_ptr);
510 * This is called when perl is about to access an element of
514 sharedsv_array_mg_copy(pTHX_ SV *sv, MAGIC* mg,
515 SV *nsv, const char *name, int namlen)
517 shared_sv *shared = (shared_sv *) mg->mg_ptr;
518 MAGIC *nmg = sv_magicext(nsv,mg->mg_obj,
519 toLOWER(mg->mg_type),&sharedsv_elem_vtbl,
521 nmg->mg_flags |= MGf_DUP;
523 /* Maybe do this to associate shared value immediately ? */
524 sharedsv_elem_FIND(aTHX_ nsv, nmg);
530 sharedsv_array_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param)
532 shared_sv *shared = (shared_sv *) mg->mg_ptr;
533 SvREFCNT_inc(SHAREDSvPTR(shared));
534 mg->mg_flags |= MGf_DUP;
538 MGVTBL sharedsv_array_vtbl = {
541 sharedsv_array_mg_FETCHSIZE, /* len */
542 sharedsv_array_mg_CLEAR, /* clear */
543 sharedsv_array_mg_free, /* free */
544 sharedsv_array_mg_copy, /* copy */
545 sharedsv_array_mg_dup /* dup */
548 =for apidoc sharedsv_unlock
550 Recursively unlocks a shared sv.
555 Perl_sharedsv_unlock(pTHX_ shared_sv* ssv)
557 MUTEX_LOCK(&ssv->mutex);
558 if (ssv->owner != aTHX) {
559 Perl_croak(aTHX_ "panic: Perl_sharedsv_unlock unlocking mutex that we don't own");
560 MUTEX_UNLOCK(&ssv->mutex);
564 if (--ssv->locks == 0) {
566 COND_SIGNAL(&ssv->cond);
568 MUTEX_UNLOCK(&ssv->mutex);
572 Perl_sharedsv_unlock_scope(pTHX_ shared_sv* ssv)
574 MUTEX_LOCK(&ssv->mutex);
575 if (ssv->owner != aTHX) {
576 MUTEX_UNLOCK(&ssv->mutex);
581 COND_SIGNAL(&ssv->cond);
582 MUTEX_UNLOCK(&ssv->mutex);
585 =for apidoc sharedsv_lock
587 Recursive locks on a sharedsv.
588 Locks are dynamically scoped at the level of the first lock.
593 Perl_sharedsv_lock(pTHX_ shared_sv* ssv)
597 MUTEX_LOCK(&ssv->mutex);
598 if (ssv->owner && ssv->owner == aTHX) {
600 MUTEX_UNLOCK(&ssv->mutex);
604 COND_WAIT(&ssv->cond,&ssv->mutex);
608 SAVEDESTRUCTOR_X(Perl_sharedsv_unlock_scope,ssv);
609 MUTEX_UNLOCK(&ssv->mutex);
613 Perl_sharedsv_locksv(pTHX_ SV *sv)
615 Perl_sharedsv_lock(aTHX_ Perl_sharedsv_find(aTHX_ sv));
618 =head1 Shared SV Functions
620 =for apidoc sharedsv_init
622 Saves a space for keeping SVs wider than an interpreter,
623 currently only stores a pointer to the first interpreter.
628 Perl_sharedsv_init(pTHX)
631 /* This pair leaves us in shared context ... */
632 PL_sharedsv_space = perl_alloc();
633 perl_construct(PL_sharedsv_space);
635 MUTEX_INIT(&PL_sharedsv_space_mutex);
636 PL_lockhook = &Perl_sharedsv_locksv;
637 PL_sharehook = &Perl_sharedsv_share;
640 /* Accessor to convert threads::shared::tie objects back shared_sv * */
642 SV_to_sharedsv(pTHX_ SV *sv)
644 shared_sv *shared = 0;
647 shared = INT2PTR(shared_sv *, SvIV(SvRV(sv)));
652 MODULE = threads::shared PACKAGE = threads::shared::tie
657 PUSH(shared_sv *shared, ...)
662 for(i = 1; i < items; i++) {
663 SV* tmp = newSVsv(ST(i));
664 shared_sv *target = Perl_sharedsv_associate(aTHX_ &tmp, Nullsv, 0);
666 av_push((AV*) SHAREDSvPTR(shared), SHAREDSvPTR(target));
673 UNSHIFT(shared_sv *shared, ...)
679 av_unshift((AV*)SHAREDSvPTR(shared), items - 1);
681 for(i = 1; i < items; i++) {
682 SV* tmp = newSVsv(ST(i));
683 shared_sv *target = Perl_sharedsv_associate(aTHX_ &tmp, Nullsv, 0);
685 av_store((AV*) SHAREDSvPTR(shared), i - 1, SHAREDSvPTR(target));
692 POP(shared_sv *shared)
698 sv = av_pop((AV*)SHAREDSvPTR(shared));
701 Perl_sharedsv_associate(aTHX_ &ST(0), sv, 0);
706 SHIFT(shared_sv *shared)
712 sv = av_shift((AV*)SHAREDSvPTR(shared));
715 Perl_sharedsv_associate(aTHX_ &ST(0), sv, 0);
720 EXTEND(shared_sv *shared, IV count)
724 av_extend((AV*)SHAREDSvPTR(shared), count);
728 EXISTS(shared_sv *shared, SV *index)
733 if (SvTYPE(SHAREDSvPTR(shared)) == SVt_PVAV) {
734 exists = av_exists((AV*) SHAREDSvPTR(shared), SvIV(index));
737 exists = hv_exists_ent((HV*) SHAREDSvPTR(shared), index, 0);
740 ST(0) = (exists) ? &PL_sv_yes : &PL_sv_no;
744 STORESIZE(shared_sv *shared,IV count)
748 av_fill((AV*) SHAREDSvPTR(shared), count);
752 FIRSTKEY(shared_sv *shared)
760 hv_iterinit((HV*) SHAREDSvPTR(shared));
761 entry = hv_iternext((HV*) SHAREDSvPTR(shared));
763 key = hv_iterkey(entry,&len);
765 ST(0) = sv_2mortal(newSVpv(key, len));
768 ST(0) = &PL_sv_undef;
774 NEXTKEY(shared_sv *shared, SV *oldkey)
782 entry = hv_iternext((HV*) SHAREDSvPTR(shared));
784 key = hv_iterkey(entry,&len);
786 ST(0) = sv_2mortal(newSVpv(key, len));
789 ST(0) = &PL_sv_undef;
794 MODULE = threads::shared PACKAGE = threads::shared
799 lock_enabled(SV *ref)
805 shared = Perl_sharedsv_find(aTHX, ref);
807 croak("lock can only be used on shared values");
808 Perl_sharedsv_lock(aTHX_ shared);
811 cond_wait_enabled(SV *ref)
818 shared = Perl_sharedsv_find(aTHX_ ref);
820 croak("cond_wait can only be used on shared values");
821 if(shared->owner != aTHX)
822 croak("You need a lock before you can cond_wait");
823 MUTEX_LOCK(&shared->mutex);
824 shared->owner = NULL;
825 locks = shared->locks = 0;
826 COND_WAIT(&shared->user_cond, &shared->mutex);
827 shared->owner = aTHX;
828 shared->locks = locks;
829 MUTEX_UNLOCK(&shared->mutex);
832 cond_signal_enabled(SV *ref)
838 shared = Perl_sharedsv_find(aTHX_ ref);
840 croak("cond_signal can only be used on shared values");
841 COND_SIGNAL(&shared->user_cond);
844 cond_broadcast_enabled(SV *ref)
850 shared = Perl_sharedsv_find(aTHX_ ref);
852 croak("cond_broadcast can only be used on shared values");
853 COND_BROADCAST(&shared->user_cond);
857 Perl_sharedsv_init(aTHX);