From 11343788cbaaede18e3146b5219d2fbdaeaf516e Mon Sep 17 00:00:00 2001 From: Malcolm Beattie Date: Fri, 28 Mar 1997 18:40:44 +0000 Subject: Initial 3-way merge from (5.001m, thr1m, 5.003) plus fixups. p4raw-id: //depot/thrperl@4 --- pp_hot.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 154 insertions(+), 3 deletions(-) (limited to 'pp_hot.c') diff --git a/pp_hot.c b/pp_hot.c index 8fe39f37f7..b143ff72c3 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -20,6 +20,43 @@ /* Hot code. */ +#ifdef USE_THREADS +static void +unset_cvowner(cvarg) +void *cvarg; +{ + register CV* cv = (CV *) cvarg; +#ifdef DEBUGGING + dTHR; +#endif /* DEBUGGING */ + + DEBUG_L((fprintf(stderr, "0x%lx unsetting CvOWNER of 0x%lx:%s\n", + (unsigned long)thr, (unsigned long)cv, SvPEEK((SV*)cv)))); + MUTEX_LOCK(CvMUTEXP(cv)); + assert(CvDEPTH(cv) == 0); + assert(thr == CvOWNER(cv)); + CvOWNER(cv) = 0; + if (CvCONDP(cv)) + COND_SIGNAL(CvCONDP(cv)); /* next please */ + MUTEX_UNLOCK(CvMUTEXP(cv)); + SvREFCNT_dec(cv); +} + +#if 0 +void +mutex_unlock(m) +void *m; +{ +#ifdef DEBUGGING + dTHR; + DEBUG_L((fprintf(stderr, "0x%lx unlocking mutex 0x%lx\n", + (unsigned long) thr, (unsigned long) m))); +#endif /* DEBUGGING */ + MUTEX_UNLOCK((pthread_mutex_t *) m); +} +#endif +#endif /* USE_THREADS */ + PP(pp_const) { dSP; @@ -932,6 +969,7 @@ ret_no: OP * do_readline() { + dTHR; dSP; dTARGETSTACKED; register SV *sv; STRLEN tmplen = 0; @@ -1733,6 +1771,119 @@ PP(pp_entersub) DIE("No DBsub routine"); } +#ifdef USE_THREADS + MUTEX_LOCK(CvMUTEXP(cv)); + if (!CvCONDP(cv)) { +#ifdef DEBUGGING + DEBUG_L((fprintf(stderr, "0x%lx entering fast %s\n", + (unsigned long)thr, SvPEEK((SV*)cv)))); +#endif /* DEBUGGING */ + MUTEX_UNLOCK(CvMUTEXP(cv)); /* fast sub wants neither sync nor clone */ + } + else if (SvFLAGS(cv) & SVpcv_SYNC) { + /* + * It's a synchronised CV. Wait until it's free unless + * we own it already (in which case we're recursing). + */ + if (CvOWNER(cv) && CvOWNER(cv) != thr) { + do { + DEBUG_L((fprintf(stderr, "0x%lx wait for 0x%lx to leave %s\n", + (unsigned long)thr,(unsigned long)CvOWNER(cv), + SvPEEK((SV*)cv)))); + COND_WAIT(CvCONDP(cv), CvMUTEXP(cv)); /* yawn */ + } while (CvOWNER(cv)); + } + CvOWNER(cv) = thr; /* Assert ownership */ + SvREFCNT_inc(cv); + MUTEX_UNLOCK(CvMUTEXP(cv)); + if (CvDEPTH(cv) == 0) + SAVEDESTRUCTOR(unset_cvowner, (void*) cv); + } + else { + /* + * It's an ordinary unsynchronised CV so we must distinguish + * three cases. (1) It's ours already (and we're recursing); + * (2) it's free (but we may already be using a cached clone); + * (3) another thread owns it. Case (1) is easy: we just use it. + * Case (2) means we look for a clone--if we have one, use it + * otherwise grab ownership of cv. Case (3) means look we for a + * clone and have to create one if we don't already have one. + * Why look for a clone in case (2) when we could just grab + * ownership of cv straight away? Well, we could be recursing, + * i.e. we originally tried to enter cv while another thread + * owned it (hence we used a clone) but it has been freed up + * and we're now recursing into it. It may or may not be "better" + * to use the clone but at least CvDEPTH can be trusted. + */ + if (CvOWNER(cv) == thr) + MUTEX_UNLOCK(CvMUTEXP(cv)); + else { + /* Case (2) or (3) */ + SV **svp; + + /* + * XXX Might it be better to release CvMUTEXP(cv) while we + * do the hv_fetch? We might find someone has pinched it + * when we look again, in which case we would be in case + * (3) instead of (2) so we'd have to clone. Would the fact + * that we released the mutex more quickly make up for this? + */ + svp = hv_fetch(cvcache, (char *)cv, sizeof(cv), FALSE); + if (svp) { + /* We already have a clone to use */ + MUTEX_UNLOCK(CvMUTEXP(cv)); + cv = *(CV**)svp; + DEBUG_L(fprintf(stderr, + "entersub: 0x%lx already has clone 0x%lx:%s\n", + (unsigned long) thr, (unsigned long) cv, + SvPEEK((SV*)cv))); + CvOWNER(cv) = thr; + SvREFCNT_inc(cv); + if (CvDEPTH(cv) == 0) + SAVEDESTRUCTOR(unset_cvowner, (void*) cv); + } + else { + /* (2) => grab ownership of cv. (3) => make clone */ + if (!CvOWNER(cv)) { + CvOWNER(cv) = thr; + SvREFCNT_inc(cv); + MUTEX_UNLOCK(CvMUTEXP(cv)); + DEBUG_L(fprintf(stderr, + "entersub: 0x%lx grabbing 0x%lx:%s\n", + (unsigned long) thr, (unsigned long) cv, + SvPEEK((SV*)cv))); + } else { + /* Make a new clone. */ + CV *clonecv; + SvREFCNT_inc(cv); /* don't let it vanish from under us */ + MUTEX_UNLOCK(CvMUTEXP(cv)); + DEBUG_L((fprintf(stderr, + "entersub: 0x%lx cloning 0x%lx:%s\n", + (unsigned long) thr, (unsigned long) cv, + SvPEEK((SV*)cv)))); + /* + * We're creating a new clone so there's no race + * between the original MUTEX_UNLOCK and the + * SvREFCNT_inc since no one will be trying to undef + * it out from underneath us. At least, I don't think + * there's a race... + */ + clonecv = cv_clone(cv); + SvREFCNT_dec(cv); /* finished with this */ + hv_store(cvcache, (char*)cv, sizeof(cv), (SV*)clonecv,0); + CvOWNER(clonecv) = thr; + cv = clonecv; + SvREFCNT_inc(cv); + } + assert(CvDEPTH(cv) == 0); + SAVEDESTRUCTOR(unset_cvowner, (void*) cv); + } + } + } +#endif /* USE_THREADS */ + + gimme = GIMME; + if (CvXSUB(cv)) { if (CvOLDSTYLE(cv)) { I32 (*fp3)_((int,int,int)); @@ -1886,8 +2037,8 @@ PP(pp_aelem) } void -provide_ref(op, sv) -OP* op; +provide_ref(o, sv) +OP* o; SV* sv; { if (SvGMAGICAL(sv)) @@ -1896,7 +2047,7 @@ SV* sv; if (SvREADONLY(sv)) croak(no_modify); (void)SvUPGRADE(sv, SVt_RV); - SvRV(sv) = (op->op_private & OPpDEREF_HV ? + SvRV(sv) = (o->op_private & OPpDEREF_HV ? (SV*)newHV() : (SV*)newAV()); SvROK_on(sv); SvSETMAGIC(sv); -- cgit v1.2.1 From f93b4edd807be1c6102dad09f884828c27c4a58b Mon Sep 17 00:00:00 2001 From: Malcolm Beattie Date: Wed, 23 Apr 1997 19:06:45 +0000 Subject: Added programmer-level condition variables via "condpair" magic. Added support for detached threads and tweaked a few things. p4raw-id: //depot/thrperl@8 --- pp_hot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pp_hot.c') diff --git a/pp_hot.c b/pp_hot.c index b143ff72c3..2aee0611d5 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -1780,7 +1780,7 @@ PP(pp_entersub) #endif /* DEBUGGING */ MUTEX_UNLOCK(CvMUTEXP(cv)); /* fast sub wants neither sync nor clone */ } - else if (SvFLAGS(cv) & SVpcv_SYNC) { + else if (SvFLAGS(cv) & SVp_SYNC) { /* * It's a synchronised CV. Wait until it's free unless * we own it already (in which case we're recursing). -- cgit v1.2.1 From 9ed32d99bcab50ff8df392e9741dd3de08a596a4 Mon Sep 17 00:00:00 2001 From: Malcolm Beattie Date: Fri, 2 May 1997 19:03:49 +0000 Subject: Don't require CvDEPTH == 0 when bombing out of subs. p4raw-id: //depot/thrperl@9 --- pp_hot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pp_hot.c') diff --git a/pp_hot.c b/pp_hot.c index 2aee0611d5..5d70aa3a8c 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -33,7 +33,7 @@ void *cvarg; DEBUG_L((fprintf(stderr, "0x%lx unsetting CvOWNER of 0x%lx:%s\n", (unsigned long)thr, (unsigned long)cv, SvPEEK((SV*)cv)))); MUTEX_LOCK(CvMUTEXP(cv)); - assert(CvDEPTH(cv) == 0); + /* assert(CvDEPTH(cv) == 0); */ assert(thr == CvOWNER(cv)); CvOWNER(cv) = 0; if (CvCONDP(cv)) -- cgit v1.2.1