ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
(Generate patch)

Comparing Coro/Coro/State.xs (file contents):
Revision 1.6 by root, Tue Jul 17 15:42:28 2001 UTC vs.
Revision 1.250 by root, Wed Oct 22 16:34:07 2008 UTC

1#include "libcoro/coro.c"
2
3#define PERL_NO_GET_CONTEXT
4#define PERL_EXT
5
1#include "EXTERN.h" 6#include "EXTERN.h"
2#include "perl.h" 7#include "perl.h"
3#include "XSUB.h" 8#include "XSUB.h"
9#include "perliol.h"
4 10
5#if 0 11#include "patchlevel.h"
6# define CHK(x) (void *)0 12
13#include <stdio.h>
14#include <errno.h>
15#include <assert.h>
16
17#ifdef WIN32
18# undef setjmp
19# undef longjmp
20# undef _exit
21# define setjmp _setjmp // deep magic, don't ask
7#else 22#else
8# define CHK(x) if (!(x)) croak("FATAL, CHK: " #x) 23# include <inttypes.h> /* most portable stdint.h */
24#endif
25
26#ifdef HAVE_MMAP
27# include <unistd.h>
28# include <sys/mman.h>
29# ifndef MAP_ANONYMOUS
30# ifdef MAP_ANON
31# define MAP_ANONYMOUS MAP_ANON
32# else
33# undef HAVE_MMAP
34# endif
9#endif 35# endif
36# include <limits.h>
37# ifndef PAGESIZE
38# define PAGESIZE pagesize
39# define BOOT_PAGESIZE pagesize = sysconf (_SC_PAGESIZE)
40static long pagesize;
41# else
42# define BOOT_PAGESIZE (void)0
43# endif
44#else
45# define PAGESIZE 0
46# define BOOT_PAGESIZE (void)0
47#endif
10 48
49#if CORO_USE_VALGRIND
50# include <valgrind/valgrind.h>
51# define REGISTER_STACK(cctx,start,end) (cctx)->valgrind_id = VALGRIND_STACK_REGISTER ((start), (end))
52#else
53# define REGISTER_STACK(cctx,start,end)
54#endif
55
56/* the maximum number of idle cctx that will be pooled */
57#define MAX_IDLE_CCTX 8
58
59#define PERL_VERSION_ATLEAST(a,b,c) \
60 (PERL_REVISION > (a) \
61 || (PERL_REVISION == (a) \
62 && (PERL_VERSION > (b) \
63 || (PERL_VERSION == (b) && PERLSUBVERSION >= (c)))))
64
65#if !PERL_VERSION_ATLEAST (5,6,0)
66# ifndef PL_ppaddr
67# define PL_ppaddr ppaddr
68# endif
69# ifndef call_sv
70# define call_sv perl_call_sv
71# endif
72# ifndef get_sv
73# define get_sv perl_get_sv
74# endif
75# ifndef get_cv
76# define get_cv perl_get_cv
77# endif
78# ifndef IS_PADGV
79# define IS_PADGV(v) 0
80# endif
81# ifndef IS_PADCONST
82# define IS_PADCONST(v) 0
83# endif
84#endif
85
86/* 5.8.8 */
87#ifndef GV_NOTQUAL
88# define GV_NOTQUAL 0
89#endif
90#ifndef newSV
91# define newSV(l) NEWSV(0,l)
92#endif
93#ifndef SvREFCNT_inc_NN
94# define SvREFCNT_inc_NN(sv) SvREFCNT_inc (sv)
95#endif
96
97/* 5.11 */
98#ifndef CxHASARGS
99# define CxHASARGS(cx) (cx)->blk_sub.hasargs
100#endif
101
102/* 5.8.7 */
103#ifndef SvRV_set
104# define SvRV_set(s,v) SvRV(s) = (v)
105#endif
106
107#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
108# undef CORO_STACKGUARD
109#endif
110
111#ifndef CORO_STACKGUARD
112# define CORO_STACKGUARD 0
113#endif
114
115/* prefer perl internal functions over our own? */
116#ifndef CORO_PREFER_PERL_FUNCTIONS
117# define CORO_PREFER_PERL_FUNCTIONS 0
118#endif
119
120/* The next macros try to return the current stack pointer, in an as
121 * portable way as possible. */
122#define dSTACKLEVEL volatile char stacklevel
123#define STACKLEVEL ((void *)&stacklevel)
124
125#define IN_DESTRUCT (PL_main_cv == Nullcv)
126
127#if __GNUC__ >= 3
128# define attribute(x) __attribute__(x)
129# define BARRIER __asm__ __volatile__ ("" : : : "memory")
130# define expect(expr,value) __builtin_expect ((expr),(value))
131#else
132# define attribute(x)
133# define BARRIER
134# define expect(expr,value) (expr)
135#endif
136
137#define expect_false(expr) expect ((expr) != 0, 0)
138#define expect_true(expr) expect ((expr) != 0, 1)
139
140#define NOINLINE attribute ((noinline))
141
142#include "CoroAPI.h"
143
144#ifdef USE_ITHREADS
145static perl_mutex coro_mutex;
146# define LOCK do { MUTEX_LOCK (&coro_mutex); } while (0)
147# define UNLOCK do { MUTEX_UNLOCK (&coro_mutex); } while (0)
148#else
149# define LOCK (void)0
150# define UNLOCK (void)0
151#endif
152
153/* helper storage struct for Coro::AIO */
154struct io_state
155{
156 AV *res;
157 int errorno;
158 I32 laststype;
159 int laststatval;
160 Stat_t statcache;
161};
162
163static double (*nvtime)(); /* so why doesn't it take void? */
164
165static size_t coro_stacksize = CORO_STACKSIZE;
166static struct CoroAPI coroapi;
167static AV *main_mainstack; /* used to differentiate between $main and others */
168static JMPENV *main_top_env;
169static HV *coro_state_stash, *coro_stash;
170static volatile SV *coro_mortal; /* will be freed after next transfer */
171
172static GV *irsgv; /* $/ */
173static GV *stdoutgv; /* *STDOUT */
174static SV *rv_diehook;
175static SV *rv_warnhook;
176static HV *hv_sig; /* %SIG */
177
178/* async_pool helper stuff */
179static SV *sv_pool_rss;
180static SV *sv_pool_size;
181static AV *av_async_pool;
182
183/* Coro::AnyEvent */
184static SV *sv_activity;
185
186static struct coro_cctx *cctx_first;
187static int cctx_count, cctx_idle;
188
189enum {
190 CC_MAPPED = 0x01,
191 CC_NOREUSE = 0x02, /* throw this away after tracing */
192 CC_TRACE = 0x04,
193 CC_TRACE_SUB = 0x08, /* trace sub calls */
194 CC_TRACE_LINE = 0x10, /* trace each statement */
195 CC_TRACE_ALL = CC_TRACE_SUB | CC_TRACE_LINE,
196};
197
198/* this is a structure representing a c-level coroutine */
199typedef struct coro_cctx {
200 struct coro_cctx *next;
201
202 /* the stack */
203 void *sptr;
204 size_t ssize;
205
206 /* cpu state */
207 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
208 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */
209 JMPENV *top_env;
210 coro_context cctx;
211
212#if CORO_USE_VALGRIND
213 int valgrind_id;
214#endif
215 unsigned char flags;
216} coro_cctx;
217
218enum {
219 CF_RUNNING = 0x0001, /* coroutine is running */
220 CF_READY = 0x0002, /* coroutine is ready */
221 CF_NEW = 0x0004, /* has never been switched to */
222 CF_DESTROYED = 0x0008, /* coroutine data has been freed */
223};
224
225/* the structure where most of the perl state is stored, overlaid on the cxstack */
226typedef struct {
227 SV *defsv;
228 AV *defav;
229 SV *errsv;
230 SV *irsgv;
231#define VAR(name,type) type name;
232# include "state.h"
233#undef VAR
234} perl_slots;
235
236#define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT))
237
238/* this is a structure representing a perl-level coroutine */
11struct coro { 239struct coro {
12 U8 dowarn; 240 /* the c coroutine allocated to this perl coroutine, if any */
13 AV *defav; 241 coro_cctx *cctx;
14 242
15 PERL_SI *curstackinfo; 243 /* process data */
16 AV *curstack;
17 AV *mainstack; 244 AV *mainstack;
18 SV **stack_sp; 245 perl_slots *slot; /* basically the saved sp */
19 OP *op;
20 SV **curpad;
21 SV **stack_base;
22 SV **stack_max;
23 SV **tmps_stack;
24 I32 tmps_floor;
25 I32 tmps_ix;
26 I32 tmps_max;
27 I32 *markstack;
28 I32 *markstack_ptr;
29 I32 *markstack_max;
30 I32 *scopestack;
31 I32 scopestack_ix;
32 I32 scopestack_max;
33 ANY *savestack;
34 I32 savestack_ix;
35 I32 savestack_max;
36 OP **retstack;
37 I32 retstack_ix;
38 I32 retstack_max;
39 COP *curcop;
40 246
41 AV *args; 247 AV *args; /* data associated with this coroutine (initial args) */
248 int refcnt; /* coroutines are refcounted, yes */
249 int flags; /* CF_ flags */
250 HV *hv; /* the perl hash associated with this coro, if any */
251
252 /* statistics */
253 int usecount; /* number of transfers to this coro */
254
255 /* coro process data */
256 int prio;
257 SV *throw; /* exception to be thrown */
258
259 /* async_pool */
260 SV *saved_deffh;
261
262 /* linked list */
263 struct coro *next, *prev;
42}; 264};
43 265
44typedef struct coro *Coro__State; 266typedef struct coro *Coro__State;
45typedef struct coro *Coro__State_or_hashref; 267typedef struct coro *Coro__State_or_hashref;
46 268
47static HV *padlist_cache; 269/** Coro ********************************************************************/
48 270
49/* mostly copied from op.c:cv_clone2 */ 271#define PRIO_MAX 3
50STATIC AV * 272#define PRIO_HIGH 1
51clone_padlist (AV *protopadlist) 273#define PRIO_NORMAL 0
274#define PRIO_LOW -1
275#define PRIO_IDLE -3
276#define PRIO_MIN -4
277
278/* for Coro.pm */
279static SV *coro_current;
280static SV *coro_readyhook;
281static AV *coro_ready [PRIO_MAX-PRIO_MIN+1];
282static int coro_nready;
283static struct coro *coro_first;
284
285/** lowlevel stuff **********************************************************/
286
287static SV *
288coro_get_sv (pTHX_ const char *name, int create)
52{ 289{
53 AV *av; 290#if PERL_VERSION_ATLEAST (5,10,0)
54 I32 ix; 291 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
55 AV *protopad_name = (AV *) * av_fetch (protopadlist, 0, FALSE); 292 get_sv (name, create);
56 AV *protopad = (AV *) * av_fetch (protopadlist, 1, FALSE); 293#endif
57 SV **pname = AvARRAY (protopad_name); 294 return get_sv (name, create);
58 SV **ppad = AvARRAY (protopad); 295}
59 I32 fname = AvFILLp (protopad_name); 296
60 I32 fpad = AvFILLp (protopad); 297static AV *
298coro_get_av (pTHX_ const char *name, int create)
299{
300#if PERL_VERSION_ATLEAST (5,10,0)
301 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
302 get_av (name, create);
303#endif
304 return get_av (name, create);
305}
306
307static HV *
308coro_get_hv (pTHX_ const char *name, int create)
309{
310#if PERL_VERSION_ATLEAST (5,10,0)
311 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
312 get_hv (name, create);
313#endif
314 return get_hv (name, create);
315}
316
317static AV *
318coro_clone_padlist (pTHX_ CV *cv)
319{
320 AV *padlist = CvPADLIST (cv);
61 AV *newpadlist, *newpad_name, *newpad; 321 AV *newpadlist, *newpad;
62 SV **npad;
63
64 newpad_name = newAV ();
65 for (ix = fname; ix >= 0; ix--)
66 av_store (newpad_name, ix, SvREFCNT_inc (pname[ix]));
67
68 newpad = newAV ();
69 av_fill (newpad, AvFILLp (protopad));
70 npad = AvARRAY (newpad);
71 322
72 newpadlist = newAV (); 323 newpadlist = newAV ();
73 AvREAL_off (newpadlist); 324 AvREAL_off (newpadlist);
74 av_store (newpadlist, 0, (SV *) newpad_name); 325#if PERL_VERSION_ATLEAST (5,10,0)
326 Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1);
327#else
328 Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1, 1);
329#endif
330 newpad = (AV *)AvARRAY (padlist)[AvFILLp (padlist)];
331 --AvFILLp (padlist);
332
333 av_store (newpadlist, 0, SvREFCNT_inc_NN (*av_fetch (padlist, 0, FALSE)));
75 av_store (newpadlist, 1, (SV *) newpad); 334 av_store (newpadlist, 1, (SV *)newpad);
76 335
77 av = newAV (); /* will be @_ */ 336 return newpadlist;
78 av_extend (av, 0); 337}
79 av_store (newpad, 0, (SV *) av);
80 AvFLAGS (av) = AVf_REIFY;
81 338
82 for (ix = fpad; ix > 0; ix--) 339static void
340free_padlist (pTHX_ AV *padlist)
341{
342 /* may be during global destruction */
343 if (SvREFCNT (padlist))
83 { 344 {
84 SV *namesv = (ix <= fname) ? pname[ix] : Nullsv; 345 I32 i = AvFILLp (padlist);
85 if (namesv && namesv != &PL_sv_undef) 346 while (i >= 0)
86 { 347 {
87 char *name = SvPVX (namesv); /* XXX */ 348 SV **svp = av_fetch (padlist, i--, FALSE);
88 if (SvFLAGS (namesv) & SVf_FAKE || *name == '&') 349 if (svp)
89 { /* lexical from outside? */
90 npad[ix] = SvREFCNT_inc (ppad[ix]);
91 } 350 {
92 else
93 { /* our own lexical */
94 SV *sv; 351 SV *sv;
95 if (*name == '&') 352 while (&PL_sv_undef != (sv = av_pop ((AV *)*svp)))
96 sv = SvREFCNT_inc (ppad[ix]); 353 SvREFCNT_dec (sv);
97 else if (*name == '@') 354
98 sv = (SV *) newAV (); 355 SvREFCNT_dec (*svp);
99 else if (*name == '%')
100 sv = (SV *) newHV ();
101 else
102 sv = NEWSV (0, 0);
103 if (!SvPADBUSY (sv))
104 SvPADMY_on (sv);
105 npad[ix] = sv;
106 } 356 }
107 } 357 }
108 else if (IS_PADGV (ppad[ix]) || IS_PADCONST (ppad[ix]))
109 {
110 npad[ix] = SvREFCNT_inc (ppad[ix]);
111 }
112 else
113 {
114 SV *sv = NEWSV (0, 0);
115 SvPADTMP_on (sv);
116 npad[ix] = sv;
117 }
118 }
119 358
120#if 0 /* NONOTUNDERSTOOD */
121 /* Now that vars are all in place, clone nested closures. */
122
123 for (ix = fpad; ix > 0; ix--) {
124 SV* namesv = (ix <= fname) ? pname[ix] : Nullsv;
125 if (namesv
126 && namesv != &PL_sv_undef
127 && !(SvFLAGS(namesv) & SVf_FAKE)
128 && *SvPVX(namesv) == '&'
129 && CvCLONE(ppad[ix]))
130 {
131 CV *kid = cv_clone((CV*)ppad[ix]);
132 SvREFCNT_dec(ppad[ix]);
133 CvCLONE_on(kid);
134 SvPADMY_on(kid);
135 npad[ix] = (SV*)kid;
136 }
137 }
138#endif
139
140 return newpadlist;
141}
142
143STATIC AV *
144free_padlist (AV *padlist)
145{
146 /* may be during global destruction */
147 if (SvREFCNT(padlist))
148 {
149 I32 i = AvFILLp(padlist);
150 while (i >= 0)
151 {
152 SV **svp = av_fetch(padlist, i--, FALSE);
153 SV *sv = svp ? *svp : Nullsv;
154 if (sv)
155 SvREFCNT_dec(sv);
156 }
157
158 SvREFCNT_dec((SV*)padlist); 359 SvREFCNT_dec ((SV*)padlist);
360 }
361}
362
363static int
364coro_cv_free (pTHX_ SV *sv, MAGIC *mg)
365{
366 AV *padlist;
367 AV *av = (AV *)mg->mg_obj;
368
369 /* casting is fun. */
370 while (&PL_sv_undef != (SV *)(padlist = (AV *)av_pop (av)))
371 free_padlist (aTHX_ padlist);
372
373 SvREFCNT_dec (av); /* sv_magicext increased the refcount */
374
375 return 0;
376}
377
378#define CORO_MAGIC_type_cv PERL_MAGIC_ext
379#define CORO_MAGIC_type_state PERL_MAGIC_ext
380
381static MGVTBL coro_cv_vtbl = {
382 0, 0, 0, 0,
383 coro_cv_free
384};
385
386#define CORO_MAGIC(sv,type) \
387 SvMAGIC (sv) \
388 ? SvMAGIC (sv)->mg_type == type \
389 ? SvMAGIC (sv) \
390 : mg_find (sv, type) \
391 : 0
392
393#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv)
394#define CORO_MAGIC_state(sv) CORO_MAGIC (((SV *)(sv)), CORO_MAGIC_type_state)
395
396static struct coro *
397SvSTATE_ (pTHX_ SV *coro)
398{
399 HV *stash;
400 MAGIC *mg;
401
402 if (SvROK (coro))
403 coro = SvRV (coro);
404
405 if (expect_false (SvTYPE (coro) != SVt_PVHV))
406 croak ("Coro::State object required");
407
408 stash = SvSTASH (coro);
409 if (expect_false (stash != coro_stash && stash != coro_state_stash))
410 {
411 /* very slow, but rare, check */
412 if (!sv_derived_from (sv_2mortal (newRV_inc (coro)), "Coro::State"))
413 croak ("Coro::State object required");
414 }
415
416 mg = CORO_MAGIC_state (coro);
417 return (struct coro *)mg->mg_ptr;
418}
419
420#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv))
421
422/* the next two functions merely cache the padlists */
423static void
424get_padlist (pTHX_ CV *cv)
425{
426 MAGIC *mg = CORO_MAGIC_cv (cv);
427 AV *av;
428
429 if (expect_true (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0))
430 CvPADLIST (cv) = (AV *)AvARRAY (av)[AvFILLp (av)--];
431 else
432 {
433#if CORO_PREFER_PERL_FUNCTIONS
434 /* this is probably cleaner? but also slower! */
435 /* in practise, it seems to be less stable */
436 CV *cp = Perl_cv_clone (cv);
437 CvPADLIST (cv) = CvPADLIST (cp);
438 CvPADLIST (cp) = 0;
439 SvREFCNT_dec (cp);
440#else
441 CvPADLIST (cv) = coro_clone_padlist (aTHX_ cv);
442#endif
443 }
444}
445
446static void
447put_padlist (pTHX_ CV *cv)
448{
449 MAGIC *mg = CORO_MAGIC_cv (cv);
450 AV *av;
451
452 if (expect_false (!mg))
453 mg = sv_magicext ((SV *)cv, (SV *)newAV (), CORO_MAGIC_type_cv, &coro_cv_vtbl, 0, 0);
454
455 av = (AV *)mg->mg_obj;
456
457 if (expect_false (AvFILLp (av) >= AvMAX (av)))
458 av_extend (av, AvMAX (av) + 1);
459
460 AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv);
461}
462
463/** load & save, init *******************************************************/
464
465static void
466load_perl (pTHX_ Coro__State c)
467{
468 perl_slots *slot = c->slot;
469 c->slot = 0;
470
471 PL_mainstack = c->mainstack;
472
473 GvSV (PL_defgv) = slot->defsv;
474 GvAV (PL_defgv) = slot->defav;
475 GvSV (PL_errgv) = slot->errsv;
476 GvSV (irsgv) = slot->irsgv;
477
478 #define VAR(name,type) PL_ ## name = slot->name;
479 # include "state.h"
480 #undef VAR
481
482 {
483 dSP;
484
485 CV *cv;
486
487 /* now do the ugly restore mess */
488 while (expect_true (cv = (CV *)POPs))
489 {
490 put_padlist (aTHX_ cv); /* mark this padlist as available */
491 CvDEPTH (cv) = PTR2IV (POPs);
492 CvPADLIST (cv) = (AV *)POPs;
493 }
494
495 PUTBACK;
159 } 496 }
160} 497}
161 498
162/* the next tow functions merely cache the padlists */
163STATIC void
164get_padlist (CV *cv)
165{
166 SV **he = hv_fetch (padlist_cache, (void *)&cv, sizeof (CV *), 0);
167
168 if (he && AvFILLp ((AV *)*he) >= 0)
169 CvPADLIST (cv) = (AV *)av_pop ((AV *)*he);
170 else
171 CvPADLIST (cv) = clone_padlist (CvPADLIST (cv));
172}
173
174STATIC void
175put_padlist (CV *cv)
176{
177 SV **he = hv_fetch (padlist_cache, (void *)&cv, sizeof (CV *), 1);
178
179 if (SvTYPE (*he) != SVt_PVAV)
180 {
181 SvREFCNT_dec (*he);
182 *he = (SV *)newAV ();
183 }
184
185 av_push ((AV *)*he, (SV *)CvPADLIST (cv));
186}
187
188static void 499static void
189save_state(pTHX_ Coro__State c) 500save_perl (pTHX_ Coro__State c)
190{ 501{
191 { 502 {
192 dSP; 503 dSP;
193 I32 cxix = cxstack_ix; 504 I32 cxix = cxstack_ix;
505 PERL_CONTEXT *ccstk = cxstack;
194 PERL_SI *top_si = PL_curstackinfo; 506 PERL_SI *top_si = PL_curstackinfo;
195 PERL_CONTEXT *ccstk = cxstack;
196 507
197 /* 508 /*
198 * the worst thing you can imagine happens first - we have to save 509 * the worst thing you can imagine happens first - we have to save
199 * (and reinitialize) all cv's in the whole callchain :( 510 * (and reinitialize) all cv's in the whole callchain :(
200 */ 511 */
201 512
202 PUSHs (Nullsv); 513 XPUSHs (Nullsv);
203 /* this loop was inspired by pp_caller */ 514 /* this loop was inspired by pp_caller */
204 for (;;) 515 for (;;)
205 { 516 {
206 while (cxix >= 0) 517 while (expect_true (cxix >= 0))
207 { 518 {
208 PERL_CONTEXT *cx = &ccstk[cxix--]; 519 PERL_CONTEXT *cx = &ccstk[cxix--];
209 520
210 if (CxTYPE(cx) == CXt_SUB) 521 if (expect_true (CxTYPE (cx) == CXt_SUB || CxTYPE (cx) == CXt_FORMAT))
211 { 522 {
212 CV *cv = cx->blk_sub.cv; 523 CV *cv = cx->blk_sub.cv;
524
213 if (CvDEPTH(cv)) 525 if (expect_true (CvDEPTH (cv)))
214 { 526 {
215#ifdef USE_THREADS
216 XPUSHs ((SV *)CvOWNER(cv));
217#endif
218 EXTEND (SP, 3); 527 EXTEND (SP, 3);
219 PUSHs ((SV *)CvDEPTH(cv));
220 PUSHs ((SV *)CvPADLIST(cv)); 528 PUSHs ((SV *)CvPADLIST (cv));
529 PUSHs (INT2PTR (SV *, (IV)CvDEPTH (cv)));
221 PUSHs ((SV *)cv); 530 PUSHs ((SV *)cv);
222 531
223 get_padlist (cv);
224
225 CvDEPTH(cv) = 0; 532 CvDEPTH (cv) = 0;
226#ifdef USE_THREADS 533 get_padlist (aTHX_ cv);
227 CvOWNER(cv) = 0;
228 error must unlock this cv etc.. etc...
229 if you are here wondering about this error message then
230 the reason is that it will not work as advertised yet
231#endif
232 } 534 }
233 } 535 }
234 else if (CxTYPE(cx) == CXt_FORMAT) 536 }
537
538 if (expect_true (top_si->si_type == PERLSI_MAIN))
539 break;
540
541 top_si = top_si->si_prev;
542 ccstk = top_si->si_cxstack;
543 cxix = top_si->si_cxix;
544 }
545
546 PUTBACK;
547 }
548
549 /* allocate some space on the context stack for our purposes */
550 /* we manually unroll here, as usually 2 slots is enough */
551 if (SLOT_COUNT >= 1) CXINC;
552 if (SLOT_COUNT >= 2) CXINC;
553 if (SLOT_COUNT >= 3) CXINC;
554 {
555 int i;
556 for (i = 3; i < SLOT_COUNT; ++i)
557 CXINC;
558 }
559 cxstack_ix -= SLOT_COUNT; /* undo allocation */
560
561 c->mainstack = PL_mainstack;
562
563 {
564 perl_slots *slot = c->slot = (perl_slots *)(cxstack + cxstack_ix + 1);
565
566 slot->defav = GvAV (PL_defgv);
567 slot->defsv = DEFSV;
568 slot->errsv = ERRSV;
569 slot->irsgv = GvSV (irsgv);
570
571 #define VAR(name,type) slot->name = PL_ ## name;
572 # include "state.h"
573 #undef VAR
574 }
575}
576
577/*
578 * allocate various perl stacks. This is an exact copy
579 * of perl.c:init_stacks, except that it uses less memory
580 * on the (sometimes correct) assumption that coroutines do
581 * not usually need a lot of stackspace.
582 */
583#if CORO_PREFER_PERL_FUNCTIONS
584# define coro_init_stacks init_stacks
585#else
586static void
587coro_init_stacks (pTHX)
588{
589 PL_curstackinfo = new_stackinfo(32, 8);
590 PL_curstackinfo->si_type = PERLSI_MAIN;
591 PL_curstack = PL_curstackinfo->si_stack;
592 PL_mainstack = PL_curstack; /* remember in case we switch stacks */
593
594 PL_stack_base = AvARRAY(PL_curstack);
595 PL_stack_sp = PL_stack_base;
596 PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
597
598 New(50,PL_tmps_stack,32,SV*);
599 PL_tmps_floor = -1;
600 PL_tmps_ix = -1;
601 PL_tmps_max = 32;
602
603 New(54,PL_markstack,16,I32);
604 PL_markstack_ptr = PL_markstack;
605 PL_markstack_max = PL_markstack + 16;
606
607#ifdef SET_MARK_OFFSET
608 SET_MARK_OFFSET;
609#endif
610
611 New(54,PL_scopestack,8,I32);
612 PL_scopestack_ix = 0;
613 PL_scopestack_max = 8;
614
615 New(54,PL_savestack,24,ANY);
616 PL_savestack_ix = 0;
617 PL_savestack_max = 24;
618
619#if !PERL_VERSION_ATLEAST (5,10,0)
620 New(54,PL_retstack,4,OP*);
621 PL_retstack_ix = 0;
622 PL_retstack_max = 4;
623#endif
624}
625#endif
626
627/*
628 * destroy the stacks, the callchain etc...
629 */
630static void
631coro_destroy_stacks (pTHX)
632{
633 while (PL_curstackinfo->si_next)
634 PL_curstackinfo = PL_curstackinfo->si_next;
635
636 while (PL_curstackinfo)
637 {
638 PERL_SI *p = PL_curstackinfo->si_prev;
639
640 if (!IN_DESTRUCT)
641 SvREFCNT_dec (PL_curstackinfo->si_stack);
642
643 Safefree (PL_curstackinfo->si_cxstack);
644 Safefree (PL_curstackinfo);
645 PL_curstackinfo = p;
646 }
647
648 Safefree (PL_tmps_stack);
649 Safefree (PL_markstack);
650 Safefree (PL_scopestack);
651 Safefree (PL_savestack);
652#if !PERL_VERSION_ATLEAST (5,10,0)
653 Safefree (PL_retstack);
654#endif
655}
656
657static size_t
658coro_rss (pTHX_ struct coro *coro)
659{
660 size_t rss = sizeof (*coro);
661
662 if (coro->mainstack)
663 {
664 perl_slots tmp_slot;
665 perl_slots *slot;
666
667 if (coro->flags & CF_RUNNING)
668 {
669 slot = &tmp_slot;
670
671 #define VAR(name,type) slot->name = PL_ ## name;
672 # include "state.h"
673 #undef VAR
674 }
675 else
676 slot = coro->slot;
677
678 if (slot)
679 {
680 rss += sizeof (slot->curstackinfo);
681 rss += (slot->curstackinfo->si_cxmax + 1) * sizeof (PERL_CONTEXT);
682 rss += sizeof (SV) + sizeof (struct xpvav) + (1 + AvMAX (slot->curstack)) * sizeof (SV *);
683 rss += slot->tmps_max * sizeof (SV *);
684 rss += (slot->markstack_max - slot->markstack_ptr) * sizeof (I32);
685 rss += slot->scopestack_max * sizeof (I32);
686 rss += slot->savestack_max * sizeof (ANY);
687
688#if !PERL_VERSION_ATLEAST (5,10,0)
689 rss += slot->retstack_max * sizeof (OP *);
690#endif
691 }
692 }
693
694 return rss;
695}
696
697/** coroutine stack handling ************************************************/
698
699static int (*orig_sigelem_get) (pTHX_ SV *sv, MAGIC *mg);
700static int (*orig_sigelem_set) (pTHX_ SV *sv, MAGIC *mg);
701static int (*orig_sigelem_clr) (pTHX_ SV *sv, MAGIC *mg);
702
703/* apparently < 5.8.8 */
704#ifndef MgPV_nolen_const
705#define MgPV_nolen_const(mg) (((((int)(mg)->mg_len)) == HEf_SVKEY) ? \
706 SvPV_nolen((SV*)((mg)->mg_ptr)) : \
707 (const char*)(mg)->mg_ptr)
708#endif
709
710/*
711 * This overrides the default magic get method of %SIG elements.
712 * The original one doesn't provide for reading back of PL_diehook/PL_warnhook
713 * and instead of tryign to save and restore the hash elements, we just provide
714 * readback here.
715 * We only do this when the hook is != 0, as they are often set to 0 temporarily,
716 * not expecting this to actually change the hook. This is a potential problem
717 * when a schedule happens then, but we ignore this.
718 */
719static int
720coro_sigelem_get (pTHX_ SV *sv, MAGIC *mg)
721{
722 const char *s = MgPV_nolen_const (mg);
723
724 if (*s == '_')
725 {
726 SV **svp = 0;
727
728 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
729 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
730
731 if (svp)
732 {
733 sv_setsv (sv, *svp ? *svp : &PL_sv_undef);
734 return 0;
735 }
736 }
737
738 return orig_sigelem_get ? orig_sigelem_get (aTHX_ sv, mg) : 0;
739}
740
741static int
742coro_sigelem_clr (pTHX_ SV *sv, MAGIC *mg)
743{
744 const char *s = MgPV_nolen_const (mg);
745
746 if (*s == '_')
747 {
748 SV **svp = 0;
749
750 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
751 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
752
753 if (svp)
754 {
755 SV *old = *svp;
756 *svp = 0;
757 SvREFCNT_dec (old);
758 return 0;
759 }
760 }
761
762 return orig_sigelem_clr ? orig_sigelem_clr (aTHX_ sv, mg) : 0;
763}
764
765static int
766coro_sigelem_set (pTHX_ SV *sv, MAGIC *mg)
767{
768 const char *s = MgPV_nolen_const (mg);
769
770 if (*s == '_')
771 {
772 SV **svp = 0;
773
774 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
775 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
776
777 if (svp)
778 {
779 SV *old = *svp;
780 *svp = newSVsv (sv);
781 SvREFCNT_dec (old);
782 return 0;
783 }
784 }
785
786 return orig_sigelem_set ? orig_sigelem_set (aTHX_ sv, mg) : 0;
787}
788
789static void
790coro_setup (pTHX_ struct coro *coro)
791{
792 /*
793 * emulate part of the perl startup here.
794 */
795 coro_init_stacks (aTHX);
796
797 PL_runops = RUNOPS_DEFAULT;
798 PL_curcop = &PL_compiling;
799 PL_in_eval = EVAL_NULL;
800 PL_comppad = 0;
801 PL_curpm = 0;
802 PL_curpad = 0;
803 PL_localizing = 0;
804 PL_dirty = 0;
805 PL_restartop = 0;
806#if PERL_VERSION_ATLEAST (5,10,0)
807 PL_parser = 0;
808#endif
809
810 /* recreate the die/warn hooks */
811 PL_diehook = 0; SvSetMagicSV (*hv_fetch (hv_sig, "__DIE__" , sizeof ("__DIE__" ) - 1, 1), rv_diehook );
812 PL_warnhook = 0; SvSetMagicSV (*hv_fetch (hv_sig, "__WARN__", sizeof ("__WARN__") - 1, 1), rv_warnhook);
813
814 GvSV (PL_defgv) = newSV (0);
815 GvAV (PL_defgv) = coro->args; coro->args = 0;
816 GvSV (PL_errgv) = newSV (0);
817 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0);
818 PL_rs = newSVsv (GvSV (irsgv));
819 PL_defoutgv = (GV *)SvREFCNT_inc_NN (stdoutgv);
820
821 {
822 dSP;
823 LOGOP myop;
824
825 Zero (&myop, 1, LOGOP);
826 myop.op_next = Nullop;
827 myop.op_flags = OPf_WANT_VOID;
828
829 PUSHMARK (SP);
830 XPUSHs (sv_2mortal (av_shift (GvAV (PL_defgv))));
831 PUTBACK;
832 PL_op = (OP *)&myop;
833 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
834 SPAGAIN;
835 }
836
837 /* this newly created coroutine might be run on an existing cctx which most
838 * likely was suspended in set_stacklevel, called from entersub.
839 * set_stacklevl doesn't do anything on return, but entersub does LEAVE,
840 * so we ENTER here for symmetry
841 */
842 ENTER;
843}
844
845static void
846coro_destroy (pTHX_ struct coro *coro)
847{
848 if (!IN_DESTRUCT)
849 {
850 /* restore all saved variables and stuff */
851 LEAVE_SCOPE (0);
852 assert (PL_tmps_floor == -1);
853
854 /* free all temporaries */
855 FREETMPS;
856 assert (PL_tmps_ix == -1);
857
858 /* unwind all extra stacks */
859 POPSTACK_TO (PL_mainstack);
860
861 /* unwind main stack */
862 dounwind (-1);
863 }
864
865 SvREFCNT_dec (GvSV (PL_defgv));
866 SvREFCNT_dec (GvAV (PL_defgv));
867 SvREFCNT_dec (GvSV (PL_errgv));
868 SvREFCNT_dec (PL_defoutgv);
869 SvREFCNT_dec (PL_rs);
870 SvREFCNT_dec (GvSV (irsgv));
871
872 SvREFCNT_dec (PL_diehook);
873 SvREFCNT_dec (PL_warnhook);
874
875 SvREFCNT_dec (coro->saved_deffh);
876 SvREFCNT_dec (coro->throw);
877
878 coro_destroy_stacks (aTHX);
879}
880
881static void
882free_coro_mortal (pTHX)
883{
884 if (expect_true (coro_mortal))
885 {
886 SvREFCNT_dec (coro_mortal);
887 coro_mortal = 0;
888 }
889}
890
891static int
892runops_trace (pTHX)
893{
894 COP *oldcop = 0;
895 int oldcxix = -2;
896 struct coro *coro = SvSTATE (coro_current); /* trace cctx is tied to specific coro */
897 coro_cctx *cctx = coro->cctx;
898
899 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX)))
900 {
901 PERL_ASYNC_CHECK ();
902
903 if (cctx->flags & CC_TRACE_ALL)
904 {
905 if (PL_op->op_type == OP_LEAVESUB && cctx->flags & CC_TRACE_SUB)
906 {
907 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
908 SV **bot, **top;
909 AV *av = newAV (); /* return values */
910 SV **cb;
911 dSP;
912
913 GV *gv = CvGV (cx->blk_sub.cv);
914 SV *fullname = sv_2mortal (newSV (0));
915 if (isGV (gv))
916 gv_efullname3 (fullname, gv, 0);
917
918 bot = PL_stack_base + cx->blk_oldsp + 1;
919 top = cx->blk_gimme == G_ARRAY ? SP + 1
920 : cx->blk_gimme == G_SCALAR ? bot + 1
921 : bot;
922
923 av_extend (av, top - bot);
924 while (bot < top)
925 av_push (av, SvREFCNT_inc_NN (*bot++));
926
927 PL_runops = RUNOPS_DEFAULT;
928 ENTER;
929 SAVETMPS;
930 EXTEND (SP, 3);
931 PUSHMARK (SP);
932 PUSHs (&PL_sv_no);
933 PUSHs (fullname);
934 PUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
935 PUTBACK;
936 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
937 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
938 SPAGAIN;
939 FREETMPS;
940 LEAVE;
941 PL_runops = runops_trace;
942 }
943
944 if (oldcop != PL_curcop)
945 {
946 oldcop = PL_curcop;
947
948 if (PL_curcop != &PL_compiling)
949 {
950 SV **cb;
951
952 if (oldcxix != cxstack_ix && cctx->flags & CC_TRACE_SUB)
953 {
954 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
955
956 if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix)
957 {
958 runops_proc_t old_runops = PL_runops;
959 dSP;
960 GV *gv = CvGV (cx->blk_sub.cv);
961 SV *fullname = sv_2mortal (newSV (0));
962
963 if (isGV (gv))
964 gv_efullname3 (fullname, gv, 0);
965
966 PL_runops = RUNOPS_DEFAULT;
967 ENTER;
968 SAVETMPS;
969 EXTEND (SP, 3);
970 PUSHMARK (SP);
971 PUSHs (&PL_sv_yes);
972 PUSHs (fullname);
973 PUSHs (CxHASARGS (cx) ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef);
974 PUTBACK;
975 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
976 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
977 SPAGAIN;
978 FREETMPS;
979 LEAVE;
980 PL_runops = runops_trace;
981 }
982
983 oldcxix = cxstack_ix;
984 }
985
986 if (cctx->flags & CC_TRACE_LINE)
987 {
988 dSP;
989
990 PL_runops = RUNOPS_DEFAULT;
991 ENTER;
992 SAVETMPS;
993 EXTEND (SP, 3);
994 PL_runops = RUNOPS_DEFAULT;
995 PUSHMARK (SP);
996 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0)));
997 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop))));
998 PUTBACK;
999 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0);
1000 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1001 SPAGAIN;
1002 FREETMPS;
1003 LEAVE;
1004 PL_runops = runops_trace;
1005 }
1006 }
1007 }
1008 }
1009 }
1010
1011 TAINT_NOT;
1012 return 0;
1013}
1014
1015/* inject a fake call to Coro::State::_cctx_init into the execution */
1016/* _cctx_init should be careful, as it could be called at almost any time */
1017/* during execution of a perl program */
1018static void NOINLINE
1019cctx_prepare (pTHX_ coro_cctx *cctx)
1020{
1021 dSP;
1022 LOGOP myop;
1023
1024 PL_top_env = &PL_start_env;
1025
1026 if (cctx->flags & CC_TRACE)
1027 PL_runops = runops_trace;
1028
1029 Zero (&myop, 1, LOGOP);
1030 myop.op_next = PL_op;
1031 myop.op_flags = OPf_WANT_VOID | OPf_STACKED;
1032
1033 PUSHMARK (SP);
1034 EXTEND (SP, 2);
1035 PUSHs (sv_2mortal (newSViv (PTR2IV (cctx))));
1036 PUSHs ((SV *)get_cv ("Coro::State::_cctx_init", FALSE));
1037 PUTBACK;
1038 PL_op = (OP *)&myop;
1039 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
1040 SPAGAIN;
1041}
1042
1043/*
1044 * this is a _very_ stripped down perl interpreter ;)
1045 */
1046static void
1047cctx_run (void *arg)
1048{
1049 dTHX;
1050
1051 /* cctx_run is the alternative tail of transfer(), so unlock here. */
1052 UNLOCK;
1053
1054 /* we now skip the entersub that lead to transfer() */
1055 PL_op = PL_op->op_next;
1056
1057 /* inject a fake subroutine call to cctx_init */
1058 cctx_prepare (aTHX_ (coro_cctx *)arg);
1059
1060 /* somebody or something will hit me for both perl_run and PL_restartop */
1061 PL_restartop = PL_op;
1062 perl_run (PL_curinterp);
1063
1064 /*
1065 * If perl-run returns we assume exit() was being called or the coro
1066 * fell off the end, which seems to be the only valid (non-bug)
1067 * reason for perl_run to return. We try to exit by jumping to the
1068 * bootstrap-time "top" top_env, as we cannot restore the "main"
1069 * coroutine as Coro has no such concept
1070 */
1071 PL_top_env = main_top_env;
1072 JMPENV_JUMP (2); /* I do not feel well about the hardcoded 2 at all */
1073}
1074
1075static coro_cctx *
1076cctx_new ()
1077{
1078 coro_cctx *cctx;
1079 void *stack_start;
1080 size_t stack_size;
1081
1082 ++cctx_count;
1083
1084 Newz (0, cctx, 1, coro_cctx);
1085
1086#if HAVE_MMAP
1087 cctx->ssize = ((coro_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
1088 /* mmap supposedly does allocate-on-write for us */
1089 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
1090
1091 if (cctx->sptr != (void *)-1)
1092 {
1093# if CORO_STACKGUARD
1094 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE);
1095# endif
1096 stack_start = CORO_STACKGUARD * PAGESIZE + (char *)cctx->sptr;
1097 stack_size = cctx->ssize - CORO_STACKGUARD * PAGESIZE;
1098 cctx->flags |= CC_MAPPED;
1099 }
1100 else
1101#endif
1102 {
1103 cctx->ssize = coro_stacksize * (long)sizeof (long);
1104 New (0, cctx->sptr, coro_stacksize, long);
1105
1106 if (!cctx->sptr)
1107 {
1108 perror ("FATAL: unable to allocate stack for coroutine");
1109 _exit (EXIT_FAILURE);
1110 }
1111
1112 stack_start = cctx->sptr;
1113 stack_size = cctx->ssize;
1114 }
1115
1116 REGISTER_STACK (cctx, (char *)stack_start, (char *)stack_start + stack_size);
1117 coro_create (&cctx->cctx, cctx_run, (void *)cctx, stack_start, stack_size);
1118
1119 return cctx;
1120}
1121
1122static void
1123cctx_destroy (coro_cctx *cctx)
1124{
1125 if (!cctx)
1126 return;
1127
1128 --cctx_count;
1129
1130#if CORO_USE_VALGRIND
1131 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id);
1132#endif
1133
1134#if HAVE_MMAP
1135 if (cctx->flags & CC_MAPPED)
1136 munmap (cctx->sptr, cctx->ssize);
1137 else
1138#endif
1139 Safefree (cctx->sptr);
1140
1141 Safefree (cctx);
1142}
1143
1144/* wether this cctx should be destructed */
1145#define CCTX_EXPIRED(cctx) ((cctx)->ssize < coro_stacksize || ((cctx)->flags & CC_NOREUSE))
1146
1147static coro_cctx *
1148cctx_get (pTHX)
1149{
1150 while (expect_true (cctx_first))
1151 {
1152 coro_cctx *cctx = cctx_first;
1153 cctx_first = cctx->next;
1154 --cctx_idle;
1155
1156 if (expect_true (!CCTX_EXPIRED (cctx)))
1157 return cctx;
1158
1159 cctx_destroy (cctx);
1160 }
1161
1162 return cctx_new ();
1163}
1164
1165static void
1166cctx_put (coro_cctx *cctx)
1167{
1168 /* free another cctx if overlimit */
1169 if (expect_false (cctx_idle >= MAX_IDLE_CCTX))
1170 {
1171 coro_cctx *first = cctx_first;
1172 cctx_first = first->next;
1173 --cctx_idle;
1174
1175 cctx_destroy (first);
1176 }
1177
1178 ++cctx_idle;
1179 cctx->next = cctx_first;
1180 cctx_first = cctx;
1181}
1182
1183/** coroutine switching *****************************************************/
1184
1185static void
1186transfer_check (pTHX_ struct coro *prev, struct coro *next)
1187{
1188 if (expect_true (prev != next))
1189 {
1190 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW))))
1191 croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states");
1192
1193 if (expect_false (next->flags & CF_RUNNING))
1194 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states");
1195
1196 if (expect_false (next->flags & CF_DESTROYED))
1197 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states");
1198
1199#if !PERL_VERSION_ATLEAST (5,10,0)
1200 if (expect_false (PL_lex_state != LEX_NOTPARSING))
1201 croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version");
1202#endif
1203 }
1204}
1205
1206/* always use the TRANSFER macro */
1207static void NOINLINE
1208transfer (pTHX_ struct coro *prev, struct coro *next, int force_cctx)
1209{
1210 dSTACKLEVEL;
1211 static volatile int has_throw;
1212
1213 /* sometimes transfer is only called to set idle_sp */
1214 if (expect_false (!next))
1215 {
1216 ((coro_cctx *)prev)->idle_sp = STACKLEVEL;
1217 assert (((coro_cctx *)prev)->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */
1218 }
1219 else if (expect_true (prev != next))
1220 {
1221 coro_cctx *prev__cctx;
1222
1223 if (expect_false (prev->flags & CF_NEW))
1224 {
1225 /* create a new empty context */
1226 Newz (0, prev->cctx, 1, coro_cctx);
1227 prev->flags &= ~CF_NEW;
1228 prev->flags |= CF_RUNNING;
1229 }
1230
1231 prev->flags &= ~CF_RUNNING;
1232 next->flags |= CF_RUNNING;
1233
1234 LOCK;
1235
1236 /* first get rid of the old state */
1237 save_perl (aTHX_ prev);
1238
1239 if (expect_false (next->flags & CF_NEW))
1240 {
1241 /* need to start coroutine */
1242 next->flags &= ~CF_NEW;
1243 /* setup coroutine call */
1244 coro_setup (aTHX_ next);
1245 }
1246 else
1247 load_perl (aTHX_ next);
1248
1249 prev__cctx = prev->cctx;
1250
1251 /* possibly "free" the cctx */
1252 if (expect_true (
1253 prev__cctx->idle_sp == STACKLEVEL
1254 && !(prev__cctx->flags & CC_TRACE)
1255 && !force_cctx
1256 ))
1257 {
1258 /* I assume that STACKLEVEL is a stronger indicator than PL_top_env changes */
1259 assert (("ERROR: current top_env must equal previous top_env", PL_top_env == prev__cctx->idle_te));
1260
1261 prev->cctx = 0;
1262
1263 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */
1264 /* without this the next cctx_get might destroy the prev__cctx while still in use */
1265 if (expect_false (CCTX_EXPIRED (prev__cctx)))
1266 if (!next->cctx)
1267 next->cctx = cctx_get (aTHX);
1268
1269 cctx_put (prev__cctx);
1270 }
1271
1272 ++next->usecount;
1273
1274 if (expect_true (!next->cctx))
1275 next->cctx = cctx_get (aTHX);
1276
1277 has_throw = !!next->throw;
1278
1279 if (expect_false (prev__cctx != next->cctx))
1280 {
1281 prev__cctx->top_env = PL_top_env;
1282 PL_top_env = next->cctx->top_env;
1283 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx);
1284 }
1285
1286 free_coro_mortal (aTHX);
1287 UNLOCK;
1288
1289 if (expect_false (has_throw))
1290 {
1291 struct coro *coro = SvSTATE (coro_current);
1292
1293 if (coro->throw)
1294 {
1295 SV *exception = coro->throw;
1296 coro->throw = 0;
1297 sv_setsv (ERRSV, exception);
1298 croak (0);
1299 }
1300 }
1301 }
1302}
1303
1304struct transfer_args
1305{
1306 struct coro *prev, *next;
1307};
1308
1309#define TRANSFER(ta, force_cctx) transfer (aTHX_ (ta).prev, (ta).next, (force_cctx))
1310#define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next)
1311
1312/** high level stuff ********************************************************/
1313
1314static int
1315coro_state_destroy (pTHX_ struct coro *coro)
1316{
1317 if (coro->flags & CF_DESTROYED)
1318 return 0;
1319
1320 coro->flags |= CF_DESTROYED;
1321
1322 if (coro->flags & CF_READY)
1323 {
1324 /* reduce nready, as destroying a ready coro effectively unreadies it */
1325 /* alternative: look through all ready queues and remove the coro */
1326 LOCK;
1327 --coro_nready;
1328 UNLOCK;
1329 }
1330 else
1331 coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */
1332
1333 if (coro->mainstack && coro->mainstack != main_mainstack)
1334 {
1335 struct coro temp;
1336
1337 if (coro->flags & CF_RUNNING)
1338 croak ("FATAL: tried to destroy currently running coroutine");
1339
1340 save_perl (aTHX_ &temp);
1341 load_perl (aTHX_ coro);
1342
1343 coro_destroy (aTHX_ coro);
1344
1345 load_perl (aTHX_ &temp);
1346
1347 coro->slot = 0;
1348 }
1349
1350 cctx_destroy (coro->cctx);
1351 SvREFCNT_dec (coro->args);
1352
1353 if (coro->next) coro->next->prev = coro->prev;
1354 if (coro->prev) coro->prev->next = coro->next;
1355 if (coro == coro_first) coro_first = coro->next;
1356
1357 return 1;
1358}
1359
1360static int
1361coro_state_free (pTHX_ SV *sv, MAGIC *mg)
1362{
1363 struct coro *coro = (struct coro *)mg->mg_ptr;
1364 mg->mg_ptr = 0;
1365
1366 coro->hv = 0;
1367
1368 if (--coro->refcnt < 0)
1369 {
1370 coro_state_destroy (aTHX_ coro);
1371 Safefree (coro);
1372 }
1373
1374 return 0;
1375}
1376
1377static int
1378coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
1379{
1380 struct coro *coro = (struct coro *)mg->mg_ptr;
1381
1382 ++coro->refcnt;
1383
1384 return 0;
1385}
1386
1387static MGVTBL coro_state_vtbl = {
1388 0, 0, 0, 0,
1389 coro_state_free,
1390 0,
1391#ifdef MGf_DUP
1392 coro_state_dup,
1393#else
1394# define MGf_DUP 0
1395#endif
1396};
1397
1398static void
1399prepare_transfer (pTHX_ struct transfer_args *ta, SV *prev_sv, SV *next_sv)
1400{
1401 ta->prev = SvSTATE (prev_sv);
1402 ta->next = SvSTATE (next_sv);
1403 TRANSFER_CHECK (*ta);
1404}
1405
1406static void
1407api_transfer (SV *prev_sv, SV *next_sv)
1408{
1409 dTHX;
1410 struct transfer_args ta;
1411
1412 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
1413 TRANSFER (ta, 1);
1414}
1415
1416/** Coro ********************************************************************/
1417
1418static void
1419coro_enq (pTHX_ SV *coro_sv)
1420{
1421 av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv);
1422}
1423
1424static SV *
1425coro_deq (pTHX)
1426{
1427 int prio;
1428
1429 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; )
1430 if (AvFILLp (coro_ready [prio]) >= 0)
1431 return av_shift (coro_ready [prio]);
1432
1433 return 0;
1434}
1435
1436static int
1437api_ready (SV *coro_sv)
1438{
1439 dTHX;
1440 struct coro *coro;
1441 SV *sv_hook;
1442 void (*xs_hook)(void);
1443
1444 if (SvROK (coro_sv))
1445 coro_sv = SvRV (coro_sv);
1446
1447 coro = SvSTATE (coro_sv);
1448
1449 if (coro->flags & CF_READY)
1450 return 0;
1451
1452 coro->flags |= CF_READY;
1453
1454 LOCK;
1455
1456 sv_hook = coro_nready ? 0 : coro_readyhook;
1457 xs_hook = coro_nready ? 0 : coroapi.readyhook;
1458
1459 coro_enq (aTHX_ SvREFCNT_inc_NN (coro_sv));
1460 ++coro_nready;
1461
1462 UNLOCK;
1463
1464 if (sv_hook)
1465 {
1466 dSP;
1467
1468 ENTER;
1469 SAVETMPS;
1470
1471 PUSHMARK (SP);
1472 PUTBACK;
1473 call_sv (sv_hook, G_DISCARD);
1474 SPAGAIN;
1475
1476 FREETMPS;
1477 LEAVE;
1478 }
1479
1480 if (xs_hook)
1481 xs_hook ();
1482
1483 return 1;
1484}
1485
1486static int
1487api_is_ready (SV *coro_sv)
1488{
1489 dTHX;
1490 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1491}
1492
1493static void
1494prepare_schedule (pTHX_ struct transfer_args *ta)
1495{
1496 SV *prev_sv, *next_sv;
1497
1498 for (;;)
1499 {
1500 LOCK;
1501 next_sv = coro_deq (aTHX);
1502
1503 /* nothing to schedule: call the idle handler */
1504 if (expect_false (!next_sv))
1505 {
1506 dSP;
1507 UNLOCK;
1508
1509 ENTER;
1510 SAVETMPS;
1511
1512 PUSHMARK (SP);
1513 PUTBACK;
1514 call_sv (get_sv ("Coro::idle", FALSE), G_DISCARD);
1515 SPAGAIN;
1516
1517 FREETMPS;
1518 LEAVE;
1519 continue;
1520 }
1521
1522 ta->next = SvSTATE (next_sv);
1523
1524 /* cannot transfer to destroyed coros, skip and look for next */
1525 if (expect_false (ta->next->flags & CF_DESTROYED))
1526 {
1527 UNLOCK;
1528 SvREFCNT_dec (next_sv);
1529 /* coro_nready is already taken care of by destroy */
1530 continue;
1531 }
1532
1533 --coro_nready;
1534 UNLOCK;
1535 break;
1536 }
1537
1538 /* free this only after the transfer */
1539 prev_sv = SvRV (coro_current);
1540 ta->prev = SvSTATE (prev_sv);
1541 TRANSFER_CHECK (*ta);
1542 assert (ta->next->flags & CF_READY);
1543 ta->next->flags &= ~CF_READY;
1544 SvRV_set (coro_current, next_sv);
1545
1546 LOCK;
1547 free_coro_mortal (aTHX);
1548 coro_mortal = prev_sv;
1549 UNLOCK;
1550}
1551
1552static void
1553prepare_cede (pTHX_ struct transfer_args *ta)
1554{
1555 api_ready (coro_current);
1556 prepare_schedule (aTHX_ ta);
1557}
1558
1559static int
1560prepare_cede_notself (pTHX_ struct transfer_args *ta)
1561{
1562 if (coro_nready)
1563 {
1564 SV *prev = SvRV (coro_current);
1565 prepare_schedule (aTHX_ ta);
1566 api_ready (prev);
1567 return 1;
1568 }
1569 else
1570 return 0;
1571}
1572
1573static void
1574api_schedule (void)
1575{
1576 dTHX;
1577 struct transfer_args ta;
1578
1579 prepare_schedule (aTHX_ &ta);
1580 TRANSFER (ta, 1);
1581}
1582
1583static int
1584api_cede (void)
1585{
1586 dTHX;
1587 struct transfer_args ta;
1588
1589 prepare_cede (aTHX_ &ta);
1590
1591 if (expect_true (ta.prev != ta.next))
1592 {
1593 TRANSFER (ta, 1);
1594 return 1;
1595 }
1596 else
1597 return 0;
1598}
1599
1600static int
1601api_cede_notself (void)
1602{
1603 dTHX;
1604 struct transfer_args ta;
1605
1606 if (prepare_cede_notself (aTHX_ &ta))
1607 {
1608 TRANSFER (ta, 1);
1609 return 1;
1610 }
1611 else
1612 return 0;
1613}
1614
1615static void
1616api_trace (SV *coro_sv, int flags)
1617{
1618 dTHX;
1619 struct coro *coro = SvSTATE (coro_sv);
1620
1621 if (flags & CC_TRACE)
1622 {
1623 if (!coro->cctx)
1624 coro->cctx = cctx_new ();
1625 else if (!(coro->cctx->flags & CC_TRACE))
1626 croak ("cannot enable tracing on coroutine with custom stack");
1627
1628 coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL));
1629 }
1630 else if (coro->cctx && coro->cctx->flags & CC_TRACE)
1631 {
1632 coro->cctx->flags &= ~(CC_TRACE | CC_TRACE_ALL);
1633
1634 if (coro->flags & CF_RUNNING)
1635 PL_runops = RUNOPS_DEFAULT;
1636 else
1637 coro->slot->runops = RUNOPS_DEFAULT;
1638 }
1639}
1640
1641static int
1642coro_gensub_free (pTHX_ SV *sv, MAGIC *mg)
1643{
1644 AV *padlist;
1645 AV *av = (AV *)mg->mg_obj;
1646
1647 abort ();
1648
1649 return 0;
1650}
1651
1652static MGVTBL coro_gensub_vtbl = {
1653 0, 0, 0, 0,
1654 coro_gensub_free
1655};
1656
1657/*****************************************************************************/
1658/* PerlIO::cede */
1659
1660typedef struct
1661{
1662 PerlIOBuf base;
1663 NV next, every;
1664} PerlIOCede;
1665
1666static IV
1667PerlIOCede_pushed (pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
1668{
1669 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
1670
1671 self->every = SvCUR (arg) ? SvNV (arg) : 0.01;
1672 self->next = nvtime () + self->every;
1673
1674 return PerlIOBuf_pushed (aTHX_ f, mode, Nullsv, tab);
1675}
1676
1677static SV *
1678PerlIOCede_getarg (pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
1679{
1680 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
1681
1682 return newSVnv (self->every);
1683}
1684
1685static IV
1686PerlIOCede_flush (pTHX_ PerlIO *f)
1687{
1688 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
1689 double now = nvtime ();
1690
1691 if (now >= self->next)
1692 {
1693 api_cede ();
1694 self->next = now + self->every;
1695 }
1696
1697 return PerlIOBuf_flush (aTHX_ f);
1698}
1699
1700static PerlIO_funcs PerlIO_cede =
1701{
1702 sizeof(PerlIO_funcs),
1703 "cede",
1704 sizeof(PerlIOCede),
1705 PERLIO_K_DESTRUCT | PERLIO_K_RAW,
1706 PerlIOCede_pushed,
1707 PerlIOBuf_popped,
1708 PerlIOBuf_open,
1709 PerlIOBase_binmode,
1710 PerlIOCede_getarg,
1711 PerlIOBase_fileno,
1712 PerlIOBuf_dup,
1713 PerlIOBuf_read,
1714 PerlIOBuf_unread,
1715 PerlIOBuf_write,
1716 PerlIOBuf_seek,
1717 PerlIOBuf_tell,
1718 PerlIOBuf_close,
1719 PerlIOCede_flush,
1720 PerlIOBuf_fill,
1721 PerlIOBase_eof,
1722 PerlIOBase_error,
1723 PerlIOBase_clearerr,
1724 PerlIOBase_setlinebuf,
1725 PerlIOBuf_get_base,
1726 PerlIOBuf_bufsiz,
1727 PerlIOBuf_get_ptr,
1728 PerlIOBuf_get_cnt,
1729 PerlIOBuf_set_ptrcnt,
1730};
1731
1732
1733MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
1734
1735PROTOTYPES: DISABLE
1736
1737BOOT:
1738{
1739#ifdef USE_ITHREADS
1740 MUTEX_INIT (&coro_mutex);
1741#endif
1742 BOOT_PAGESIZE;
1743
1744 irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV);
1745 stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
1746
1747 orig_sigelem_get = PL_vtbl_sigelem.svt_get; PL_vtbl_sigelem.svt_get = coro_sigelem_get;
1748 orig_sigelem_set = PL_vtbl_sigelem.svt_set; PL_vtbl_sigelem.svt_set = coro_sigelem_set;
1749 orig_sigelem_clr = PL_vtbl_sigelem.svt_clear; PL_vtbl_sigelem.svt_clear = coro_sigelem_clr;
1750
1751 hv_sig = coro_get_hv (aTHX_ "SIG", TRUE);
1752 rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV));
1753 rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV));
1754
1755 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
1756
1757 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE));
1758 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB));
1759 newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE));
1760 newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL));
1761
1762 main_mainstack = PL_mainstack;
1763 main_top_env = PL_top_env;
1764
1765 while (main_top_env->je_prev)
1766 main_top_env = main_top_env->je_prev;
1767
1768 coroapi.ver = CORO_API_VERSION;
1769 coroapi.rev = CORO_API_REVISION;
1770 coroapi.transfer = api_transfer;
1771
1772 {
1773 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
1774
1775 if (!svp) croak ("Time::HiRes is required");
1776 if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer");
1777
1778 nvtime = INT2PTR (double (*)(), SvIV (*svp));
1779 }
1780
1781 assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL));
1782}
1783
1784SV *
1785new (char *klass, ...)
1786 CODE:
1787{
1788 struct coro *coro;
1789 MAGIC *mg;
1790 HV *hv;
1791 int i;
1792
1793 Newz (0, coro, 1, struct coro);
1794 coro->args = newAV ();
1795 coro->flags = CF_NEW;
1796
1797 if (coro_first) coro_first->prev = coro;
1798 coro->next = coro_first;
1799 coro_first = coro;
1800
1801 coro->hv = hv = newHV ();
1802 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
1803 mg->mg_flags |= MGf_DUP;
1804 RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
1805
1806 av_extend (coro->args, items - 1);
1807 for (i = 1; i < items; i++)
1808 av_push (coro->args, newSVsv (ST (i)));
1809}
1810 OUTPUT:
1811 RETVAL
1812
1813# these not obviously related functions are all rolled into the same xs
1814# function to increase chances that they all will call transfer with the same
1815# stack offset
1816void
1817_set_stacklevel (...)
1818 ALIAS:
1819 Coro::State::transfer = 1
1820 Coro::schedule = 2
1821 Coro::cede = 3
1822 Coro::cede_notself = 4
1823 CODE:
1824{
1825 struct transfer_args ta;
1826
1827 PUTBACK;
1828 switch (ix)
1829 {
1830 case 0:
1831 ta.prev = (struct coro *)INT2PTR (coro_cctx *, SvIV (ST (0)));
1832 ta.next = 0;
1833 break;
1834
1835 case 1:
1836 if (items != 2)
1837 croak ("Coro::State::transfer (prev,next) expects two arguments, not %d", items);
1838
1839 prepare_transfer (aTHX_ &ta, ST (0), ST (1));
1840 break;
1841
1842 case 2:
1843 prepare_schedule (aTHX_ &ta);
1844 break;
1845
1846 case 3:
1847 prepare_cede (aTHX_ &ta);
1848 break;
1849
1850 case 4:
1851 if (!prepare_cede_notself (aTHX_ &ta))
1852 XSRETURN_EMPTY;
1853
1854 break;
1855 }
1856 SPAGAIN;
1857
1858 BARRIER;
1859 PUTBACK;
1860 TRANSFER (ta, 0);
1861 SPAGAIN; /* might be the sp of a different coroutine now */
1862 /* be extra careful not to ever do anything after TRANSFER */
1863}
1864
1865bool
1866_destroy (SV *coro_sv)
1867 CODE:
1868 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
1869 OUTPUT:
1870 RETVAL
1871
1872void
1873_exit (int code)
1874 PROTOTYPE: $
1875 CODE:
1876 _exit (code);
1877
1878int
1879cctx_stacksize (int new_stacksize = 0)
1880 CODE:
1881 RETVAL = coro_stacksize;
1882 if (new_stacksize)
1883 coro_stacksize = new_stacksize;
1884 OUTPUT:
1885 RETVAL
1886
1887int
1888cctx_count ()
1889 CODE:
1890 RETVAL = cctx_count;
1891 OUTPUT:
1892 RETVAL
1893
1894int
1895cctx_idle ()
1896 CODE:
1897 RETVAL = cctx_idle;
1898 OUTPUT:
1899 RETVAL
1900
1901void
1902list ()
1903 PPCODE:
1904{
1905 struct coro *coro;
1906 for (coro = coro_first; coro; coro = coro->next)
1907 if (coro->hv)
1908 XPUSHs (sv_2mortal (newRV_inc ((SV *)coro->hv)));
1909}
1910
1911void
1912call (Coro::State coro, SV *coderef)
1913 ALIAS:
1914 eval = 1
1915 CODE:
1916{
1917 if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot))
1918 {
1919 struct coro temp;
1920
1921 if (!(coro->flags & CF_RUNNING))
235 { 1922 {
236 /* I never used formats, so how should I know how these are implemented? */ 1923 PUTBACK;
237 /* my bold guess is as a simple, plain sub... */ 1924 save_perl (aTHX_ &temp);
238 croak ("CXt_FORMAT not yet handled. Don't switch coroutines from within formats"); 1925 load_perl (aTHX_ coro);
1926 }
1927
1928 {
1929 dSP;
1930 ENTER;
1931 SAVETMPS;
1932 PUTBACK;
1933 PUSHSTACK;
1934 PUSHMARK (SP);
1935
1936 if (ix)
1937 eval_sv (coderef, 0);
1938 else
1939 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1940
1941 POPSTACK;
1942 SPAGAIN;
1943 FREETMPS;
1944 LEAVE;
1945 PUTBACK;
1946 }
1947
1948 if (!(coro->flags & CF_RUNNING))
1949 {
1950 save_perl (aTHX_ coro);
1951 load_perl (aTHX_ &temp);
1952 SPAGAIN;
239 } 1953 }
240 } 1954 }
241
242 if (top_si->si_type == PERLSI_MAIN)
243 break;
244
245 top_si = top_si->si_prev;
246 ccstk = top_si->si_cxstack;
247 cxix = top_si->si_cxix;
248 }
249
250 PUTBACK;
251 }
252
253 c->dowarn = PL_dowarn;
254 c->defav = GvAV (PL_defgv);
255 c->curstackinfo = PL_curstackinfo;
256 c->curstack = PL_curstack;
257 c->mainstack = PL_mainstack;
258 c->stack_sp = PL_stack_sp;
259 c->op = PL_op;
260 c->curpad = PL_curpad;
261 c->stack_base = PL_stack_base;
262 c->stack_max = PL_stack_max;
263 c->tmps_stack = PL_tmps_stack;
264 c->tmps_floor = PL_tmps_floor;
265 c->tmps_ix = PL_tmps_ix;
266 c->tmps_max = PL_tmps_max;
267 c->markstack = PL_markstack;
268 c->markstack_ptr = PL_markstack_ptr;
269 c->markstack_max = PL_markstack_max;
270 c->scopestack = PL_scopestack;
271 c->scopestack_ix = PL_scopestack_ix;
272 c->scopestack_max = PL_scopestack_max;
273 c->savestack = PL_savestack;
274 c->savestack_ix = PL_savestack_ix;
275 c->savestack_max = PL_savestack_max;
276 c->retstack = PL_retstack;
277 c->retstack_ix = PL_retstack_ix;
278 c->retstack_max = PL_retstack_max;
279 c->curcop = PL_curcop;
280} 1955}
281 1956
282#define LOAD(state) do { load_state(aTHX_ state); SPAGAIN; } while (0) 1957SV *
283#define SAVE(state) do { PUTBACK; save_state(aTHX_ state); } while (0) 1958is_ready (Coro::State coro)
1959 PROTOTYPE: $
1960 ALIAS:
1961 is_ready = CF_READY
1962 is_running = CF_RUNNING
1963 is_new = CF_NEW
1964 is_destroyed = CF_DESTROYED
1965 CODE:
1966 RETVAL = boolSV (coro->flags & ix);
1967 OUTPUT:
1968 RETVAL
284 1969
285static void 1970void
286load_state(pTHX_ Coro__State c) 1971api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
287{
288 PL_dowarn = c->dowarn;
289 GvAV (PL_defgv) = c->defav;
290 PL_curstackinfo = c->curstackinfo;
291 PL_curstack = c->curstack;
292 PL_mainstack = c->mainstack;
293 PL_stack_sp = c->stack_sp;
294 PL_op = c->op;
295 PL_curpad = c->curpad;
296 PL_stack_base = c->stack_base;
297 PL_stack_max = c->stack_max;
298 PL_tmps_stack = c->tmps_stack;
299 PL_tmps_floor = c->tmps_floor;
300 PL_tmps_ix = c->tmps_ix;
301 PL_tmps_max = c->tmps_max;
302 PL_markstack = c->markstack;
303 PL_markstack_ptr = c->markstack_ptr;
304 PL_markstack_max = c->markstack_max;
305 PL_scopestack = c->scopestack;
306 PL_scopestack_ix = c->scopestack_ix;
307 PL_scopestack_max = c->scopestack_max;
308 PL_savestack = c->savestack;
309 PL_savestack_ix = c->savestack_ix;
310 PL_savestack_max = c->savestack_max;
311 PL_retstack = c->retstack;
312 PL_retstack_ix = c->retstack_ix;
313 PL_retstack_max = c->retstack_max;
314 PL_curcop = c->curcop;
315 1972
1973SV *
1974has_cctx (Coro::State coro)
1975 PROTOTYPE: $
1976 CODE:
1977 RETVAL = boolSV (!!coro->cctx);
1978 OUTPUT:
1979 RETVAL
1980
1981int
1982is_traced (Coro::State coro)
1983 PROTOTYPE: $
1984 CODE:
1985 RETVAL = (coro->cctx ? coro->cctx->flags : 0) & CC_TRACE_ALL;
1986 OUTPUT:
1987 RETVAL
1988
1989IV
1990rss (Coro::State coro)
1991 PROTOTYPE: $
1992 ALIAS:
1993 usecount = 1
1994 CODE:
1995 switch (ix)
316 { 1996 {
317 dSP; 1997 case 0: RETVAL = coro_rss (aTHX_ coro); break;
318 CV *cv; 1998 case 1: RETVAL = coro->usecount; break;
319
320 /* now do the ugly restore mess */
321 while ((cv = (CV *)POPs))
322 {
323 AV *padlist = (AV *)POPs;
324
325 put_padlist (cv);
326 CvPADLIST(cv) = padlist;
327 CvDEPTH(cv) = (I32)POPs;
328
329#ifdef USE_THREADS
330 CvOWNER(cv) = (struct perl_thread *)POPs;
331 error does not work either
332#endif
333 } 1999 }
2000 OUTPUT:
2001 RETVAL
334 2002
335 PUTBACK; 2003void
336 } 2004force_cctx ()
337} 2005 CODE:
2006 struct coro *coro = SvSTATE (coro_current);
2007 coro->cctx->idle_sp = 0;
338 2008
339/* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ 2009void
340STATIC void 2010throw (Coro::State self, SV *throw = &PL_sv_undef)
341destroy_stacks(pTHX) 2011 PROTOTYPE: $;$
342{ 2012 CODE:
343 /* die does this while calling POPSTACK, but I just don't see why. */ 2013 SvREFCNT_dec (self->throw);
344 /* OTOH, die does not have a memleak, but we do... */ 2014 self->throw = SvOK (throw) ? newSVsv (throw) : 0;
345 dounwind(-1);
346 2015
347 /* is this ugly, I ask? */ 2016void
348 while (PL_scopestack_ix) 2017swap_defsv (Coro::State self)
349 LEAVE; 2018 PROTOTYPE: $
2019 ALIAS:
2020 swap_defav = 1
2021 CODE:
2022 if (!self->slot)
2023 croak ("cannot swap state with coroutine that has no saved state");
2024 else
2025 {
2026 SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv);
2027 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
350 2028
351 while (PL_curstackinfo->si_next) 2029 SV *tmp = *src; *src = *dst; *dst = tmp;
352 PL_curstackinfo = PL_curstackinfo->si_next; 2030 }
353 2031
354 while (PL_curstackinfo)
355 {
356 PERL_SI *p = PL_curstackinfo->si_prev;
357
358 SvREFCNT_dec(PL_curstackinfo->si_stack);
359 Safefree(PL_curstackinfo->si_cxstack);
360 Safefree(PL_curstackinfo);
361 PL_curstackinfo = p;
362 }
363
364 if (PL_scopestack_ix != 0)
365 Perl_warner(aTHX_ WARN_INTERNAL,
366 "Unbalanced scopes: %ld more ENTERs than LEAVEs\n",
367 (long)PL_scopestack_ix);
368 if (PL_savestack_ix != 0)
369 Perl_warner(aTHX_ WARN_INTERNAL,
370 "Unbalanced saves: %ld more saves than restores\n",
371 (long)PL_savestack_ix);
372 if (PL_tmps_floor != -1)
373 Perl_warner(aTHX_ WARN_INTERNAL,"Unbalanced tmps: %ld more allocs than frees\n",
374 (long)PL_tmps_floor + 1);
375 /*
376 */
377 Safefree(PL_tmps_stack);
378 Safefree(PL_markstack);
379 Safefree(PL_scopestack);
380 Safefree(PL_savestack);
381 Safefree(PL_retstack);
382}
383
384#define SUB_INIT "Coro::State::_newcoro"
385
386MODULE = Coro::State PACKAGE = Coro::State 2032MODULE = Coro::State PACKAGE = Coro
387
388PROTOTYPES: ENABLE
389 2033
390BOOT: 2034BOOT:
391 if (!padlist_cache) 2035{
392 padlist_cache = newHV (); 2036 int i;
393 2037
394Coro::State 2038 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
395_newprocess(args) 2039 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
396 SV * args 2040 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
2041
2042 coro_current = coro_get_sv (aTHX_ "Coro::current", FALSE);
2043 SvREADONLY_on (coro_current);
2044
2045 coro_stash = gv_stashpv ("Coro", TRUE);
2046
2047 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
2048 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
2049 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
2050 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW));
2051 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
2052 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN));
2053
2054 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
2055 coro_ready[i] = newAV ();
2056
2057 {
2058 SV *sv = perl_get_sv ("Coro::API", TRUE);
2059 perl_get_sv ("Coro::API", TRUE); /* silence 5.10 warning */
2060
2061 coroapi.schedule = api_schedule;
2062 coroapi.cede = api_cede;
2063 coroapi.cede_notself = api_cede_notself;
2064 coroapi.ready = api_ready;
2065 coroapi.is_ready = api_is_ready;
2066 coroapi.nready = &coro_nready;
2067 coroapi.current = coro_current;
2068
2069 GCoroAPI = &coroapi;
2070 sv_setiv (sv, (IV)&coroapi);
2071 SvREADONLY_on (sv);
2072 }
2073}
2074
2075void
2076_set_current (SV *current)
397 PROTOTYPE: $ 2077 PROTOTYPE: $
2078 CODE:
2079 SvREFCNT_dec (SvRV (coro_current));
2080 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current)));
2081
2082void
2083_set_readyhook (SV *hook)
2084 PROTOTYPE: $
398 CODE: 2085 CODE:
399 Coro__State coro;
400
401 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV)
402 croak ("Coro::State::newprocess expects an arrayref");
403 2086 LOCK;
404 New (0, coro, 1, struct coro); 2087 SvREFCNT_dec (coro_readyhook);
2088 coro_readyhook = SvOK (hook) ? newSVsv (hook) : 0;
2089 UNLOCK;
405 2090
406 coro->mainstack = 0; /* actual work is done inside transfer */ 2091int
407 coro->args = (AV *)SvREFCNT_inc (SvRV (args)); 2092prio (Coro::State coro, int newprio = 0)
408 2093 ALIAS:
2094 nice = 1
2095 CODE:
2096{
409 RETVAL = coro; 2097 RETVAL = coro->prio;
410 OUTPUT: 2098
2099 if (items > 1)
2100 {
2101 if (ix)
2102 newprio = coro->prio - newprio;
2103
2104 if (newprio < PRIO_MIN) newprio = PRIO_MIN;
2105 if (newprio > PRIO_MAX) newprio = PRIO_MAX;
2106
2107 coro->prio = newprio;
2108 }
2109}
2110 OUTPUT:
411 RETVAL 2111 RETVAL
412 2112
2113SV *
2114ready (SV *self)
2115 PROTOTYPE: $
2116 CODE:
2117 RETVAL = boolSV (api_ready (self));
2118 OUTPUT:
2119 RETVAL
2120
2121int
2122nready (...)
2123 PROTOTYPE:
2124 CODE:
2125 RETVAL = coro_nready;
2126 OUTPUT:
2127 RETVAL
2128
2129# for async_pool speedup
413void 2130void
414transfer(prev,next) 2131_pool_1 (SV *cb)
415 Coro::State_or_hashref prev 2132 CODE:
416 Coro::State_or_hashref next 2133{
2134 struct coro *coro = SvSTATE (coro_current);
2135 HV *hv = (HV *)SvRV (coro_current);
2136 AV *defav = GvAV (PL_defgv);
2137 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
2138 AV *invoke_av;
2139 int i, len;
2140
2141 if (!invoke)
2142 {
2143 SV *old = PL_diehook;
2144 PL_diehook = 0;
2145 SvREFCNT_dec (old);
2146 croak ("\3async_pool terminate\2\n");
2147 }
2148
2149 SvREFCNT_dec (coro->saved_deffh);
2150 coro->saved_deffh = SvREFCNT_inc_NN ((SV *)PL_defoutgv);
2151
2152 hv_store (hv, "desc", sizeof ("desc") - 1,
2153 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
2154
2155 invoke_av = (AV *)SvRV (invoke);
2156 len = av_len (invoke_av);
2157
2158 sv_setsv (cb, AvARRAY (invoke_av)[0]);
2159
2160 if (len > 0)
2161 {
2162 av_fill (defav, len - 1);
2163 for (i = 0; i < len; ++i)
2164 av_store (defav, i, SvREFCNT_inc_NN (AvARRAY (invoke_av)[i + 1]));
2165 }
2166
2167 SvREFCNT_dec (invoke);
2168}
2169
2170void
2171_pool_2 (SV *cb)
2172 CODE:
2173{
2174 struct coro *coro = SvSTATE (coro_current);
2175
2176 sv_setsv (cb, &PL_sv_undef);
2177
2178 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
2179 coro->saved_deffh = 0;
2180
2181 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss)
2182 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
2183 {
2184 SV *old = PL_diehook;
2185 PL_diehook = 0;
2186 SvREFCNT_dec (old);
2187 croak ("\3async_pool terminate\2\n");
2188 }
2189
2190 av_clear (GvAV (PL_defgv));
2191 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1,
2192 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
2193
2194 coro->prio = 0;
2195
2196 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
2197 api_trace (coro_current, 0);
2198
2199 av_push (av_async_pool, newSVsv (coro_current));
2200}
2201
2202#if 0
2203
2204void
2205_generator_call (...)
2206 PROTOTYPE: @
2207 PPCODE:
2208 fprintf (stderr, "call %p\n", CvXSUBANY(cv).any_ptr);
2209 xxxx
2210 abort ();
2211
2212SV *
2213gensub (SV *sub, ...)
2214 PROTOTYPE: &;@
417 CODE: 2215 CODE:
2216{
2217 struct coro *coro;
2218 MAGIC *mg;
2219 CV *xcv;
2220 CV *ncv = (CV *)newSV_type (SVt_PVCV);
2221 int i;
418 2222
419 if (prev != next) 2223 CvGV (ncv) = CvGV (cv);
2224 CvFILE (ncv) = CvFILE (cv);
2225
2226 Newz (0, coro, 1, struct coro);
2227 coro->args = newAV ();
2228 coro->flags = CF_NEW;
2229
2230 av_extend (coro->args, items - 1);
2231 for (i = 1; i < items; i++)
2232 av_push (coro->args, newSVsv (ST (i)));
2233
2234 CvISXSUB_on (ncv);
2235 CvXSUBANY (ncv).any_ptr = (void *)coro;
2236
2237 xcv = GvCV (gv_fetchpv ("Coro::_generator_call", 0, SVt_PVCV));
2238
2239 CvXSUB (ncv) = CvXSUB (xcv);
2240 CvANON_on (ncv);
2241
2242 mg = sv_magicext ((SV *)ncv, 0, CORO_MAGIC_type_state, &coro_gensub_vtbl, (char *)coro, 0);
2243 RETVAL = newRV_noinc ((SV *)ncv);
2244}
2245 OUTPUT:
2246 RETVAL
2247
2248#endif
2249
2250
2251MODULE = Coro::State PACKAGE = Coro::AIO
2252
2253void
2254_get_state (SV *self)
2255 PPCODE:
2256{
2257 AV *defav = GvAV (PL_defgv);
2258 AV *av = newAV ();
2259 int i;
2260 SV *data_sv = newSV (sizeof (struct io_state));
2261 struct io_state *data = (struct io_state *)SvPVX (data_sv);
2262 SvCUR_set (data_sv, sizeof (struct io_state));
2263 SvPOK_only (data_sv);
2264
2265 data->errorno = errno;
2266 data->laststype = PL_laststype;
2267 data->laststatval = PL_laststatval;
2268 data->statcache = PL_statcache;
2269
2270 av_extend (av, AvFILLp (defav) + 1 + 1);
2271
2272 for (i = 0; i <= AvFILLp (defav); ++i)
2273 av_push (av, SvREFCNT_inc_NN (AvARRAY (defav)[i]));
2274
2275 av_push (av, data_sv);
2276
2277 XPUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
2278
2279 api_ready (self);
2280}
2281
2282void
2283_set_state (SV *state)
2284 PROTOTYPE: $
2285 PPCODE:
2286{
2287 AV *av = (AV *)SvRV (state);
2288 struct io_state *data = (struct io_state *)SvPVX (AvARRAY (av)[AvFILLp (av)]);
2289 int i;
2290
2291 errno = data->errorno;
2292 PL_laststype = data->laststype;
2293 PL_laststatval = data->laststatval;
2294 PL_statcache = data->statcache;
2295
2296 EXTEND (SP, AvFILLp (av));
2297 for (i = 0; i < AvFILLp (av); ++i)
2298 PUSHs (sv_2mortal (SvREFCNT_inc_NN (AvARRAY (av)[i])));
2299}
2300
2301
2302MODULE = Coro::State PACKAGE = Coro::AnyEvent
2303
2304BOOT:
2305 sv_activity = coro_get_sv (aTHX_ "Coro::AnyEvent::ACTIVITY", TRUE);
2306
2307SV *
2308_schedule (...)
2309 PROTOTYPE: @
2310 CODE:
2311{
2312 static int incede;
2313
2314 api_cede_notself ();
2315
2316 ++incede;
2317 while (coro_nready >= incede && api_cede ())
2318 ;
2319
2320 sv_setsv (sv_activity, &PL_sv_undef);
2321 if (coro_nready >= incede)
420 { 2322 {
421 /*
422 * this could be done in newprocess which would lead to
423 * extremely elegant and fast (just SAVE/LOAD)
424 * code here, but lazy allocation of stacks has also
425 * some virtues and the overhead of the if() is nil.
426 */
427 if (next->mainstack)
428 {
429 SAVE (prev);
430 LOAD (next);
431 /* mark this state as in-use */
432 next->mainstack = 0;
433 next->tmps_ix = -2;
434 }
435 else if (next->tmps_ix == -2)
436 {
437 croak ("tried to transfer to running coroutine");
438 }
439 else
440 {
441 SAVE (prev);
442
443 /*
444 * emulate part of the perl startup here.
445 */
446 UNOP myop;
447
448 init_stacks (); /* from perl.c */
449 PL_op = (OP *)&myop;
450 /*PL_curcop = 0;*/
451 GvAV (PL_defgv) = (AV *)SvREFCNT_inc ((SV *)next->args);
452
453 SPAGAIN;
454 Zero(&myop, 1, UNOP);
455 myop.op_next = Nullop;
456 myop.op_flags = OPf_WANT_VOID;
457
458 PUSHMARK(SP); 2323 PUSHMARK (SP);
459 XPUSHs ((SV*)get_cv(SUB_INIT, TRUE));
460 PUTBACK; 2324 PUTBACK;
461 /* 2325 call_pv ("Coro::AnyEvent::_activity", G_DISCARD | G_EVAL);
462 * the next line is slightly wrong, as PL_op->op_next
463 * is actually being executed so we skip the first op.
464 * that doesn't matter, though, since it is only
465 * pp_nextstate and we never return...
466 */
467 PL_op = Perl_pp_entersub(aTHX);
468 SPAGAIN; 2326 SPAGAIN;
469
470 ENTER;
471 }
472 } 2327 }
473 2328
474void 2329 --incede;
475DESTROY(coro) 2330}
476 Coro::State coro
477 CODE:
478 2331
479 if (coro->mainstack)
480 {
481 struct coro temp;
482 2332
483 SAVE(aTHX_ (&temp)); 2333MODULE = Coro::State PACKAGE = PerlIO::cede
484 LOAD(aTHX_ coro);
485 2334
486 destroy_stacks (); 2335BOOT:
487 SvREFCNT_dec ((SV *)GvAV (PL_defgv)); 2336 PerlIO_define_layer (aTHX_ &PerlIO_cede);
488
489 LOAD((&temp));
490 }
491
492 SvREFCNT_dec (coro->args);
493 Safefree (coro);
494
495

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines