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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines