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.376 by root, Fri Oct 2 20:48:04 2009 UTC

1#define NDEBUG 1
2
3#include "libcoro/coro.c"
4
5#define PERL_NO_GET_CONTEXT
6#define PERL_EXT
7
1#include "EXTERN.h" 8#include "EXTERN.h"
2#include "perl.h" 9#include "perl.h"
3#include "XSUB.h" 10#include "XSUB.h"
11#include "perliol.h"
4 12
5#if 0 13#include "schmorp.h"
6# define CHK(x) (void *)0 14
15#include <stdio.h>
16#include <errno.h>
17#include <assert.h>
18
19#ifndef SVs_PADSTALE
20# define SVs_PADSTALE 0
21#endif
22
23#ifdef WIN32
24# undef setjmp
25# undef longjmp
26# undef _exit
27# define setjmp _setjmp /* deep magic */
7#else 28#else
8# define CHK(x) if (!(x)) croak("FATAL, CHK: " #x) 29# include <inttypes.h> /* most portable stdint.h */
9#endif 30#endif
10 31
32#ifdef HAVE_MMAP
33# include <unistd.h>
34# include <sys/mman.h>
35# ifndef MAP_ANONYMOUS
36# ifdef MAP_ANON
37# define MAP_ANONYMOUS MAP_ANON
38# else
39# undef HAVE_MMAP
40# endif
41# endif
42# include <limits.h>
43# ifndef PAGESIZE
44# define PAGESIZE pagesize
45# define BOOT_PAGESIZE pagesize = sysconf (_SC_PAGESIZE)
46static long pagesize;
47# else
48# define BOOT_PAGESIZE (void)0
49# endif
50#else
51# define PAGESIZE 0
52# define BOOT_PAGESIZE (void)0
53#endif
54
55#if CORO_USE_VALGRIND
56# include <valgrind/valgrind.h>
57#endif
58
59/* the maximum number of idle cctx that will be pooled */
60static int cctx_max_idle = 4;
61
62#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
63# undef CORO_STACKGUARD
64#endif
65
66#ifndef CORO_STACKGUARD
67# define CORO_STACKGUARD 0
68#endif
69
70/* prefer perl internal functions over our own? */
71#ifndef CORO_PREFER_PERL_FUNCTIONS
72# define CORO_PREFER_PERL_FUNCTIONS 0
73#endif
74
75/* The next macros try to return the current stack pointer, in an as
76 * portable way as possible. */
77#if __GNUC__ >= 4
78# define dSTACKLEVEL int stacklevel_dummy
79# define STACKLEVEL __builtin_frame_address (0)
80#else
81# define dSTACKLEVEL volatile void *stacklevel
82# define STACKLEVEL ((void *)&stacklevel)
83#endif
84
85#define IN_DESTRUCT PL_dirty
86
87#if __GNUC__ >= 3
88# define attribute(x) __attribute__(x)
89# define expect(expr,value) __builtin_expect ((expr), (value))
90# define INLINE static inline
91#else
92# define attribute(x)
93# define expect(expr,value) (expr)
94# define INLINE static
95#endif
96
97#define expect_false(expr) expect ((expr) != 0, 0)
98#define expect_true(expr) expect ((expr) != 0, 1)
99
100#define NOINLINE attribute ((noinline))
101
102#include "CoroAPI.h"
103#define GCoroAPI (&coroapi) /* very sneaky */
104
105#ifdef USE_ITHREADS
106# if CORO_PTHREAD
107static void *coro_thx;
108# endif
109#endif
110
111#ifdef __linux
112# include <time.h> /* for timespec */
113# include <syscall.h> /* for SYS_* */
114# ifdef SYS_clock_gettime
115# define coro_clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts))
116# define CORO_CLOCK_MONOTONIC 1
117# define CORO_CLOCK_THREAD_CPUTIME_ID 3
118# endif
119#endif
120
121static double (*nvtime)(); /* so why doesn't it take void? */
122static void (*u2time)(pTHX_ UV ret[2]);
123
124/* we hijack an hopefully unused CV flag for our purposes */
125#define CVf_SLF 0x4000
126static OP *pp_slf (pTHX);
127
128static U32 cctx_gen;
129static size_t cctx_stacksize = CORO_STACKSIZE;
130static struct CoroAPI coroapi;
131static AV *main_mainstack; /* used to differentiate between $main and others */
132static JMPENV *main_top_env;
133static HV *coro_state_stash, *coro_stash;
134static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */
135
136static AV *av_destroy; /* destruction queue */
137static SV *sv_manager; /* the manager coro */
138static SV *sv_idle; /* $Coro::idle */
139
140static GV *irsgv; /* $/ */
141static GV *stdoutgv; /* *STDOUT */
142static SV *rv_diehook;
143static SV *rv_warnhook;
144static HV *hv_sig; /* %SIG */
145
146/* async_pool helper stuff */
147static SV *sv_pool_rss;
148static SV *sv_pool_size;
149static SV *sv_async_pool_idle; /* description string */
150static AV *av_async_pool; /* idle pool */
151static SV *sv_Coro; /* class string */
152static CV *cv_pool_handler;
153
154/* Coro::AnyEvent */
155static SV *sv_activity;
156
157/* enable processtime/realtime profiling */
158static char enable_times;
159typedef U32 coro_ts[2];
160static coro_ts time_real, time_cpu;
161static char times_valid;
162
163static struct coro_cctx *cctx_first;
164static int cctx_count, cctx_idle;
165
166enum {
167 CC_MAPPED = 0x01,
168 CC_NOREUSE = 0x02, /* throw this away after tracing */
169 CC_TRACE = 0x04,
170 CC_TRACE_SUB = 0x08, /* trace sub calls */
171 CC_TRACE_LINE = 0x10, /* trace each statement */
172 CC_TRACE_ALL = CC_TRACE_SUB | CC_TRACE_LINE,
173};
174
175/* this is a structure representing a c-level coroutine */
176typedef struct coro_cctx
177{
178 struct coro_cctx *next;
179
180 /* the stack */
181 void *sptr;
182 size_t ssize;
183
184 /* cpu state */
185 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
186 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */
187 JMPENV *top_env;
188 coro_context cctx;
189
190 U32 gen;
191#if CORO_USE_VALGRIND
192 int valgrind_id;
193#endif
194 unsigned char flags;
195} coro_cctx;
196
197coro_cctx *cctx_current; /* the currently running cctx */
198
199/*****************************************************************************/
200
201enum {
202 CF_RUNNING = 0x0001, /* coroutine is running */
203 CF_READY = 0x0002, /* coroutine is ready */
204 CF_NEW = 0x0004, /* has never been switched to */
205 CF_DESTROYED = 0x0008, /* coroutine data has been freed */
206 CF_SUSPENDED = 0x0010, /* coroutine can't be scheduled */
207};
208
209/* the structure where most of the perl state is stored, overlaid on the cxstack */
210typedef struct
211{
212 SV *defsv;
213 AV *defav;
214 SV *errsv;
215 SV *irsgv;
216 HV *hinthv;
217#define VAR(name,type) type name;
218# include "state.h"
219#undef VAR
220} perl_slots;
221
222#define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT))
223
224/* this is a structure representing a perl-level coroutine */
11struct coro { 225struct coro {
12 U8 dowarn; 226 /* the C coroutine allocated to this perl coroutine, if any */
13 AV *defav; 227 coro_cctx *cctx;
14 228
15 PERL_SI *curstackinfo; 229 /* ready queue */
16 AV *curstack; 230 struct coro *next_ready;
231
232 /* state data */
233 struct CoroSLF slf_frame; /* saved slf frame */
17 AV *mainstack; 234 AV *mainstack;
18 SV **stack_sp; 235 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 236
41 AV *args; 237 CV *startcv; /* the CV to execute */
238 AV *args; /* data associated with this coroutine (initial args) */
239 int refcnt; /* coroutines are refcounted, yes */
240 int flags; /* CF_ flags */
241 HV *hv; /* the perl hash associated with this coro, if any */
242 void (*on_destroy)(pTHX_ struct coro *coro);
243
244 /* statistics */
245 int usecount; /* number of transfers to this coro */
246
247 /* coro process data */
248 int prio;
249 SV *except; /* exception to be thrown */
250 SV *rouse_cb;
251
252 /* async_pool */
253 SV *saved_deffh;
254 SV *invoke_cb;
255 AV *invoke_av;
256
257 /* on_enter/on_leave */
258 AV *on_enter;
259 AV *on_leave;
260
261 /* swap_sv */
262 AV *swap_sv;
263
264 /* times */
265 coro_ts t_cpu, t_real;
266
267 /* linked list */
268 struct coro *next, *prev;
42}; 269};
43 270
44typedef struct coro *Coro__State; 271typedef struct coro *Coro__State;
45typedef struct coro *Coro__State_or_hashref; 272typedef struct coro *Coro__State_or_hashref;
46 273
47static HV *padlist_cache; 274/* the following variables are effectively part of the perl context */
275/* and get copied between struct coro and these variables */
276/* the mainr easonw e don't support windows process emulation */
277static struct CoroSLF slf_frame; /* the current slf frame */
48 278
49/* mostly copied from op.c:cv_clone2 */ 279/** Coro ********************************************************************/
50STATIC AV * 280
51clone_padlist (AV *protopadlist) 281#define CORO_PRIO_MAX 3
282#define CORO_PRIO_HIGH 1
283#define CORO_PRIO_NORMAL 0
284#define CORO_PRIO_LOW -1
285#define CORO_PRIO_IDLE -3
286#define CORO_PRIO_MIN -4
287
288/* for Coro.pm */
289static SV *coro_current;
290static SV *coro_readyhook;
291static struct coro *coro_ready [CORO_PRIO_MAX - CORO_PRIO_MIN + 1][2]; /* head|tail */
292static CV *cv_coro_run, *cv_coro_terminate;
293static struct coro *coro_first;
294#define coro_nready coroapi.nready
295
296/** Coro::Select ************************************************************/
297
298static OP *(*coro_old_pp_sselect) (pTHX);
299static SV *coro_select_select;
300
301/* horrible hack, but if it works... */
302static OP *
303coro_pp_sselect (pTHX)
52{ 304{
53 AV *av; 305 dSP;
54 I32 ix; 306 PUSHMARK (SP - 4); /* fake argument list */
55 AV *protopad_name = (AV *) * av_fetch (protopadlist, 0, FALSE); 307 XPUSHs (coro_select_select);
56 AV *protopad = (AV *) * av_fetch (protopadlist, 1, FALSE); 308 PUTBACK;
57 SV **pname = AvARRAY (protopad_name); 309
58 SV **ppad = AvARRAY (protopad); 310 /* entersub is an UNOP, select a LISTOP... keep your fingers crossed */
59 I32 fname = AvFILLp (protopad_name); 311 PL_op->op_flags |= OPf_STACKED;
60 I32 fpad = AvFILLp (protopad); 312 PL_op->op_private = 0;
313 return PL_ppaddr [OP_ENTERSUB](aTHX);
314}
315
316/** lowlevel stuff **********************************************************/
317
318static SV *
319coro_get_sv (pTHX_ const char *name, int create)
320{
321#if PERL_VERSION_ATLEAST (5,10,0)
322 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
323 get_sv (name, create);
324#endif
325 return get_sv (name, create);
326}
327
328static AV *
329coro_get_av (pTHX_ const char *name, int create)
330{
331#if PERL_VERSION_ATLEAST (5,10,0)
332 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
333 get_av (name, create);
334#endif
335 return get_av (name, create);
336}
337
338static HV *
339coro_get_hv (pTHX_ const char *name, int create)
340{
341#if PERL_VERSION_ATLEAST (5,10,0)
342 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
343 get_hv (name, create);
344#endif
345 return get_hv (name, create);
346}
347
348INLINE void
349coro_times_update ()
350{
351#ifdef coro_clock_gettime
352 struct timespec ts;
353
354 ts.tv_sec = ts.tv_nsec = 0;
355 coro_clock_gettime (CORO_CLOCK_THREAD_CPUTIME_ID, &ts);
356 time_cpu [0] = ts.tv_sec; time_cpu [1] = ts.tv_nsec;
357
358 ts.tv_sec = ts.tv_nsec = 0;
359 coro_clock_gettime (CORO_CLOCK_MONOTONIC, &ts);
360 time_real [0] = ts.tv_sec; time_real [1] = ts.tv_nsec;
361#else
362 dTHX;
363 UV tv[2];
364
365 u2time (aTHX_ tv);
366 time_real [0] = tv [0];
367 time_real [1] = tv [1] * 1000;
368#endif
369}
370
371INLINE void
372coro_times_add (struct coro *c)
373{
374 c->t_real [1] += time_real [1];
375 if (c->t_real [1] > 1000000000) { c->t_real [1] -= 1000000000; ++c->t_real [0]; }
376 c->t_real [0] += time_real [0];
377
378 c->t_cpu [1] += time_cpu [1];
379 if (c->t_cpu [1] > 1000000000) { c->t_cpu [1] -= 1000000000; ++c->t_cpu [0]; }
380 c->t_cpu [0] += time_cpu [0];
381}
382
383INLINE void
384coro_times_sub (struct coro *c)
385{
386 if (c->t_real [1] < time_real [1]) { c->t_real [1] += 1000000000; --c->t_real [0]; }
387 c->t_real [1] -= time_real [1];
388 c->t_real [0] -= time_real [0];
389
390 if (c->t_cpu [1] < time_cpu [1]) { c->t_cpu [1] += 1000000000; --c->t_cpu [0]; }
391 c->t_cpu [1] -= time_cpu [1];
392 c->t_cpu [0] -= time_cpu [0];
393}
394
395/*****************************************************************************/
396/* magic glue */
397
398#define CORO_MAGIC_type_cv 26
399#define CORO_MAGIC_type_state PERL_MAGIC_ext
400
401#define CORO_MAGIC_NN(sv, type) \
402 (expect_true (SvMAGIC (sv)->mg_type == type) \
403 ? SvMAGIC (sv) \
404 : mg_find (sv, type))
405
406#define CORO_MAGIC(sv, type) \
407 (expect_true (SvMAGIC (sv)) \
408 ? CORO_MAGIC_NN (sv, type) \
409 : 0)
410
411#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv)
412#define CORO_MAGIC_state(sv) CORO_MAGIC_NN (((SV *)(sv)), CORO_MAGIC_type_state)
413
414INLINE struct coro *
415SvSTATE_ (pTHX_ SV *coro)
416{
417 HV *stash;
418 MAGIC *mg;
419
420 if (SvROK (coro))
421 coro = SvRV (coro);
422
423 if (expect_false (SvTYPE (coro) != SVt_PVHV))
424 croak ("Coro::State object required");
425
426 stash = SvSTASH (coro);
427 if (expect_false (stash != coro_stash && stash != coro_state_stash))
428 {
429 /* very slow, but rare, check */
430 if (!sv_derived_from (sv_2mortal (newRV_inc (coro)), "Coro::State"))
431 croak ("Coro::State object required");
432 }
433
434 mg = CORO_MAGIC_state (coro);
435 return (struct coro *)mg->mg_ptr;
436}
437
438#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv))
439
440/* faster than SvSTATE, but expects a coroutine hv */
441#define SvSTATE_hv(hv) ((struct coro *)CORO_MAGIC_NN ((SV *)hv, CORO_MAGIC_type_state)->mg_ptr)
442#define SvSTATE_current SvSTATE_hv (SvRV (coro_current))
443
444/*****************************************************************************/
445/* padlist management and caching */
446
447static AV *
448coro_derive_padlist (pTHX_ CV *cv)
449{
450 AV *padlist = CvPADLIST (cv);
61 AV *newpadlist, *newpad_name, *newpad; 451 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 452
72 newpadlist = newAV (); 453 newpadlist = newAV ();
73 AvREAL_off (newpadlist); 454 AvREAL_off (newpadlist);
74 av_store (newpadlist, 0, (SV *) newpad_name); 455#if PERL_VERSION_ATLEAST (5,10,0)
456 Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1);
457#else
458 Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1, 1);
459#endif
460 newpad = (AV *)AvARRAY (padlist)[AvFILLp (padlist)];
461 --AvFILLp (padlist);
462
463 av_store (newpadlist, 0, SvREFCNT_inc_NN (AvARRAY (padlist)[0]));
75 av_store (newpadlist, 1, (SV *) newpad); 464 av_store (newpadlist, 1, (SV *)newpad);
76 465
77 av = newAV (); /* will be @_ */ 466 return newpadlist;
78 av_extend (av, 0); 467}
79 av_store (newpad, 0, (SV *) av);
80 AvFLAGS (av) = AVf_REIFY;
81 468
82 for (ix = fpad; ix > 0; ix--) 469static void
470free_padlist (pTHX_ AV *padlist)
471{
472 /* may be during global destruction */
473 if (!IN_DESTRUCT)
83 { 474 {
84 SV *namesv = (ix <= fname) ? pname[ix] : Nullsv; 475 I32 i = AvFILLp (padlist);
85 if (namesv && namesv != &PL_sv_undef) 476
477 while (i > 0) /* special-case index 0 */
86 { 478 {
87 char *name = SvPVX (namesv); /* XXX */ 479 /* we try to be extra-careful here */
88 if (SvFLAGS (namesv) & SVf_FAKE || *name == '&') 480 AV *av = (AV *)AvARRAY (padlist)[i--];
89 { /* lexical from outside? */ 481 I32 j = AvFILLp (av);
90 npad[ix] = SvREFCNT_inc (ppad[ix]); 482
91 } 483 while (j >= 0)
92 else 484 SvREFCNT_dec (AvARRAY (av)[j--]);
93 { /* our own lexical */ 485
94 SV *sv; 486 AvFILLp (av) = -1;
95 if (*name == '&') 487 SvREFCNT_dec (av);
96 sv = SvREFCNT_inc (ppad[ix]);
97 else if (*name == '@')
98 sv = (SV *) newAV ();
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 }
107 } 488 }
108 else if (IS_PADGV (ppad[ix]) || IS_PADCONST (ppad[ix])) 489
109 { 490 SvREFCNT_dec (AvARRAY (padlist)[0]);
110 npad[ix] = SvREFCNT_inc (ppad[ix]); 491
111 } 492 AvFILLp (padlist) = -1;
493 SvREFCNT_dec ((SV*)padlist);
494 }
495}
496
497static int
498coro_cv_free (pTHX_ SV *sv, MAGIC *mg)
499{
500 AV *padlist;
501 AV *av = (AV *)mg->mg_obj;
502
503 /* perl manages to free our internal AV and _then_ call us */
504 if (IN_DESTRUCT)
505 return 0;
506
507 /* casting is fun. */
508 while (&PL_sv_undef != (SV *)(padlist = (AV *)av_pop (av)))
509 free_padlist (aTHX_ padlist);
510
511 SvREFCNT_dec (av); /* sv_magicext increased the refcount */
512
513 return 0;
514}
515
516static MGVTBL coro_cv_vtbl = {
517 0, 0, 0, 0,
518 coro_cv_free
519};
520
521/* the next two functions merely cache the padlists */
522static void
523get_padlist (pTHX_ CV *cv)
524{
525 MAGIC *mg = CORO_MAGIC_cv (cv);
526 AV *av;
527
528 if (expect_true (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0))
529 CvPADLIST (cv) = (AV *)AvARRAY (av)[AvFILLp (av)--];
112 else 530 else
113 { 531 {
114 SV *sv = NEWSV (0, 0); 532#if CORO_PREFER_PERL_FUNCTIONS
115 SvPADTMP_on (sv); 533 /* this is probably cleaner? but also slower! */
116 npad[ix] = sv; 534 /* in practise, it seems to be less stable */
117 } 535 CV *cp = Perl_cv_clone (aTHX_ cv);
118 } 536 CvPADLIST (cv) = CvPADLIST (cp);
119 537 CvPADLIST (cp) = 0;
120#if 0 /* NONOTUNDERSTOOD */ 538 SvREFCNT_dec (cp);
121 /* Now that vars are all in place, clone nested closures. */ 539#else
122 540 CvPADLIST (cv) = coro_derive_padlist (aTHX_ cv);
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 541#endif
139 542 }
140 return newpadlist;
141} 543}
142 544
143STATIC AV * 545static void
144free_padlist (AV *padlist) 546put_padlist (pTHX_ CV *cv)
145{ 547{
146 /* may be during global destruction */ 548 MAGIC *mg = CORO_MAGIC_cv (cv);
147 if (SvREFCNT(padlist)) 549 AV *av;
550
551 if (expect_false (!mg))
552 mg = sv_magicext ((SV *)cv, (SV *)newAV (), CORO_MAGIC_type_cv, &coro_cv_vtbl, 0, 0);
553
554 av = (AV *)mg->mg_obj;
555
556 if (expect_false (AvFILLp (av) >= AvMAX (av)))
557 av_extend (av, AvFILLp (av) + 1);
558
559 AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv);
560}
561
562/** load & save, init *******************************************************/
563
564/* swap sv heads, at least logically */
565static void
566swap_svs (pTHX_ Coro__State c)
567{
568 int i;
569
570 for (i = 0; i <= AvFILLp (c->swap_sv); )
148 { 571 {
149 I32 i = AvFILLp(padlist); 572 SV *a = AvARRAY (c->swap_sv)[i++];
150 while (i >= 0) 573 SV *b = AvARRAY (c->swap_sv)[i++];
574
575 const U32 keep = SVs_PADSTALE | SVs_PADTMP | SVs_PADMY; /* keep these flags */
576 SV tmp;
577
578 /* swap sv_any */
579 SvANY (&tmp) = SvANY (a); SvANY (a) = SvANY (b); SvANY (b) = SvANY (&tmp);
580
581 /* swap sv_flags */
582 SvFLAGS (&tmp) = SvFLAGS (a);
583 SvFLAGS (a) = (SvFLAGS (a) & keep) | (SvFLAGS (b ) & ~keep);
584 SvFLAGS (b) = (SvFLAGS (b) & keep) | (SvFLAGS (&tmp) & ~keep);
585
586#if PERL_VERSION_ATLEAST (5,10,0)
587 /* perl 5.10 complicates this _quite_ a bit, but it also is
588 * is much faster, so no quarrels here. alternatively, we could
589 * sv_upgrade to avoid this.
590 */
151 { 591 {
152 SV **svp = av_fetch(padlist, i--, FALSE); 592 /* swap sv_u */
153 SV *sv = svp ? *svp : Nullsv; 593 tmp.sv_u = a->sv_u; a->sv_u = b->sv_u; b->sv_u = tmp.sv_u;
154 if (sv) 594
155 SvREFCNT_dec(sv); 595 /* if SvANY points to the head, we need to adjust the pointers,
596 * as the pointer for a still points to b, and maybe vice versa.
597 */
598 #define svany_in_head(type) \
599 (((1 << SVt_NULL) | (1 << SVt_BIND) | (1 << SVt_IV) | (1 << SVt_RV)) & (1 << (type)))
600
601 if (svany_in_head (SvTYPE (a)))
602 SvANY (a) = (void *)((PTRV)SvANY (a) - (PTRV)b + (PTRV)a);
603
604 if (svany_in_head (SvTYPE (b)))
605 SvANY (b) = (void *)((PTRV)SvANY (b) - (PTRV)a + (PTRV)b);
156 } 606 }
607#endif
608 }
609}
157 610
158 SvREFCNT_dec((SV*)padlist); 611#define SWAP_SVS(coro) \
612 if (expect_false ((coro)->swap_sv)) \
613 swap_svs (aTHX_ (coro))
614
615static void
616on_enterleave_call (pTHX_ SV *cb);
617
618static void
619load_perl (pTHX_ Coro__State c)
620{
621 perl_slots *slot = c->slot;
622 c->slot = 0;
623
624 PL_mainstack = c->mainstack;
625
626 GvSV (PL_defgv) = slot->defsv;
627 GvAV (PL_defgv) = slot->defav;
628 GvSV (PL_errgv) = slot->errsv;
629 GvSV (irsgv) = slot->irsgv;
630 GvHV (PL_hintgv) = slot->hinthv;
631
632 #define VAR(name,type) PL_ ## name = slot->name;
633 # include "state.h"
634 #undef VAR
635
636 {
637 dSP;
638
639 CV *cv;
640
641 /* now do the ugly restore mess */
642 while (expect_true (cv = (CV *)POPs))
643 {
644 put_padlist (aTHX_ cv); /* mark this padlist as available */
645 CvDEPTH (cv) = PTR2IV (POPs);
646 CvPADLIST (cv) = (AV *)POPs;
647 }
648
649 PUTBACK;
159 } 650 }
160}
161 651
162/* the next tow functions merely cache the padlists */ 652 slf_frame = c->slf_frame;
163STATIC void 653 CORO_THROW = c->except;
164get_padlist (CV *cv)
165{
166 SV **he = hv_fetch (padlist_cache, (void *)&cv, sizeof (CV *), 0);
167 654
168 if (he && AvFILLp ((AV *)*he) >= 0) 655 if (expect_false (enable_times))
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 } 656 {
657 if (expect_false (!times_valid))
658 coro_times_update ();
184 659
185 av_push ((AV *)*he, (SV *)CvPADLIST (cv)); 660 coro_times_sub (c);
186} 661 }
187 662
663 if (expect_false (c->on_enter))
664 {
665 int i;
666
667 for (i = 0; i <= AvFILLp (c->on_enter); ++i)
668 on_enterleave_call (aTHX_ AvARRAY (c->on_enter)[i]);
669 }
670
671 SWAP_SVS (c);
672}
673
188static void 674static void
189save_state(pTHX_ Coro__State c) 675save_perl (pTHX_ Coro__State c)
190{ 676{
677 SWAP_SVS (c);
678
679 if (expect_false (c->on_leave))
680 {
681 int i;
682
683 for (i = AvFILLp (c->on_leave); i >= 0; --i)
684 on_enterleave_call (aTHX_ AvARRAY (c->on_leave)[i]);
685 }
686
687 times_valid = 0;
688
689 if (expect_false (enable_times))
690 {
691 coro_times_update (); times_valid = 1;
692 coro_times_add (c);
693 }
694
695 c->except = CORO_THROW;
696 c->slf_frame = slf_frame;
697
191 { 698 {
192 dSP; 699 dSP;
193 I32 cxix = cxstack_ix; 700 I32 cxix = cxstack_ix;
701 PERL_CONTEXT *ccstk = cxstack;
194 PERL_SI *top_si = PL_curstackinfo; 702 PERL_SI *top_si = PL_curstackinfo;
195 PERL_CONTEXT *ccstk = cxstack;
196 703
197 /* 704 /*
198 * the worst thing you can imagine happens first - we have to save 705 * the worst thing you can imagine happens first - we have to save
199 * (and reinitialize) all cv's in the whole callchain :( 706 * (and reinitialize) all cv's in the whole callchain :(
200 */ 707 */
201 708
202 PUSHs (Nullsv); 709 XPUSHs (Nullsv);
203 /* this loop was inspired by pp_caller */ 710 /* this loop was inspired by pp_caller */
204 for (;;) 711 for (;;)
205 { 712 {
206 while (cxix >= 0) 713 while (expect_true (cxix >= 0))
207 { 714 {
208 PERL_CONTEXT *cx = &ccstk[cxix--]; 715 PERL_CONTEXT *cx = &ccstk[cxix--];
209 716
210 if (CxTYPE(cx) == CXt_SUB) 717 if (expect_true (CxTYPE (cx) == CXt_SUB) || expect_false (CxTYPE (cx) == CXt_FORMAT))
211 { 718 {
212 CV *cv = cx->blk_sub.cv; 719 CV *cv = cx->blk_sub.cv;
720
213 if (CvDEPTH(cv)) 721 if (expect_true (CvDEPTH (cv)))
214 { 722 {
215#ifdef USE_THREADS
216 XPUSHs ((SV *)CvOWNER(cv));
217#endif
218 EXTEND (SP, 3);
219 PUSHs ((SV *)CvDEPTH(cv));
220 PUSHs ((SV *)CvPADLIST(cv)); 723 PUSHs ((SV *)CvPADLIST (cv));
724 PUSHs (INT2PTR (SV *, (IV)CvDEPTH (cv)));
221 PUSHs ((SV *)cv); 725 PUSHs ((SV *)cv);
222 726
223 get_padlist (cv);
224
225 CvDEPTH(cv) = 0; 727 CvDEPTH (cv) = 0;
226#ifdef USE_THREADS 728 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 } 729 }
233 } 730 }
234 else if (CxTYPE(cx) == CXt_FORMAT) 731 }
732
733 if (expect_true (top_si->si_type == PERLSI_MAIN))
734 break;
735
736 top_si = top_si->si_prev;
737 ccstk = top_si->si_cxstack;
738 cxix = top_si->si_cxix;
739 }
740
741 PUTBACK;
742 }
743
744 /* allocate some space on the context stack for our purposes */
745 /* we manually unroll here, as usually 2 slots is enough */
746 if (SLOT_COUNT >= 1) CXINC;
747 if (SLOT_COUNT >= 2) CXINC;
748 if (SLOT_COUNT >= 3) CXINC;
749 {
750 unsigned int i;
751 for (i = 3; i < SLOT_COUNT; ++i)
752 CXINC;
753 }
754 cxstack_ix -= SLOT_COUNT; /* undo allocation */
755
756 c->mainstack = PL_mainstack;
757
758 {
759 perl_slots *slot = c->slot = (perl_slots *)(cxstack + cxstack_ix + 1);
760
761 slot->defav = GvAV (PL_defgv);
762 slot->defsv = DEFSV;
763 slot->errsv = ERRSV;
764 slot->irsgv = GvSV (irsgv);
765 slot->hinthv = GvHV (PL_hintgv);
766
767 #define VAR(name,type) slot->name = PL_ ## name;
768 # include "state.h"
769 #undef VAR
770 }
771}
772
773/*
774 * allocate various perl stacks. This is almost an exact copy
775 * of perl.c:init_stacks, except that it uses less memory
776 * on the (sometimes correct) assumption that coroutines do
777 * not usually need a lot of stackspace.
778 */
779#if CORO_PREFER_PERL_FUNCTIONS
780# define coro_init_stacks(thx) init_stacks ()
781#else
782static void
783coro_init_stacks (pTHX)
784{
785 PL_curstackinfo = new_stackinfo(32, 8);
786 PL_curstackinfo->si_type = PERLSI_MAIN;
787 PL_curstack = PL_curstackinfo->si_stack;
788 PL_mainstack = PL_curstack; /* remember in case we switch stacks */
789
790 PL_stack_base = AvARRAY(PL_curstack);
791 PL_stack_sp = PL_stack_base;
792 PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
793
794 New(50,PL_tmps_stack,32,SV*);
795 PL_tmps_floor = -1;
796 PL_tmps_ix = -1;
797 PL_tmps_max = 32;
798
799 New(54,PL_markstack,16,I32);
800 PL_markstack_ptr = PL_markstack;
801 PL_markstack_max = PL_markstack + 16;
802
803#ifdef SET_MARK_OFFSET
804 SET_MARK_OFFSET;
805#endif
806
807 New(54,PL_scopestack,8,I32);
808 PL_scopestack_ix = 0;
809 PL_scopestack_max = 8;
810
811 New(54,PL_savestack,24,ANY);
812 PL_savestack_ix = 0;
813 PL_savestack_max = 24;
814
815#if !PERL_VERSION_ATLEAST (5,10,0)
816 New(54,PL_retstack,4,OP*);
817 PL_retstack_ix = 0;
818 PL_retstack_max = 4;
819#endif
820}
821#endif
822
823/*
824 * destroy the stacks, the callchain etc...
825 */
826static void
827coro_destruct_stacks (pTHX)
828{
829 while (PL_curstackinfo->si_next)
830 PL_curstackinfo = PL_curstackinfo->si_next;
831
832 while (PL_curstackinfo)
833 {
834 PERL_SI *p = PL_curstackinfo->si_prev;
835
836 if (!IN_DESTRUCT)
837 SvREFCNT_dec (PL_curstackinfo->si_stack);
838
839 Safefree (PL_curstackinfo->si_cxstack);
840 Safefree (PL_curstackinfo);
841 PL_curstackinfo = p;
842 }
843
844 Safefree (PL_tmps_stack);
845 Safefree (PL_markstack);
846 Safefree (PL_scopestack);
847 Safefree (PL_savestack);
848#if !PERL_VERSION_ATLEAST (5,10,0)
849 Safefree (PL_retstack);
850#endif
851}
852
853#define CORO_RSS \
854 rss += sizeof (SYM (curstackinfo)); \
855 rss += (SYM (curstackinfo->si_cxmax) + 1) * sizeof (PERL_CONTEXT); \
856 rss += sizeof (SV) + sizeof (struct xpvav) + (1 + AvMAX (SYM (curstack))) * sizeof (SV *); \
857 rss += SYM (tmps_max) * sizeof (SV *); \
858 rss += (SYM (markstack_max) - SYM (markstack_ptr)) * sizeof (I32); \
859 rss += SYM (scopestack_max) * sizeof (I32); \
860 rss += SYM (savestack_max) * sizeof (ANY);
861
862static size_t
863coro_rss (pTHX_ struct coro *coro)
864{
865 size_t rss = sizeof (*coro);
866
867 if (coro->mainstack)
868 {
869 if (coro->flags & CF_RUNNING)
870 {
871 #define SYM(sym) PL_ ## sym
872 CORO_RSS;
873 #undef SYM
874 }
875 else
876 {
877 #define SYM(sym) coro->slot->sym
878 CORO_RSS;
879 #undef SYM
880 }
881 }
882
883 return rss;
884}
885
886/** coroutine stack handling ************************************************/
887
888static int (*orig_sigelem_get) (pTHX_ SV *sv, MAGIC *mg);
889static int (*orig_sigelem_set) (pTHX_ SV *sv, MAGIC *mg);
890static int (*orig_sigelem_clr) (pTHX_ SV *sv, MAGIC *mg);
891
892/* apparently < 5.8.8 */
893#ifndef MgPV_nolen_const
894#define MgPV_nolen_const(mg) (((((int)(mg)->mg_len)) == HEf_SVKEY) ? \
895 SvPV_nolen((SV*)((mg)->mg_ptr)) : \
896 (const char*)(mg)->mg_ptr)
897#endif
898
899/*
900 * This overrides the default magic get method of %SIG elements.
901 * The original one doesn't provide for reading back of PL_diehook/PL_warnhook
902 * and instead of trying to save and restore the hash elements, we just provide
903 * readback here.
904 */
905static int
906coro_sigelem_get (pTHX_ SV *sv, MAGIC *mg)
907{
908 const char *s = MgPV_nolen_const (mg);
909
910 if (*s == '_')
911 {
912 SV **svp = 0;
913
914 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
915 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
916
917 if (svp)
918 {
919 sv_setsv (sv, *svp ? *svp : &PL_sv_undef);
920 return 0;
921 }
922 }
923
924 return orig_sigelem_get ? orig_sigelem_get (aTHX_ sv, mg) : 0;
925}
926
927static int
928coro_sigelem_clr (pTHX_ SV *sv, MAGIC *mg)
929{
930 const char *s = MgPV_nolen_const (mg);
931
932 if (*s == '_')
933 {
934 SV **svp = 0;
935
936 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
937 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
938
939 if (svp)
940 {
941 SV *old = *svp;
942 *svp = 0;
943 SvREFCNT_dec (old);
944 return 0;
945 }
946 }
947
948 return orig_sigelem_clr ? orig_sigelem_clr (aTHX_ sv, mg) : 0;
949}
950
951static int
952coro_sigelem_set (pTHX_ SV *sv, MAGIC *mg)
953{
954 const char *s = MgPV_nolen_const (mg);
955
956 if (*s == '_')
957 {
958 SV **svp = 0;
959
960 if (strEQ (s, "__DIE__" )) svp = &PL_diehook;
961 if (strEQ (s, "__WARN__")) svp = &PL_warnhook;
962
963 if (svp)
964 {
965 SV *old = *svp;
966 *svp = SvOK (sv) ? newSVsv (sv) : 0;
967 SvREFCNT_dec (old);
968 return 0;
969 }
970 }
971
972 return orig_sigelem_set ? orig_sigelem_set (aTHX_ sv, mg) : 0;
973}
974
975static void
976prepare_nop (pTHX_ struct coro_transfer_args *ta)
977{
978 /* kind of mega-hacky, but works */
979 ta->next = ta->prev = (struct coro *)ta;
980}
981
982static int
983slf_check_nop (pTHX_ struct CoroSLF *frame)
984{
985 return 0;
986}
987
988static int
989slf_check_repeat (pTHX_ struct CoroSLF *frame)
990{
991 return 1;
992}
993
994static UNOP init_perl_op;
995
996static void NOINLINE /* noinline to keep it out of the transfer fast path */
997init_perl (pTHX_ struct coro *coro)
998{
999 /*
1000 * emulate part of the perl startup here.
1001 */
1002 coro_init_stacks (aTHX);
1003
1004 PL_runops = RUNOPS_DEFAULT;
1005 PL_curcop = &PL_compiling;
1006 PL_in_eval = EVAL_NULL;
1007 PL_comppad = 0;
1008 PL_comppad_name = 0;
1009 PL_comppad_name_fill = 0;
1010 PL_comppad_name_floor = 0;
1011 PL_curpm = 0;
1012 PL_curpad = 0;
1013 PL_localizing = 0;
1014 PL_dirty = 0;
1015 PL_restartop = 0;
1016#if PERL_VERSION_ATLEAST (5,10,0)
1017 PL_parser = 0;
1018#endif
1019 PL_hints = 0;
1020
1021 /* recreate the die/warn hooks */
1022 PL_diehook = 0; SvSetMagicSV (*hv_fetch (hv_sig, "__DIE__" , sizeof ("__DIE__" ) - 1, 1), rv_diehook );
1023 PL_warnhook = 0; SvSetMagicSV (*hv_fetch (hv_sig, "__WARN__", sizeof ("__WARN__") - 1, 1), rv_warnhook);
1024
1025 GvSV (PL_defgv) = newSV (0);
1026 GvAV (PL_defgv) = coro->args; coro->args = 0;
1027 GvSV (PL_errgv) = newSV (0);
1028 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0);
1029 GvHV (PL_hintgv) = 0;
1030 PL_rs = newSVsv (GvSV (irsgv));
1031 PL_defoutgv = (GV *)SvREFCNT_inc_NN (stdoutgv);
1032
1033 {
1034 dSP;
1035 UNOP myop;
1036
1037 Zero (&myop, 1, UNOP);
1038 myop.op_next = Nullop;
1039 myop.op_type = OP_ENTERSUB;
1040 myop.op_flags = OPf_WANT_VOID;
1041
1042 PUSHMARK (SP);
1043 PUSHs ((SV *)coro->startcv);
1044 PUTBACK;
1045 PL_op = (OP *)&myop;
1046 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
1047 }
1048
1049 /* this newly created coroutine might be run on an existing cctx which most
1050 * likely was suspended in pp_slf, so we have to emulate entering pp_slf here.
1051 */
1052 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */
1053 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */
1054
1055 /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */
1056 init_perl_op.op_next = PL_op;
1057 init_perl_op.op_type = OP_ENTERSUB;
1058 init_perl_op.op_ppaddr = pp_slf;
1059 /* no flags etc. required, as an init function won't be called */
1060
1061 PL_op = (OP *)&init_perl_op;
1062
1063 /* copy throw, in case it was set before init_perl */
1064 CORO_THROW = coro->except;
1065
1066 SWAP_SVS (coro);
1067
1068 if (expect_false (enable_times))
1069 {
1070 coro_times_update ();
1071 coro_times_sub (coro);
1072 }
1073}
1074
1075static void
1076coro_unwind_stacks (pTHX)
1077{
1078 if (!IN_DESTRUCT)
1079 {
1080 /* restore all saved variables and stuff */
1081 LEAVE_SCOPE (0);
1082 assert (PL_tmps_floor == -1);
1083
1084 /* free all temporaries */
1085 FREETMPS;
1086 assert (PL_tmps_ix == -1);
1087
1088 /* unwind all extra stacks */
1089 POPSTACK_TO (PL_mainstack);
1090
1091 /* unwind main stack */
1092 dounwind (-1);
1093 }
1094}
1095
1096static void
1097destroy_perl (pTHX_ struct coro *coro)
1098{
1099 SV *svf [9];
1100
1101 {
1102 struct coro *current = SvSTATE_current;
1103
1104 assert (("FATAL: tried to destroy currently running coroutine", coro->mainstack != PL_mainstack));
1105
1106 save_perl (aTHX_ current);
1107 load_perl (aTHX_ coro);
1108
1109 coro_unwind_stacks (aTHX);
1110 coro_destruct_stacks (aTHX);
1111
1112 /* restore swapped sv's */
1113 SWAP_SVS (coro);
1114
1115 // now save some sv's to be free'd later
1116 svf [0] = GvSV (PL_defgv);
1117 svf [1] = (SV *)GvAV (PL_defgv);
1118 svf [2] = GvSV (PL_errgv);
1119 svf [3] = (SV *)PL_defoutgv;
1120 svf [4] = PL_rs;
1121 svf [5] = GvSV (irsgv);
1122 svf [6] = (SV *)GvHV (PL_hintgv);
1123 svf [7] = PL_diehook;
1124 svf [8] = PL_warnhook;
1125 assert (9 == sizeof (svf) / sizeof (*svf));
1126
1127 load_perl (aTHX_ current);
1128 }
1129
1130 {
1131 unsigned int i;
1132
1133 for (i = 0; i < sizeof (svf) / sizeof (*svf); ++i)
1134 SvREFCNT_dec (svf [i]);
1135
1136 SvREFCNT_dec (coro->saved_deffh);
1137 SvREFCNT_dec (coro->rouse_cb);
1138 SvREFCNT_dec (coro->invoke_cb);
1139 SvREFCNT_dec (coro->invoke_av);
1140 }
1141}
1142
1143INLINE void
1144free_coro_mortal (pTHX)
1145{
1146 if (expect_true (coro_mortal))
1147 {
1148 SvREFCNT_dec (coro_mortal);
1149 coro_mortal = 0;
1150 }
1151}
1152
1153static int
1154runops_trace (pTHX)
1155{
1156 COP *oldcop = 0;
1157 int oldcxix = -2;
1158
1159 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX)))
1160 {
1161 PERL_ASYNC_CHECK ();
1162
1163 if (cctx_current->flags & CC_TRACE_ALL)
1164 {
1165 if (PL_op->op_type == OP_LEAVESUB && cctx_current->flags & CC_TRACE_SUB)
1166 {
1167 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
1168 SV **bot, **top;
1169 AV *av = newAV (); /* return values */
1170 SV **cb;
1171 dSP;
1172
1173 GV *gv = CvGV (cx->blk_sub.cv);
1174 SV *fullname = sv_2mortal (newSV (0));
1175 if (isGV (gv))
1176 gv_efullname3 (fullname, gv, 0);
1177
1178 bot = PL_stack_base + cx->blk_oldsp + 1;
1179 top = cx->blk_gimme == G_ARRAY ? SP + 1
1180 : cx->blk_gimme == G_SCALAR ? bot + 1
1181 : bot;
1182
1183 av_extend (av, top - bot);
1184 while (bot < top)
1185 av_push (av, SvREFCNT_inc_NN (*bot++));
1186
1187 PL_runops = RUNOPS_DEFAULT;
1188 ENTER;
1189 SAVETMPS;
1190 EXTEND (SP, 3);
1191 PUSHMARK (SP);
1192 PUSHs (&PL_sv_no);
1193 PUSHs (fullname);
1194 PUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
1195 PUTBACK;
1196 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
1197 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1198 SPAGAIN;
1199 FREETMPS;
1200 LEAVE;
1201 PL_runops = runops_trace;
1202 }
1203
1204 if (oldcop != PL_curcop)
1205 {
1206 oldcop = PL_curcop;
1207
1208 if (PL_curcop != &PL_compiling)
1209 {
1210 SV **cb;
1211
1212 if (oldcxix != cxstack_ix && cctx_current->flags & CC_TRACE_SUB)
1213 {
1214 PERL_CONTEXT *cx = &cxstack[cxstack_ix];
1215
1216 if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix)
1217 {
1218 dSP;
1219 GV *gv = CvGV (cx->blk_sub.cv);
1220 SV *fullname = sv_2mortal (newSV (0));
1221
1222 if (isGV (gv))
1223 gv_efullname3 (fullname, gv, 0);
1224
1225 PL_runops = RUNOPS_DEFAULT;
1226 ENTER;
1227 SAVETMPS;
1228 EXTEND (SP, 3);
1229 PUSHMARK (SP);
1230 PUSHs (&PL_sv_yes);
1231 PUSHs (fullname);
1232 PUSHs (CxHASARGS (cx) ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef);
1233 PUTBACK;
1234 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
1235 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1236 SPAGAIN;
1237 FREETMPS;
1238 LEAVE;
1239 PL_runops = runops_trace;
1240 }
1241
1242 oldcxix = cxstack_ix;
1243 }
1244
1245 if (cctx_current->flags & CC_TRACE_LINE)
1246 {
1247 dSP;
1248
1249 PL_runops = RUNOPS_DEFAULT;
1250 ENTER;
1251 SAVETMPS;
1252 EXTEND (SP, 3);
1253 PL_runops = RUNOPS_DEFAULT;
1254 PUSHMARK (SP);
1255 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0)));
1256 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop))));
1257 PUTBACK;
1258 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0);
1259 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1260 SPAGAIN;
1261 FREETMPS;
1262 LEAVE;
1263 PL_runops = runops_trace;
1264 }
1265 }
1266 }
1267 }
1268 }
1269
1270 TAINT_NOT;
1271 return 0;
1272}
1273
1274static struct CoroSLF cctx_ssl_frame;
1275
1276static void
1277slf_prepare_set_stacklevel (pTHX_ struct coro_transfer_args *ta)
1278{
1279 ta->prev = 0;
1280}
1281
1282static int
1283slf_check_set_stacklevel (pTHX_ struct CoroSLF *frame)
1284{
1285 *frame = cctx_ssl_frame;
1286
1287 return frame->check (aTHX_ frame); /* execute the restored frame - there must be one */
1288}
1289
1290/* initialises PL_top_env and injects a pseudo-slf-call to set the stacklevel */
1291static void NOINLINE
1292cctx_prepare (pTHX)
1293{
1294 PL_top_env = &PL_start_env;
1295
1296 if (cctx_current->flags & CC_TRACE)
1297 PL_runops = runops_trace;
1298
1299 /* we already must be executing an SLF op, there is no other valid way
1300 * that can lead to creation of a new cctx */
1301 assert (("FATAL: can't prepare slf-less cctx in Coro module (please report)",
1302 slf_frame.prepare && PL_op->op_ppaddr == pp_slf));
1303
1304 /* we must emulate leaving pp_slf, which is done inside slf_check_set_stacklevel */
1305 cctx_ssl_frame = slf_frame;
1306
1307 slf_frame.prepare = slf_prepare_set_stacklevel;
1308 slf_frame.check = slf_check_set_stacklevel;
1309}
1310
1311/* the tail of transfer: execute stuff we can only do after a transfer */
1312INLINE void
1313transfer_tail (pTHX)
1314{
1315 free_coro_mortal (aTHX);
1316}
1317
1318/*
1319 * this is a _very_ stripped down perl interpreter ;)
1320 */
1321static void
1322cctx_run (void *arg)
1323{
1324#ifdef USE_ITHREADS
1325# if CORO_PTHREAD
1326 PERL_SET_CONTEXT (coro_thx);
1327# endif
1328#endif
1329 {
1330 dTHX;
1331
1332 /* normally we would need to skip the entersub here */
1333 /* not doing so will re-execute it, which is exactly what we want */
1334 /* PL_nop = PL_nop->op_next */
1335
1336 /* inject a fake subroutine call to cctx_init */
1337 cctx_prepare (aTHX);
1338
1339 /* cctx_run is the alternative tail of transfer() */
1340 transfer_tail (aTHX);
1341
1342 /* somebody or something will hit me for both perl_run and PL_restartop */
1343 PL_restartop = PL_op;
1344 perl_run (PL_curinterp);
1345 /*
1346 * Unfortunately, there is no way to get at the return values of the
1347 * coro body here, as perl_run destroys these. Likewise, we cannot catch
1348 * runtime errors here, as this is just a random interpreter, not a thread.
1349 */
1350
1351 /*
1352 * If perl-run returns we assume exit() was being called or the coro
1353 * fell off the end, which seems to be the only valid (non-bug)
1354 * reason for perl_run to return. We try to exit by jumping to the
1355 * bootstrap-time "top" top_env, as we cannot restore the "main"
1356 * coroutine as Coro has no such concept.
1357 * This actually isn't valid with the pthread backend, but OSes requiring
1358 * that backend are too broken to do it in a standards-compliant way.
1359 */
1360 PL_top_env = main_top_env;
1361 JMPENV_JUMP (2); /* I do not feel well about the hardcoded 2 at all */
1362 }
1363}
1364
1365static coro_cctx *
1366cctx_new ()
1367{
1368 coro_cctx *cctx;
1369
1370 ++cctx_count;
1371 New (0, cctx, 1, coro_cctx);
1372
1373 cctx->gen = cctx_gen;
1374 cctx->flags = 0;
1375 cctx->idle_sp = 0; /* can be accessed by transfer between cctx_run and set_stacklevel, on throw */
1376
1377 return cctx;
1378}
1379
1380/* create a new cctx only suitable as source */
1381static coro_cctx *
1382cctx_new_empty ()
1383{
1384 coro_cctx *cctx = cctx_new ();
1385
1386 cctx->sptr = 0;
1387 coro_create (&cctx->cctx, 0, 0, 0, 0);
1388
1389 return cctx;
1390}
1391
1392/* create a new cctx suitable as destination/running a perl interpreter */
1393static coro_cctx *
1394cctx_new_run ()
1395{
1396 coro_cctx *cctx = cctx_new ();
1397 void *stack_start;
1398 size_t stack_size;
1399
1400#if HAVE_MMAP
1401 cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
1402 /* mmap supposedly does allocate-on-write for us */
1403 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
1404
1405 if (cctx->sptr != (void *)-1)
1406 {
1407 #if CORO_STACKGUARD
1408 mprotect (cctx->sptr, CORO_STACKGUARD * PAGESIZE, PROT_NONE);
1409 #endif
1410 stack_start = (char *)cctx->sptr + CORO_STACKGUARD * PAGESIZE;
1411 stack_size = cctx->ssize - CORO_STACKGUARD * PAGESIZE;
1412 cctx->flags |= CC_MAPPED;
1413 }
1414 else
1415#endif
1416 {
1417 cctx->ssize = cctx_stacksize * (long)sizeof (long);
1418 New (0, cctx->sptr, cctx_stacksize, long);
1419
1420 if (!cctx->sptr)
1421 {
1422 perror ("FATAL: unable to allocate stack for coroutine, exiting.");
1423 _exit (EXIT_FAILURE);
1424 }
1425
1426 stack_start = cctx->sptr;
1427 stack_size = cctx->ssize;
1428 }
1429
1430 #if CORO_USE_VALGRIND
1431 cctx->valgrind_id = VALGRIND_STACK_REGISTER ((char *)stack_start, (char *)stack_start + stack_size);
1432 #endif
1433
1434 coro_create (&cctx->cctx, cctx_run, (void *)cctx, stack_start, stack_size);
1435
1436 return cctx;
1437}
1438
1439static void
1440cctx_destroy (coro_cctx *cctx)
1441{
1442 if (!cctx)
1443 return;
1444
1445 assert (("FATAL: tried to destroy current cctx", cctx != cctx_current));//D temporary?
1446
1447 --cctx_count;
1448 coro_destroy (&cctx->cctx);
1449
1450 /* coro_transfer creates new, empty cctx's */
1451 if (cctx->sptr)
1452 {
1453 #if CORO_USE_VALGRIND
1454 VALGRIND_STACK_DEREGISTER (cctx->valgrind_id);
1455 #endif
1456
1457#if HAVE_MMAP
1458 if (cctx->flags & CC_MAPPED)
1459 munmap (cctx->sptr, cctx->ssize);
1460 else
1461#endif
1462 Safefree (cctx->sptr);
1463 }
1464
1465 Safefree (cctx);
1466}
1467
1468/* wether this cctx should be destructed */
1469#define CCTX_EXPIRED(cctx) ((cctx)->gen != cctx_gen || ((cctx)->flags & CC_NOREUSE))
1470
1471static coro_cctx *
1472cctx_get (pTHX)
1473{
1474 while (expect_true (cctx_first))
1475 {
1476 coro_cctx *cctx = cctx_first;
1477 cctx_first = cctx->next;
1478 --cctx_idle;
1479
1480 if (expect_true (!CCTX_EXPIRED (cctx)))
1481 return cctx;
1482
1483 cctx_destroy (cctx);
1484 }
1485
1486 return cctx_new_run ();
1487}
1488
1489static void
1490cctx_put (coro_cctx *cctx)
1491{
1492 assert (("FATAL: cctx_put called on non-initialised cctx in Coro (please report)", cctx->sptr));
1493
1494 /* free another cctx if overlimit */
1495 if (expect_false (cctx_idle >= cctx_max_idle))
1496 {
1497 coro_cctx *first = cctx_first;
1498 cctx_first = first->next;
1499 --cctx_idle;
1500
1501 cctx_destroy (first);
1502 }
1503
1504 ++cctx_idle;
1505 cctx->next = cctx_first;
1506 cctx_first = cctx;
1507}
1508
1509/** coroutine switching *****************************************************/
1510
1511static void
1512transfer_check (pTHX_ struct coro *prev, struct coro *next)
1513{
1514 /* TODO: throwing up here is considered harmful */
1515
1516 if (expect_true (prev != next))
1517 {
1518 if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW))))
1519 croak ("Coro::State::transfer called with a blocked prev Coro::State, but can only transfer from running or new states,");
1520
1521 if (expect_false (next->flags & (CF_RUNNING | CF_DESTROYED | CF_SUSPENDED)))
1522 croak ("Coro::State::transfer called with running, destroyed or suspended next Coro::State, but can only transfer to inactive states,");
1523
1524#if !PERL_VERSION_ATLEAST (5,10,0)
1525 if (expect_false (PL_lex_state != LEX_NOTPARSING))
1526 croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version,");
1527#endif
1528 }
1529}
1530
1531/* always use the TRANSFER macro */
1532static void NOINLINE /* noinline so we have a fixed stackframe */
1533transfer (pTHX_ struct coro *prev, struct coro *next, int force_cctx)
1534{
1535 dSTACKLEVEL;
1536
1537 /* sometimes transfer is only called to set idle_sp */
1538 if (expect_false (!prev))
1539 {
1540 cctx_current->idle_sp = STACKLEVEL;
1541 assert (cctx_current->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */
1542 }
1543 else if (expect_true (prev != next))
1544 {
1545 coro_cctx *cctx_prev;
1546
1547 if (expect_false (prev->flags & CF_NEW))
1548 {
1549 /* create a new empty/source context */
1550 prev->flags &= ~CF_NEW;
1551 prev->flags |= CF_RUNNING;
1552 }
1553
1554 prev->flags &= ~CF_RUNNING;
1555 next->flags |= CF_RUNNING;
1556
1557 /* first get rid of the old state */
1558 save_perl (aTHX_ prev);
1559
1560 if (expect_false (next->flags & CF_NEW))
1561 {
1562 /* need to start coroutine */
1563 next->flags &= ~CF_NEW;
1564 /* setup coroutine call */
1565 init_perl (aTHX_ next);
1566 }
1567 else
1568 load_perl (aTHX_ next);
1569
1570 /* possibly untie and reuse the cctx */
1571 if (expect_true (
1572 cctx_current->idle_sp == STACKLEVEL
1573 && !(cctx_current->flags & CC_TRACE)
1574 && !force_cctx
1575 ))
1576 {
1577 /* I assume that stacklevel is a stronger indicator than PL_top_env changes */
1578 assert (("FATAL: current top_env must equal previous top_env in Coro (please report)", PL_top_env == cctx_current->idle_te));
1579
1580 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get. */
1581 /* without this the next cctx_get might destroy the running cctx while still in use */
1582 if (expect_false (CCTX_EXPIRED (cctx_current)))
1583 if (expect_true (!next->cctx))
1584 next->cctx = cctx_get (aTHX);
1585
1586 cctx_put (cctx_current);
1587 }
1588 else
1589 prev->cctx = cctx_current;
1590
1591 ++next->usecount;
1592
1593 cctx_prev = cctx_current;
1594 cctx_current = expect_false (next->cctx) ? next->cctx : cctx_get (aTHX);
1595
1596 next->cctx = 0;
1597
1598 if (expect_false (cctx_prev != cctx_current))
1599 {
1600 cctx_prev->top_env = PL_top_env;
1601 PL_top_env = cctx_current->top_env;
1602 coro_transfer (&cctx_prev->cctx, &cctx_current->cctx);
1603 }
1604
1605 transfer_tail (aTHX);
1606 }
1607}
1608
1609#define TRANSFER(ta, force_cctx) transfer (aTHX_ (ta).prev, (ta).next, (force_cctx))
1610#define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next)
1611
1612/** high level stuff ********************************************************/
1613
1614static int
1615coro_state_destroy (pTHX_ struct coro *coro)
1616{
1617 if (coro->flags & CF_DESTROYED)
1618 return 0;
1619
1620 if (coro->on_destroy && !PL_dirty)
1621 coro->on_destroy (aTHX_ coro);
1622
1623 coro->flags |= CF_DESTROYED;
1624
1625 if (coro->flags & CF_READY)
1626 {
1627 /* reduce nready, as destroying a ready coro effectively unreadies it */
1628 /* alternative: look through all ready queues and remove the coro */
1629 --coro_nready;
1630 }
1631 else
1632 coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */
1633
1634 if (coro->mainstack
1635 && coro->mainstack != main_mainstack
1636 && coro->slot
1637 && !PL_dirty)
1638 destroy_perl (aTHX_ coro);
1639
1640 if (coro->next) coro->next->prev = coro->prev;
1641 if (coro->prev) coro->prev->next = coro->next;
1642 if (coro == coro_first) coro_first = coro->next;
1643
1644 cctx_destroy (coro->cctx);
1645 SvREFCNT_dec (coro->startcv);
1646 SvREFCNT_dec (coro->args);
1647 SvREFCNT_dec (coro->swap_sv);
1648 SvREFCNT_dec (CORO_THROW);
1649
1650 return 1;
1651}
1652
1653static int
1654coro_state_free (pTHX_ SV *sv, MAGIC *mg)
1655{
1656 struct coro *coro = (struct coro *)mg->mg_ptr;
1657 mg->mg_ptr = 0;
1658
1659 coro->hv = 0;
1660
1661 if (--coro->refcnt < 0)
1662 {
1663 coro_state_destroy (aTHX_ coro);
1664 Safefree (coro);
1665 }
1666
1667 return 0;
1668}
1669
1670static int
1671coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
1672{
1673 struct coro *coro = (struct coro *)mg->mg_ptr;
1674
1675 ++coro->refcnt;
1676
1677 return 0;
1678}
1679
1680static MGVTBL coro_state_vtbl = {
1681 0, 0, 0, 0,
1682 coro_state_free,
1683 0,
1684#ifdef MGf_DUP
1685 coro_state_dup,
1686#else
1687# define MGf_DUP 0
1688#endif
1689};
1690
1691static void
1692prepare_transfer (pTHX_ struct coro_transfer_args *ta, SV *prev_sv, SV *next_sv)
1693{
1694 ta->prev = SvSTATE (prev_sv);
1695 ta->next = SvSTATE (next_sv);
1696 TRANSFER_CHECK (*ta);
1697}
1698
1699static void
1700api_transfer (pTHX_ SV *prev_sv, SV *next_sv)
1701{
1702 struct coro_transfer_args ta;
1703
1704 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
1705 TRANSFER (ta, 1);
1706}
1707
1708/** Coro ********************************************************************/
1709
1710INLINE void
1711coro_enq (pTHX_ struct coro *coro)
1712{
1713 struct coro **ready = coro_ready [coro->prio - CORO_PRIO_MIN];
1714
1715 SvREFCNT_inc_NN (coro->hv);
1716
1717 coro->next_ready = 0;
1718 *(ready [0] ? &ready [1]->next_ready : &ready [0]) = coro;
1719 ready [1] = coro;
1720}
1721
1722INLINE struct coro *
1723coro_deq (pTHX)
1724{
1725 int prio;
1726
1727 for (prio = CORO_PRIO_MAX - CORO_PRIO_MIN + 1; --prio >= 0; )
1728 {
1729 struct coro **ready = coro_ready [prio];
1730
1731 if (ready [0])
1732 {
1733 struct coro *coro = ready [0];
1734 ready [0] = coro->next_ready;
1735 return coro;
1736 }
1737 }
1738
1739 return 0;
1740}
1741
1742static void
1743invoke_sv_ready_hook_helper (void)
1744{
1745 dTHX;
1746 dSP;
1747
1748 ENTER;
1749 SAVETMPS;
1750
1751 PUSHMARK (SP);
1752 PUTBACK;
1753 call_sv (coro_readyhook, G_VOID | G_DISCARD);
1754
1755 FREETMPS;
1756 LEAVE;
1757}
1758
1759static int
1760api_ready (pTHX_ SV *coro_sv)
1761{
1762 struct coro *coro = SvSTATE (coro_sv);
1763
1764 if (coro->flags & CF_READY)
1765 return 0;
1766
1767 coro->flags |= CF_READY;
1768
1769 coro_enq (aTHX_ coro);
1770
1771 if (!coro_nready++)
1772 if (coroapi.readyhook)
1773 coroapi.readyhook ();
1774
1775 return 1;
1776}
1777
1778static int
1779api_is_ready (pTHX_ SV *coro_sv)
1780{
1781 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1782}
1783
1784/* expects to own a reference to next->hv */
1785INLINE void
1786prepare_schedule_to (pTHX_ struct coro_transfer_args *ta, struct coro *next)
1787{
1788 SV *prev_sv = SvRV (coro_current);
1789
1790 ta->prev = SvSTATE_hv (prev_sv);
1791 ta->next = next;
1792
1793 TRANSFER_CHECK (*ta);
1794
1795 SvRV_set (coro_current, (SV *)next->hv);
1796
1797 free_coro_mortal (aTHX);
1798 coro_mortal = prev_sv;
1799}
1800
1801static void
1802prepare_schedule (pTHX_ struct coro_transfer_args *ta)
1803{
1804 for (;;)
1805 {
1806 struct coro *next = coro_deq (aTHX);
1807
1808 if (expect_true (next))
1809 {
1810 /* cannot transfer to destroyed coros, skip and look for next */
1811 if (expect_false (next->flags & (CF_DESTROYED | CF_SUSPENDED)))
1812 SvREFCNT_dec (next->hv); /* coro_nready has already been taken care of by destroy */
1813 else
1814 {
1815 next->flags &= ~CF_READY;
1816 --coro_nready;
1817
1818 prepare_schedule_to (aTHX_ ta, next);
1819 break;
1820 }
1821 }
1822 else
1823 {
1824 /* nothing to schedule: call the idle handler */
1825 if (SvROK (sv_idle)
1826 && SvOBJECT (SvRV (sv_idle)))
1827 {
1828 ++coro_nready; /* hack so that api_ready doesn't invoke ready hook */
1829 api_ready (aTHX_ SvRV (sv_idle));
1830 --coro_nready;
1831 }
1832 else
1833 {
1834 /* TODO: deprecated, remove, cannot work reliably *//*D*/
1835 dSP;
1836
1837 ENTER;
1838 SAVETMPS;
1839
1840 PUSHMARK (SP);
1841 PUTBACK;
1842 call_sv (sv_idle, G_VOID | G_DISCARD);
1843
1844 FREETMPS;
1845 LEAVE;
1846 }
1847 }
1848 }
1849}
1850
1851INLINE void
1852prepare_cede (pTHX_ struct coro_transfer_args *ta)
1853{
1854 api_ready (aTHX_ coro_current);
1855 prepare_schedule (aTHX_ ta);
1856}
1857
1858INLINE void
1859prepare_cede_notself (pTHX_ struct coro_transfer_args *ta)
1860{
1861 SV *prev = SvRV (coro_current);
1862
1863 if (coro_nready)
1864 {
1865 prepare_schedule (aTHX_ ta);
1866 api_ready (aTHX_ prev);
1867 }
1868 else
1869 prepare_nop (aTHX_ ta);
1870}
1871
1872static void
1873api_schedule (pTHX)
1874{
1875 struct coro_transfer_args ta;
1876
1877 prepare_schedule (aTHX_ &ta);
1878 TRANSFER (ta, 1);
1879}
1880
1881static void
1882api_schedule_to (pTHX_ SV *coro_sv)
1883{
1884 struct coro_transfer_args ta;
1885 struct coro *next = SvSTATE (coro_sv);
1886
1887 SvREFCNT_inc_NN (coro_sv);
1888 prepare_schedule_to (aTHX_ &ta, next);
1889}
1890
1891static int
1892api_cede (pTHX)
1893{
1894 struct coro_transfer_args ta;
1895
1896 prepare_cede (aTHX_ &ta);
1897
1898 if (expect_true (ta.prev != ta.next))
1899 {
1900 TRANSFER (ta, 1);
1901 return 1;
1902 }
1903 else
1904 return 0;
1905}
1906
1907static int
1908api_cede_notself (pTHX)
1909{
1910 if (coro_nready)
1911 {
1912 struct coro_transfer_args ta;
1913
1914 prepare_cede_notself (aTHX_ &ta);
1915 TRANSFER (ta, 1);
1916 return 1;
1917 }
1918 else
1919 return 0;
1920}
1921
1922static void
1923api_trace (pTHX_ SV *coro_sv, int flags)
1924{
1925 struct coro *coro = SvSTATE (coro_sv);
1926
1927 if (coro->flags & CF_RUNNING)
1928 croak ("cannot enable tracing on a running coroutine, caught");
1929
1930 if (flags & CC_TRACE)
1931 {
1932 if (!coro->cctx)
1933 coro->cctx = cctx_new_run ();
1934 else if (!(coro->cctx->flags & CC_TRACE))
1935 croak ("cannot enable tracing on coroutine with custom stack, caught");
1936
1937 coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL));
1938 }
1939 else if (coro->cctx && coro->cctx->flags & CC_TRACE)
1940 {
1941 coro->cctx->flags &= ~(CC_TRACE | CC_TRACE_ALL);
1942
1943 if (coro->flags & CF_RUNNING)
1944 PL_runops = RUNOPS_DEFAULT;
1945 else
1946 coro->slot->runops = RUNOPS_DEFAULT;
1947 }
1948}
1949
1950static void
1951coro_call_on_destroy (pTHX_ struct coro *coro)
1952{
1953 SV **on_destroyp = hv_fetch (coro->hv, "_on_destroy", sizeof ("_on_destroy") - 1, 0);
1954 SV **statusp = hv_fetch (coro->hv, "_status", sizeof ("_status") - 1, 0);
1955
1956 if (on_destroyp)
1957 {
1958 AV *on_destroy = (AV *)SvRV (*on_destroyp);
1959
1960 while (AvFILLp (on_destroy) >= 0)
1961 {
1962 dSP; /* don't disturb outer sp */
1963 SV *cb = av_pop (on_destroy);
1964
1965 PUSHMARK (SP);
1966
1967 if (statusp)
1968 {
1969 int i;
1970 AV *status = (AV *)SvRV (*statusp);
1971 EXTEND (SP, AvFILLp (status) + 1);
1972
1973 for (i = 0; i <= AvFILLp (status); ++i)
1974 PUSHs (AvARRAY (status)[i]);
1975 }
1976
1977 PUTBACK;
1978 call_sv (sv_2mortal (cb), G_VOID | G_DISCARD);
1979 }
1980 }
1981}
1982
1983static void
1984slf_init_terminate (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
1985{
1986 int i;
1987 HV *hv = (HV *)SvRV (coro_current);
1988 AV *av = newAV ();
1989
1990 /* items are actually not so common, so optimise for this case */
1991 if (items)
1992 {
1993 av_extend (av, items - 1);
1994
1995 for (i = 0; i < items; ++i)
1996 av_push (av, SvREFCNT_inc_NN (arg [i]));
1997 }
1998
1999 hv_store (hv, "_status", sizeof ("_status") - 1, newRV_noinc ((SV *)av), 0);
2000
2001 av_push (av_destroy, (SV *)newRV_inc ((SV *)hv)); /* RVinc for perl */
2002 api_ready (aTHX_ sv_manager);
2003
2004 frame->prepare = prepare_schedule;
2005 frame->check = slf_check_repeat;
2006
2007 /* as a minor optimisation, we could unwind all stacks here */
2008 /* but that puts extra pressure on pp_slf, and is not worth much */
2009 /*coro_unwind_stacks (aTHX);*/
2010}
2011
2012/*****************************************************************************/
2013/* async pool handler */
2014
2015static int
2016slf_check_pool_handler (pTHX_ struct CoroSLF *frame)
2017{
2018 HV *hv = (HV *)SvRV (coro_current);
2019 struct coro *coro = (struct coro *)frame->data;
2020
2021 if (!coro->invoke_cb)
2022 return 1; /* loop till we have invoke */
2023 else
2024 {
2025 hv_store (hv, "desc", sizeof ("desc") - 1,
2026 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
2027
2028 coro->saved_deffh = SvREFCNT_inc_NN ((SV *)PL_defoutgv);
2029
2030 {
2031 dSP;
2032 XPUSHs (sv_2mortal (coro->invoke_cb)); coro->invoke_cb = 0;
2033 PUTBACK;
2034 }
2035
2036 SvREFCNT_dec (GvAV (PL_defgv));
2037 GvAV (PL_defgv) = coro->invoke_av;
2038 coro->invoke_av = 0;
2039
2040 return 0;
2041 }
2042}
2043
2044static void
2045slf_init_pool_handler (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2046{
2047 HV *hv = (HV *)SvRV (coro_current);
2048 struct coro *coro = SvSTATE_hv ((SV *)hv);
2049
2050 if (expect_true (coro->saved_deffh))
2051 {
2052 /* subsequent iteration */
2053 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
2054 coro->saved_deffh = 0;
2055
2056 if (coro_rss (aTHX_ coro) > SvUV (sv_pool_rss)
2057 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
2058 {
2059 coro->invoke_cb = SvREFCNT_inc_NN ((SV *)cv_coro_terminate);
2060 coro->invoke_av = newAV ();
2061
2062 frame->prepare = prepare_nop;
2063 }
2064 else
2065 {
2066 av_clear (GvAV (PL_defgv));
2067 hv_store (hv, "desc", sizeof ("desc") - 1, SvREFCNT_inc_NN (sv_async_pool_idle), 0);
2068
2069 coro->prio = 0;
2070
2071 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
2072 api_trace (aTHX_ coro_current, 0);
2073
2074 frame->prepare = prepare_schedule;
2075 av_push (av_async_pool, SvREFCNT_inc (hv));
2076 }
2077 }
2078 else
2079 {
2080 /* first iteration, simply fall through */
2081 frame->prepare = prepare_nop;
2082 }
2083
2084 frame->check = slf_check_pool_handler;
2085 frame->data = (void *)coro;
2086}
2087
2088/*****************************************************************************/
2089/* rouse callback */
2090
2091#define CORO_MAGIC_type_rouse PERL_MAGIC_ext
2092
2093static void
2094coro_rouse_callback (pTHX_ CV *cv)
2095{
2096 dXSARGS;
2097 SV *data = (SV *)S_GENSUB_ARG;
2098
2099 if (SvTYPE (SvRV (data)) != SVt_PVAV)
2100 {
2101 /* first call, set args */
2102 SV *coro = SvRV (data);
2103 AV *av = newAV ();
2104
2105 SvRV_set (data, (SV *)av);
2106
2107 /* better take a full copy of the arguments */
2108 while (items--)
2109 av_store (av, items, newSVsv (ST (items)));
2110
2111 api_ready (aTHX_ coro);
2112 SvREFCNT_dec (coro);
2113 }
2114
2115 XSRETURN_EMPTY;
2116}
2117
2118static int
2119slf_check_rouse_wait (pTHX_ struct CoroSLF *frame)
2120{
2121 SV *data = (SV *)frame->data;
2122
2123 if (CORO_THROW)
2124 return 0;
2125
2126 if (SvTYPE (SvRV (data)) != SVt_PVAV)
2127 return 1;
2128
2129 /* now push all results on the stack */
2130 {
2131 dSP;
2132 AV *av = (AV *)SvRV (data);
2133 int i;
2134
2135 EXTEND (SP, AvFILLp (av) + 1);
2136 for (i = 0; i <= AvFILLp (av); ++i)
2137 PUSHs (sv_2mortal (AvARRAY (av)[i]));
2138
2139 /* we have stolen the elements, so set length to zero and free */
2140 AvFILLp (av) = -1;
2141 av_undef (av);
2142
2143 PUTBACK;
2144 }
2145
2146 return 0;
2147}
2148
2149static void
2150slf_init_rouse_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2151{
2152 SV *cb;
2153
2154 if (items)
2155 cb = arg [0];
2156 else
2157 {
2158 struct coro *coro = SvSTATE_current;
2159
2160 if (!coro->rouse_cb)
2161 croak ("Coro::rouse_wait called without rouse callback, and no default rouse callback found either,");
2162
2163 cb = sv_2mortal (coro->rouse_cb);
2164 coro->rouse_cb = 0;
2165 }
2166
2167 if (!SvROK (cb)
2168 || SvTYPE (SvRV (cb)) != SVt_PVCV
2169 || CvXSUB ((CV *)SvRV (cb)) != coro_rouse_callback)
2170 croak ("Coro::rouse_wait called with illegal callback argument,");
2171
2172 {
2173 CV *cv = (CV *)SvRV (cb); /* for S_GENSUB_ARG */
2174 SV *data = (SV *)S_GENSUB_ARG;
2175
2176 frame->data = (void *)data;
2177 frame->prepare = SvTYPE (SvRV (data)) == SVt_PVAV ? prepare_nop : prepare_schedule;
2178 frame->check = slf_check_rouse_wait;
2179 }
2180}
2181
2182static SV *
2183coro_new_rouse_cb (pTHX)
2184{
2185 HV *hv = (HV *)SvRV (coro_current);
2186 struct coro *coro = SvSTATE_hv (hv);
2187 SV *data = newRV_inc ((SV *)hv);
2188 SV *cb = s_gensub (aTHX_ coro_rouse_callback, (void *)data);
2189
2190 sv_magicext (SvRV (cb), data, CORO_MAGIC_type_rouse, 0, 0, 0);
2191 SvREFCNT_dec (data); /* magicext increases the refcount */
2192
2193 SvREFCNT_dec (coro->rouse_cb);
2194 coro->rouse_cb = SvREFCNT_inc_NN (cb);
2195
2196 return cb;
2197}
2198
2199/*****************************************************************************/
2200/* schedule-like-function opcode (SLF) */
2201
2202static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */
2203static const CV *slf_cv;
2204static SV **slf_argv;
2205static int slf_argc, slf_arga; /* count, allocated */
2206static I32 slf_ax; /* top of stack, for restore */
2207
2208/* this restores the stack in the case we patched the entersub, to */
2209/* recreate the stack frame as perl will on following calls */
2210/* since entersub cleared the stack */
2211static OP *
2212pp_restore (pTHX)
2213{
2214 int i;
2215 SV **SP = PL_stack_base + slf_ax;
2216
2217 PUSHMARK (SP);
2218
2219 EXTEND (SP, slf_argc + 1);
2220
2221 for (i = 0; i < slf_argc; ++i)
2222 PUSHs (sv_2mortal (slf_argv [i]));
2223
2224 PUSHs ((SV *)CvGV (slf_cv));
2225
2226 RETURNOP (slf_restore.op_first);
2227}
2228
2229static void
2230slf_prepare_transfer (pTHX_ struct coro_transfer_args *ta)
2231{
2232 SV **arg = (SV **)slf_frame.data;
2233
2234 prepare_transfer (aTHX_ ta, arg [0], arg [1]);
2235}
2236
2237static void
2238slf_init_transfer (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2239{
2240 if (items != 2)
2241 croak ("Coro::State::transfer (prev, next) expects two arguments, not %d,", items);
2242
2243 frame->prepare = slf_prepare_transfer;
2244 frame->check = slf_check_nop;
2245 frame->data = (void *)arg; /* let's hope it will stay valid */
2246}
2247
2248static void
2249slf_init_schedule (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2250{
2251 frame->prepare = prepare_schedule;
2252 frame->check = slf_check_nop;
2253}
2254
2255static void
2256slf_prepare_schedule_to (pTHX_ struct coro_transfer_args *ta)
2257{
2258 struct coro *next = (struct coro *)slf_frame.data;
2259
2260 SvREFCNT_inc_NN (next->hv);
2261 prepare_schedule_to (aTHX_ ta, next);
2262}
2263
2264static void
2265slf_init_schedule_to (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2266{
2267 if (!items)
2268 croak ("Coro::schedule_to expects a coroutine argument, caught");
2269
2270 frame->data = (void *)SvSTATE (arg [0]);
2271 frame->prepare = slf_prepare_schedule_to;
2272 frame->check = slf_check_nop;
2273}
2274
2275static void
2276slf_init_cede_to (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2277{
2278 api_ready (aTHX_ SvRV (coro_current));
2279
2280 slf_init_schedule_to (aTHX_ frame, cv, arg, items);
2281}
2282
2283static void
2284slf_init_cede (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2285{
2286 frame->prepare = prepare_cede;
2287 frame->check = slf_check_nop;
2288}
2289
2290static void
2291slf_init_cede_notself (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2292{
2293 frame->prepare = prepare_cede_notself;
2294 frame->check = slf_check_nop;
2295}
2296
2297/*
2298 * these not obviously related functions are all rolled into one
2299 * function to increase chances that they all will call transfer with the same
2300 * stack offset
2301 * SLF stands for "schedule-like-function".
2302 */
2303static OP *
2304pp_slf (pTHX)
2305{
2306 I32 checkmark; /* mark SP to see how many elements check has pushed */
2307
2308 /* set up the slf frame, unless it has already been set-up */
2309 /* the latter happens when a new coro has been started */
2310 /* or when a new cctx was attached to an existing coroutine */
2311 if (expect_true (!slf_frame.prepare))
2312 {
2313 /* first iteration */
2314 dSP;
2315 SV **arg = PL_stack_base + TOPMARK + 1;
2316 int items = SP - arg; /* args without function object */
2317 SV *gv = *sp;
2318
2319 /* do a quick consistency check on the "function" object, and if it isn't */
2320 /* for us, divert to the real entersub */
2321 if (SvTYPE (gv) != SVt_PVGV
2322 || !GvCV (gv)
2323 || !(CvFLAGS (GvCV (gv)) & CVf_SLF))
2324 return PL_ppaddr[OP_ENTERSUB](aTHX);
2325
2326 if (!(PL_op->op_flags & OPf_STACKED))
2327 {
2328 /* ampersand-form of call, use @_ instead of stack */
2329 AV *av = GvAV (PL_defgv);
2330 arg = AvARRAY (av);
2331 items = AvFILLp (av) + 1;
2332 }
2333
2334 /* now call the init function, which needs to set up slf_frame */
2335 ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr)
2336 (aTHX_ &slf_frame, GvCV (gv), arg, items);
2337
2338 /* pop args */
2339 SP = PL_stack_base + POPMARK;
2340
2341 PUTBACK;
2342 }
2343
2344 /* now that we have a slf_frame, interpret it! */
2345 /* we use a callback system not to make the code needlessly */
2346 /* complicated, but so we can run multiple perl coros from one cctx */
2347
2348 do
2349 {
2350 struct coro_transfer_args ta;
2351
2352 slf_frame.prepare (aTHX_ &ta);
2353 TRANSFER (ta, 0);
2354
2355 checkmark = PL_stack_sp - PL_stack_base;
2356 }
2357 while (slf_frame.check (aTHX_ &slf_frame));
2358
2359 slf_frame.prepare = 0; /* invalidate the frame, we are done processing it */
2360
2361 /* exception handling */
2362 if (expect_false (CORO_THROW))
2363 {
2364 SV *exception = sv_2mortal (CORO_THROW);
2365
2366 CORO_THROW = 0;
2367 sv_setsv (ERRSV, exception);
2368 croak (0);
2369 }
2370
2371 /* return value handling - mostly like entersub */
2372 /* make sure we put something on the stack in scalar context */
2373 if (GIMME_V == G_SCALAR)
2374 {
2375 dSP;
2376 SV **bot = PL_stack_base + checkmark;
2377
2378 if (sp == bot) /* too few, push undef */
2379 bot [1] = &PL_sv_undef;
2380 else if (sp != bot + 1) /* too many, take last one */
2381 bot [1] = *sp;
2382
2383 SP = bot + 1;
2384
2385 PUTBACK;
2386 }
2387
2388 return NORMAL;
2389}
2390
2391static void
2392api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, I32 ax)
2393{
2394 int i;
2395 SV **arg = PL_stack_base + ax;
2396 int items = PL_stack_sp - arg + 1;
2397
2398 assert (("FATAL: SLF call with illegal CV value", !CvANON (cv)));
2399
2400 if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB]
2401 && PL_op->op_ppaddr != pp_slf)
2402 croak ("FATAL: Coro SLF calls can only be made normally, not via goto or any other means, caught");
2403
2404 CvFLAGS (cv) |= CVf_SLF;
2405 CvXSUBANY (cv).any_ptr = (void *)init_cb;
2406 slf_cv = cv;
2407
2408 /* we patch the op, and then re-run the whole call */
2409 /* we have to put the same argument on the stack for this to work */
2410 /* and this will be done by pp_restore */
2411 slf_restore.op_next = (OP *)&slf_restore;
2412 slf_restore.op_type = OP_CUSTOM;
2413 slf_restore.op_ppaddr = pp_restore;
2414 slf_restore.op_first = PL_op;
2415
2416 slf_ax = ax - 1; /* undo the ax++ inside dAXMARK */
2417
2418 if (PL_op->op_flags & OPf_STACKED)
2419 {
2420 if (items > slf_arga)
2421 {
2422 slf_arga = items;
2423 free (slf_argv);
2424 slf_argv = malloc (slf_arga * sizeof (SV *));
2425 }
2426
2427 slf_argc = items;
2428
2429 for (i = 0; i < items; ++i)
2430 slf_argv [i] = SvREFCNT_inc (arg [i]);
2431 }
2432 else
2433 slf_argc = 0;
2434
2435 PL_op->op_ppaddr = pp_slf;
2436 /*PL_op->op_type = OP_CUSTOM; /* we do behave like entersub still */
2437
2438 PL_op = (OP *)&slf_restore;
2439}
2440
2441/*****************************************************************************/
2442/* dynamic wind */
2443
2444static void
2445on_enterleave_call (pTHX_ SV *cb)
2446{
2447 dSP;
2448
2449 PUSHSTACK;
2450
2451 PUSHMARK (SP);
2452 PUTBACK;
2453 call_sv (cb, G_VOID | G_DISCARD);
2454 SPAGAIN;
2455
2456 POPSTACK;
2457}
2458
2459static SV *
2460coro_avp_pop_and_free (pTHX_ AV **avp)
2461{
2462 AV *av = *avp;
2463 SV *res = av_pop (av);
2464
2465 if (AvFILLp (av) < 0)
2466 {
2467 *avp = 0;
2468 SvREFCNT_dec (av);
2469 }
2470
2471 return res;
2472}
2473
2474static void
2475coro_pop_on_enter (pTHX_ void *coro)
2476{
2477 SV *cb = coro_avp_pop_and_free (aTHX_ &((struct coro *)coro)->on_enter);
2478 SvREFCNT_dec (cb);
2479}
2480
2481static void
2482coro_pop_on_leave (pTHX_ void *coro)
2483{
2484 SV *cb = coro_avp_pop_and_free (aTHX_ &((struct coro *)coro)->on_leave);
2485 on_enterleave_call (aTHX_ sv_2mortal (cb));
2486}
2487
2488/*****************************************************************************/
2489/* PerlIO::cede */
2490
2491typedef struct
2492{
2493 PerlIOBuf base;
2494 NV next, every;
2495} PerlIOCede;
2496
2497static IV
2498PerlIOCede_pushed (pTHX_ PerlIO *f, const char *mode, SV *arg, PerlIO_funcs *tab)
2499{
2500 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2501
2502 self->every = SvCUR (arg) ? SvNV (arg) : 0.01;
2503 self->next = nvtime () + self->every;
2504
2505 return PerlIOBuf_pushed (aTHX_ f, mode, Nullsv, tab);
2506}
2507
2508static SV *
2509PerlIOCede_getarg (pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
2510{
2511 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2512
2513 return newSVnv (self->every);
2514}
2515
2516static IV
2517PerlIOCede_flush (pTHX_ PerlIO *f)
2518{
2519 PerlIOCede *self = PerlIOSelf (f, PerlIOCede);
2520 double now = nvtime ();
2521
2522 if (now >= self->next)
2523 {
2524 api_cede (aTHX);
2525 self->next = now + self->every;
2526 }
2527
2528 return PerlIOBuf_flush (aTHX_ f);
2529}
2530
2531static PerlIO_funcs PerlIO_cede =
2532{
2533 sizeof(PerlIO_funcs),
2534 "cede",
2535 sizeof(PerlIOCede),
2536 PERLIO_K_DESTRUCT | PERLIO_K_RAW,
2537 PerlIOCede_pushed,
2538 PerlIOBuf_popped,
2539 PerlIOBuf_open,
2540 PerlIOBase_binmode,
2541 PerlIOCede_getarg,
2542 PerlIOBase_fileno,
2543 PerlIOBuf_dup,
2544 PerlIOBuf_read,
2545 PerlIOBuf_unread,
2546 PerlIOBuf_write,
2547 PerlIOBuf_seek,
2548 PerlIOBuf_tell,
2549 PerlIOBuf_close,
2550 PerlIOCede_flush,
2551 PerlIOBuf_fill,
2552 PerlIOBase_eof,
2553 PerlIOBase_error,
2554 PerlIOBase_clearerr,
2555 PerlIOBase_setlinebuf,
2556 PerlIOBuf_get_base,
2557 PerlIOBuf_bufsiz,
2558 PerlIOBuf_get_ptr,
2559 PerlIOBuf_get_cnt,
2560 PerlIOBuf_set_ptrcnt,
2561};
2562
2563/*****************************************************************************/
2564/* Coro::Semaphore & Coro::Signal */
2565
2566static SV *
2567coro_waitarray_new (pTHX_ int count)
2568{
2569 /* a waitarray=semaphore contains a counter IV in $sem->[0] and any waiters after that */
2570 AV *av = newAV ();
2571 SV **ary;
2572
2573 /* unfortunately, building manually saves memory */
2574 Newx (ary, 2, SV *);
2575 AvALLOC (av) = ary;
2576#if PERL_VERSION_ATLEAST (5,10,0)
2577 AvARRAY (av) = ary;
2578#else
2579 /* 5.8.8 needs this syntax instead of AvARRAY = ary, yet */
2580 /* -DDEBUGGING flags this as a bug, despite it perfectly working */
2581 SvPVX ((SV *)av) = (char *)ary;
2582#endif
2583 AvMAX (av) = 1;
2584 AvFILLp (av) = 0;
2585 ary [0] = newSViv (count);
2586
2587 return newRV_noinc ((SV *)av);
2588}
2589
2590/* semaphore */
2591
2592static void
2593coro_semaphore_adjust (pTHX_ AV *av, IV adjust)
2594{
2595 SV *count_sv = AvARRAY (av)[0];
2596 IV count = SvIVX (count_sv);
2597
2598 count += adjust;
2599 SvIVX (count_sv) = count;
2600
2601 /* now wake up as many waiters as are expected to lock */
2602 while (count > 0 && AvFILLp (av) > 0)
2603 {
2604 SV *cb;
2605
2606 /* swap first two elements so we can shift a waiter */
2607 AvARRAY (av)[0] = AvARRAY (av)[1];
2608 AvARRAY (av)[1] = count_sv;
2609 cb = av_shift (av);
2610
2611 if (SvOBJECT (cb))
2612 {
2613 api_ready (aTHX_ cb);
2614 --count;
2615 }
2616 else if (SvTYPE (cb) == SVt_PVCV)
2617 {
2618 dSP;
2619 PUSHMARK (SP);
2620 XPUSHs (sv_2mortal (newRV_inc ((SV *)av)));
2621 PUTBACK;
2622 call_sv (cb, G_VOID | G_DISCARD | G_EVAL | G_KEEPERR);
2623 }
2624
2625 SvREFCNT_dec (cb);
2626 }
2627}
2628
2629static void
2630coro_semaphore_on_destroy (pTHX_ struct coro *coro)
2631{
2632 /* call $sem->adjust (0) to possibly wake up some other waiters */
2633 coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0);
2634}
2635
2636static int
2637slf_check_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, int acquire)
2638{
2639 AV *av = (AV *)frame->data;
2640 SV *count_sv = AvARRAY (av)[0];
2641
2642 /* if we are about to throw, don't actually acquire the lock, just throw */
2643 if (CORO_THROW)
2644 return 0;
2645 else if (SvIVX (count_sv) > 0)
2646 {
2647 SvSTATE_current->on_destroy = 0;
2648
2649 if (acquire)
2650 SvIVX (count_sv) = SvIVX (count_sv) - 1;
2651 else
2652 coro_semaphore_adjust (aTHX_ av, 0);
2653
2654 return 0;
2655 }
2656 else
2657 {
2658 int i;
2659 /* if we were woken up but can't down, we look through the whole */
2660 /* waiters list and only add us if we aren't in there already */
2661 /* this avoids some degenerate memory usage cases */
2662
2663 for (i = 1; i <= AvFILLp (av); ++i)
2664 if (AvARRAY (av)[i] == SvRV (coro_current))
2665 return 1;
2666
2667 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2668 return 1;
2669 }
2670}
2671
2672static int
2673slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2674{
2675 return slf_check_semaphore_down_or_wait (aTHX_ frame, 1);
2676}
2677
2678static int
2679slf_check_semaphore_wait (pTHX_ struct CoroSLF *frame)
2680{
2681 return slf_check_semaphore_down_or_wait (aTHX_ frame, 0);
2682}
2683
2684static void
2685slf_init_semaphore_down_or_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2686{
2687 AV *av = (AV *)SvRV (arg [0]);
2688
2689 if (SvIVX (AvARRAY (av)[0]) > 0)
2690 {
2691 frame->data = (void *)av;
2692 frame->prepare = prepare_nop;
2693 }
2694 else
2695 {
2696 av_push (av, SvREFCNT_inc (SvRV (coro_current)));
2697
2698 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2699 frame->prepare = prepare_schedule;
2700
2701 /* to avoid race conditions when a woken-up coro gets terminated */
2702 /* we arrange for a temporary on_destroy that calls adjust (0) */
2703 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2704 }
2705}
2706
2707static void
2708slf_init_semaphore_down (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2709{
2710 slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items);
2711 frame->check = slf_check_semaphore_down;
2712}
2713
2714static void
2715slf_init_semaphore_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2716{
2717 if (items >= 2)
2718 {
2719 /* callback form */
2720 AV *av = (AV *)SvRV (arg [0]);
2721 SV *cb_cv = s_get_cv_croak (arg [1]);
2722
2723 av_push (av, SvREFCNT_inc_NN (cb_cv));
2724
2725 if (SvIVX (AvARRAY (av)[0]) > 0)
2726 coro_semaphore_adjust (aTHX_ av, 0);
2727
2728 frame->prepare = prepare_nop;
2729 frame->check = slf_check_nop;
2730 }
2731 else
2732 {
2733 slf_init_semaphore_down_or_wait (aTHX_ frame, cv, arg, items);
2734 frame->check = slf_check_semaphore_wait;
2735 }
2736}
2737
2738/* signal */
2739
2740static void
2741coro_signal_wake (pTHX_ AV *av, int count)
2742{
2743 SvIVX (AvARRAY (av)[0]) = 0;
2744
2745 /* now signal count waiters */
2746 while (count > 0 && AvFILLp (av) > 0)
2747 {
2748 SV *cb;
2749
2750 /* swap first two elements so we can shift a waiter */
2751 cb = AvARRAY (av)[0];
2752 AvARRAY (av)[0] = AvARRAY (av)[1];
2753 AvARRAY (av)[1] = cb;
2754
2755 cb = av_shift (av);
2756
2757 if (SvTYPE (cb) == SVt_PVCV)
2758 {
2759 dSP;
2760 PUSHMARK (SP);
2761 XPUSHs (sv_2mortal (newRV_inc ((SV *)av)));
2762 PUTBACK;
2763 call_sv (cb, G_VOID | G_DISCARD | G_EVAL | G_KEEPERR);
2764 }
2765 else
2766 {
2767 api_ready (aTHX_ cb);
2768 sv_setiv (cb, 0); /* signal waiter */
2769 }
2770
2771 SvREFCNT_dec (cb);
2772
2773 --count;
2774 }
2775}
2776
2777static int
2778slf_check_signal_wait (pTHX_ struct CoroSLF *frame)
2779{
2780 /* if we are about to throw, also stop waiting */
2781 return SvROK ((SV *)frame->data) && !CORO_THROW;
2782}
2783
2784static void
2785slf_init_signal_wait (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2786{
2787 AV *av = (AV *)SvRV (arg [0]);
2788
2789 if (items >= 2)
2790 {
2791 SV *cb_cv = s_get_cv_croak (arg [1]);
2792 av_push (av, SvREFCNT_inc_NN (cb_cv));
2793
2794 if (SvIVX (AvARRAY (av)[0]))
2795 coro_signal_wake (aTHX_ av, 1); /* ust be the only waiter */
2796
2797 frame->prepare = prepare_nop;
2798 frame->check = slf_check_nop;
2799 }
2800 else if (SvIVX (AvARRAY (av)[0]))
2801 {
2802 SvIVX (AvARRAY (av)[0]) = 0;
2803 frame->prepare = prepare_nop;
2804 frame->check = slf_check_nop;
2805 }
2806 else
2807 {
2808 SV *waiter = newSVsv (coro_current); /* owned by signal av */
2809
2810 av_push (av, waiter);
2811
2812 frame->data = (void *)sv_2mortal (SvREFCNT_inc_NN (waiter)); /* owned by process */
2813 frame->prepare = prepare_schedule;
2814 frame->check = slf_check_signal_wait;
2815 }
2816}
2817
2818/*****************************************************************************/
2819/* Coro::AIO */
2820
2821#define CORO_MAGIC_type_aio PERL_MAGIC_ext
2822
2823/* helper storage struct */
2824struct io_state
2825{
2826 int errorno;
2827 I32 laststype; /* U16 in 5.10.0 */
2828 int laststatval;
2829 Stat_t statcache;
2830};
2831
2832static void
2833coro_aio_callback (pTHX_ CV *cv)
2834{
2835 dXSARGS;
2836 AV *state = (AV *)S_GENSUB_ARG;
2837 SV *coro = av_pop (state);
2838 SV *data_sv = newSV (sizeof (struct io_state));
2839
2840 av_extend (state, items - 1);
2841
2842 sv_upgrade (data_sv, SVt_PV);
2843 SvCUR_set (data_sv, sizeof (struct io_state));
2844 SvPOK_only (data_sv);
2845
2846 {
2847 struct io_state *data = (struct io_state *)SvPVX (data_sv);
2848
2849 data->errorno = errno;
2850 data->laststype = PL_laststype;
2851 data->laststatval = PL_laststatval;
2852 data->statcache = PL_statcache;
2853 }
2854
2855 /* now build the result vector out of all the parameters and the data_sv */
2856 {
2857 int i;
2858
2859 for (i = 0; i < items; ++i)
2860 av_push (state, SvREFCNT_inc_NN (ST (i)));
2861 }
2862
2863 av_push (state, data_sv);
2864
2865 api_ready (aTHX_ coro);
2866 SvREFCNT_dec (coro);
2867 SvREFCNT_dec ((AV *)state);
2868}
2869
2870static int
2871slf_check_aio_req (pTHX_ struct CoroSLF *frame)
2872{
2873 AV *state = (AV *)frame->data;
2874
2875 /* if we are about to throw, return early */
2876 /* this does not cancel the aio request, but at least */
2877 /* it quickly returns */
2878 if (CORO_THROW)
2879 return 0;
2880
2881 /* one element that is an RV? repeat! */
2882 if (AvFILLp (state) == 0 && SvROK (AvARRAY (state)[0]))
2883 return 1;
2884
2885 /* restore status */
2886 {
2887 SV *data_sv = av_pop (state);
2888 struct io_state *data = (struct io_state *)SvPVX (data_sv);
2889
2890 errno = data->errorno;
2891 PL_laststype = data->laststype;
2892 PL_laststatval = data->laststatval;
2893 PL_statcache = data->statcache;
2894
2895 SvREFCNT_dec (data_sv);
2896 }
2897
2898 /* push result values */
2899 {
2900 dSP;
2901 int i;
2902
2903 EXTEND (SP, AvFILLp (state) + 1);
2904 for (i = 0; i <= AvFILLp (state); ++i)
2905 PUSHs (sv_2mortal (SvREFCNT_inc_NN (AvARRAY (state)[i])));
2906
2907 PUTBACK;
2908 }
2909
2910 return 0;
2911}
2912
2913static void
2914slf_init_aio_req (pTHX_ struct CoroSLF *frame, CV *cv, SV **arg, int items)
2915{
2916 AV *state = (AV *)sv_2mortal ((SV *)newAV ());
2917 SV *coro_hv = SvRV (coro_current);
2918 struct coro *coro = SvSTATE_hv (coro_hv);
2919
2920 /* put our coroutine id on the state arg */
2921 av_push (state, SvREFCNT_inc_NN (coro_hv));
2922
2923 /* first see whether we have a non-zero priority and set it as AIO prio */
2924 if (coro->prio)
2925 {
2926 dSP;
2927
2928 static SV *prio_cv;
2929 static SV *prio_sv;
2930
2931 if (expect_false (!prio_cv))
2932 {
2933 prio_cv = (SV *)get_cv ("IO::AIO::aioreq_pri", 0);
2934 prio_sv = newSViv (0);
2935 }
2936
2937 PUSHMARK (SP);
2938 sv_setiv (prio_sv, coro->prio);
2939 XPUSHs (prio_sv);
2940
2941 PUTBACK;
2942 call_sv (prio_cv, G_VOID | G_DISCARD);
2943 }
2944
2945 /* now call the original request */
2946 {
2947 dSP;
2948 CV *req = (CV *)CORO_MAGIC_NN ((SV *)cv, CORO_MAGIC_type_aio)->mg_obj;
2949 int i;
2950
2951 PUSHMARK (SP);
2952
2953 /* first push all args to the stack */
2954 EXTEND (SP, items + 1);
2955
2956 for (i = 0; i < items; ++i)
2957 PUSHs (arg [i]);
2958
2959 /* now push the callback closure */
2960 PUSHs (sv_2mortal (s_gensub (aTHX_ coro_aio_callback, (void *)SvREFCNT_inc_NN ((SV *)state))));
2961
2962 /* now call the AIO function - we assume our request is uncancelable */
2963 PUTBACK;
2964 call_sv ((SV *)req, G_VOID | G_DISCARD);
2965 }
2966
2967 /* now that the requets is going, we loop toll we have a result */
2968 frame->data = (void *)state;
2969 frame->prepare = prepare_schedule;
2970 frame->check = slf_check_aio_req;
2971}
2972
2973static void
2974coro_aio_req_xs (pTHX_ CV *cv)
2975{
2976 dXSARGS;
2977
2978 CORO_EXECUTE_SLF_XS (slf_init_aio_req);
2979
2980 XSRETURN_EMPTY;
2981}
2982
2983/*****************************************************************************/
2984
2985#if CORO_CLONE
2986# include "clone.c"
2987#endif
2988
2989/*****************************************************************************/
2990
2991static SV *
2992coro_new (pTHX_ HV *stash, SV **argv, int argc, int is_coro)
2993{
2994 SV *coro_sv;
2995 struct coro *coro;
2996 MAGIC *mg;
2997 HV *hv;
2998 SV *cb;
2999 int i;
3000
3001 if (argc > 0)
3002 {
3003 cb = s_get_cv_croak (argv [0]);
3004
3005 if (!is_coro)
3006 {
3007 if (CvISXSUB (cb))
3008 croak ("Coro::State doesn't support XS functions as coroutine start, caught");
3009
3010 if (!CvROOT (cb))
3011 croak ("Coro::State doesn't support autoloaded or undefined functions as coroutine start, caught");
3012 }
3013 }
3014
3015 Newz (0, coro, 1, struct coro);
3016 coro->args = newAV ();
3017 coro->flags = CF_NEW;
3018
3019 if (coro_first) coro_first->prev = coro;
3020 coro->next = coro_first;
3021 coro_first = coro;
3022
3023 coro->hv = hv = newHV ();
3024 mg = sv_magicext ((SV *)hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)coro, 0);
3025 mg->mg_flags |= MGf_DUP;
3026 coro_sv = sv_bless (newRV_noinc ((SV *)hv), stash);
3027
3028 if (argc > 0)
3029 {
3030 av_extend (coro->args, argc + is_coro - 1);
3031
3032 if (is_coro)
3033 {
3034 av_push (coro->args, SvREFCNT_inc_NN ((SV *)cb));
3035 cb = (SV *)cv_coro_run;
3036 }
3037
3038 coro->startcv = (CV *)SvREFCNT_inc_NN ((SV *)cb);
3039
3040 for (i = 1; i < argc; i++)
3041 av_push (coro->args, newSVsv (argv [i]));
3042 }
3043
3044 return coro_sv;
3045}
3046
3047MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_
3048
3049PROTOTYPES: DISABLE
3050
3051BOOT:
3052{
3053#ifdef USE_ITHREADS
3054# if CORO_PTHREAD
3055 coro_thx = PERL_GET_CONTEXT;
3056# endif
3057#endif
3058 BOOT_PAGESIZE;
3059
3060 cctx_current = cctx_new_empty ();
3061
3062 irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV);
3063 stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
3064
3065 orig_sigelem_get = PL_vtbl_sigelem.svt_get; PL_vtbl_sigelem.svt_get = coro_sigelem_get;
3066 orig_sigelem_set = PL_vtbl_sigelem.svt_set; PL_vtbl_sigelem.svt_set = coro_sigelem_set;
3067 orig_sigelem_clr = PL_vtbl_sigelem.svt_clear; PL_vtbl_sigelem.svt_clear = coro_sigelem_clr;
3068
3069 hv_sig = coro_get_hv (aTHX_ "SIG", TRUE);
3070 rv_diehook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::diehook" , 0, SVt_PVCV));
3071 rv_warnhook = newRV_inc ((SV *)gv_fetchpv ("Coro::State::warnhook", 0, SVt_PVCV));
3072
3073 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
3074
3075 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE));
3076 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB));
3077 newCONSTSUB (coro_state_stash, "CC_TRACE_LINE", newSViv (CC_TRACE_LINE));
3078 newCONSTSUB (coro_state_stash, "CC_TRACE_ALL" , newSViv (CC_TRACE_ALL));
3079
3080 main_mainstack = PL_mainstack;
3081 main_top_env = PL_top_env;
3082
3083 while (main_top_env->je_prev)
3084 main_top_env = main_top_env->je_prev;
3085
3086 {
3087 SV *slf = sv_2mortal (newSViv (PTR2IV (pp_slf)));
3088
3089 if (!PL_custom_op_names) PL_custom_op_names = newHV ();
3090 hv_store_ent (PL_custom_op_names, slf, newSVpv ("coro_slf", 0), 0);
3091
3092 if (!PL_custom_op_descs) PL_custom_op_descs = newHV ();
3093 hv_store_ent (PL_custom_op_descs, slf, newSVpv ("coro schedule like function", 0), 0);
3094 }
3095
3096 coroapi.ver = CORO_API_VERSION;
3097 coroapi.rev = CORO_API_REVISION;
3098
3099 coroapi.transfer = api_transfer;
3100
3101 coroapi.sv_state = SvSTATE_;
3102 coroapi.execute_slf = api_execute_slf;
3103 coroapi.prepare_nop = prepare_nop;
3104 coroapi.prepare_schedule = prepare_schedule;
3105 coroapi.prepare_cede = prepare_cede;
3106 coroapi.prepare_cede_notself = prepare_cede_notself;
3107
3108 {
3109 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
3110
3111 if (!svp) croak ("Time::HiRes is required");
3112 if (!SvIOK (*svp)) croak ("Time::NVtime isn't a function pointer");
3113
3114 nvtime = INT2PTR (double (*)(), SvIV (*svp));
3115
3116 svp = hv_fetch (PL_modglobal, "Time::U2time", 12, 0);
3117 u2time = INT2PTR (void (*)(pTHX_ UV ret[2]), SvIV (*svp));
3118 }
3119
3120 assert (("PRIO_NORMAL must be 0", !CORO_PRIO_NORMAL));
3121}
3122
3123SV *
3124new (SV *klass, ...)
3125 ALIAS:
3126 Coro::new = 1
3127 CODE:
3128 RETVAL = coro_new (aTHX_ ix ? coro_stash : coro_state_stash, &ST (1), items - 1, ix);
3129 OUTPUT:
3130 RETVAL
3131
3132void
3133transfer (...)
3134 PROTOTYPE: $$
3135 CODE:
3136 CORO_EXECUTE_SLF_XS (slf_init_transfer);
3137
3138bool
3139_destroy (SV *coro_sv)
3140 CODE:
3141 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
3142 OUTPUT:
3143 RETVAL
3144
3145void
3146_exit (int code)
3147 PROTOTYPE: $
3148 CODE:
3149 _exit (code);
3150
3151SV *
3152clone (Coro::State coro)
3153 CODE:
3154{
3155#if CORO_CLONE
3156 struct coro *ncoro = coro_clone (aTHX_ coro);
3157 MAGIC *mg;
3158 /* TODO: too much duplication */
3159 ncoro->hv = newHV ();
3160 mg = sv_magicext ((SV *)ncoro->hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)ncoro, 0);
3161 mg->mg_flags |= MGf_DUP;
3162 RETVAL = sv_bless (newRV_noinc ((SV *)ncoro->hv), SvSTASH (coro->hv));
3163#else
3164 croak ("Coro::State->clone has not been configured into this installation of Coro, realised");
3165#endif
3166}
3167 OUTPUT:
3168 RETVAL
3169
3170int
3171cctx_stacksize (int new_stacksize = 0)
3172 PROTOTYPE: ;$
3173 CODE:
3174 RETVAL = cctx_stacksize;
3175 if (new_stacksize)
3176 {
3177 cctx_stacksize = new_stacksize;
3178 ++cctx_gen;
3179 }
3180 OUTPUT:
3181 RETVAL
3182
3183int
3184cctx_max_idle (int max_idle = 0)
3185 PROTOTYPE: ;$
3186 CODE:
3187 RETVAL = cctx_max_idle;
3188 if (max_idle > 1)
3189 cctx_max_idle = max_idle;
3190 OUTPUT:
3191 RETVAL
3192
3193int
3194cctx_count ()
3195 PROTOTYPE:
3196 CODE:
3197 RETVAL = cctx_count;
3198 OUTPUT:
3199 RETVAL
3200
3201int
3202cctx_idle ()
3203 PROTOTYPE:
3204 CODE:
3205 RETVAL = cctx_idle;
3206 OUTPUT:
3207 RETVAL
3208
3209void
3210list ()
3211 PROTOTYPE:
3212 PPCODE:
3213{
3214 struct coro *coro;
3215 for (coro = coro_first; coro; coro = coro->next)
3216 if (coro->hv)
3217 XPUSHs (sv_2mortal (newRV_inc ((SV *)coro->hv)));
3218}
3219
3220void
3221call (Coro::State coro, SV *coderef)
3222 ALIAS:
3223 eval = 1
3224 CODE:
3225{
3226 if (coro->mainstack && ((coro->flags & CF_RUNNING) || coro->slot))
3227 {
3228 struct coro *current = SvSTATE_current;
3229
3230 if (current != coro)
235 { 3231 {
236 /* I never used formats, so how should I know how these are implemented? */ 3232 PUTBACK;
237 /* my bold guess is as a simple, plain sub... */ 3233 save_perl (aTHX_ current);
238 croak ("CXt_FORMAT not yet handled. Don't switch coroutines from within formats"); 3234 load_perl (aTHX_ coro);
3235 SPAGAIN;
3236 }
3237
3238 PUSHSTACK;
3239
3240 PUSHMARK (SP);
3241 PUTBACK;
3242
3243 if (ix)
3244 eval_sv (coderef, 0);
3245 else
3246 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
3247
3248 POPSTACK;
3249 SPAGAIN;
3250
3251 if (current != coro)
3252 {
3253 PUTBACK;
3254 save_perl (aTHX_ coro);
3255 load_perl (aTHX_ current);
3256 SPAGAIN;
239 } 3257 }
240 } 3258 }
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} 3259}
281 3260
282#define LOAD(state) do { load_state(aTHX_ state); SPAGAIN; } while (0) 3261SV *
283#define SAVE(state) do { PUTBACK; save_state(aTHX_ state); } while (0) 3262is_ready (Coro::State coro)
284
285static void
286load_state(pTHX_ Coro__State c)
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
316 {
317 dSP;
318 CV *cv;
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 }
334
335 PUTBACK;
336 }
337}
338
339/* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */
340STATIC void
341destroy_stacks(pTHX)
342{
343 /* die does this while calling POPSTACK, but I just don't see why. */
344 /* OTOH, die does not have a memleak, but we do... */
345 dounwind(-1);
346
347 /* is this ugly, I ask? */
348 while (PL_scopestack_ix)
349 LEAVE;
350
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
387
388PROTOTYPES: ENABLE
389
390BOOT:
391 if (!padlist_cache)
392 padlist_cache = newHV ();
393
394Coro::State
395_newprocess(args)
396 SV * args
397 PROTOTYPE: $ 3263 PROTOTYPE: $
3264 ALIAS:
3265 is_ready = CF_READY
3266 is_running = CF_RUNNING
3267 is_new = CF_NEW
3268 is_destroyed = CF_DESTROYED
3269 is_suspended = CF_SUSPENDED
3270 CODE:
3271 RETVAL = boolSV (coro->flags & ix);
3272 OUTPUT:
3273 RETVAL
3274
3275void
3276throw (Coro::State self, SV *throw = &PL_sv_undef)
3277 PROTOTYPE: $;$
398 CODE: 3278 CODE:
399 Coro__State coro; 3279{
3280 struct coro *current = SvSTATE_current;
3281 SV **throwp = self == current ? &CORO_THROW : &self->except;
3282 SvREFCNT_dec (*throwp);
3283 SvGETMAGIC (throw);
3284 *throwp = SvOK (throw) ? newSVsv (throw) : 0;
3285}
400 3286
401 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) 3287void
402 croak ("Coro::State::newprocess expects an arrayref"); 3288api_trace (SV *coro, int flags = CC_TRACE | CC_TRACE_SUB)
3289 PROTOTYPE: $;$
3290 C_ARGS: aTHX_ coro, flags
3291
3292SV *
3293has_cctx (Coro::State coro)
3294 PROTOTYPE: $
3295 CODE:
3296 /* maybe manage the running flag differently */
3297 RETVAL = boolSV (!!coro->cctx || (coro->flags & CF_RUNNING));
3298 OUTPUT:
3299 RETVAL
3300
3301int
3302is_traced (Coro::State coro)
3303 PROTOTYPE: $
3304 CODE:
3305 RETVAL = (coro->cctx ? coro->cctx->flags : 0) & CC_TRACE_ALL;
3306 OUTPUT:
3307 RETVAL
3308
3309UV
3310rss (Coro::State coro)
3311 PROTOTYPE: $
3312 ALIAS:
3313 usecount = 1
3314 CODE:
3315 switch (ix)
3316 {
3317 case 0: RETVAL = coro_rss (aTHX_ coro); break;
3318 case 1: RETVAL = coro->usecount; break;
403 3319 }
404 New (0, coro, 1, struct coro); 3320 OUTPUT:
405
406 coro->mainstack = 0; /* actual work is done inside transfer */
407 coro->args = (AV *)SvREFCNT_inc (SvRV (args));
408
409 RETVAL = coro; 3321 RETVAL
3322
3323void
3324force_cctx ()
3325 PROTOTYPE:
3326 CODE:
3327 cctx_current->idle_sp = 0;
3328
3329void
3330swap_defsv (Coro::State self)
3331 PROTOTYPE: $
3332 ALIAS:
3333 swap_defav = 1
3334 CODE:
3335 if (!self->slot)
3336 croak ("cannot swap state with coroutine that has no saved state,");
3337 else
3338 {
3339 SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv);
3340 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
3341
3342 SV *tmp = *src; *src = *dst; *dst = tmp;
3343 }
3344
3345void
3346cancel (Coro::State self)
3347 CODE:
3348 coro_state_destroy (aTHX_ self);
3349 coro_call_on_destroy (aTHX_ self); /* actually only for Coro objects */
3350
3351
3352SV *
3353enable_times (int enabled = enable_times)
3354 CODE:
3355{
3356 RETVAL = boolSV (enable_times);
3357
3358 if (enabled != enable_times)
3359 {
3360 enable_times = enabled;
3361
3362 coro_times_update ();
3363 (enabled ? coro_times_sub : coro_times_add)(SvSTATE (coro_current));
3364 }
3365}
410 OUTPUT: 3366 OUTPUT:
411 RETVAL 3367 RETVAL
412 3368
413void 3369void
414transfer(prev,next) 3370times (Coro::State self)
415 Coro::State_or_hashref prev 3371 PPCODE:
416 Coro::State_or_hashref next 3372{
3373 struct coro *current = SvSTATE (coro_current);
3374
3375 if (expect_false (current == self))
3376 {
3377 coro_times_update ();
3378 coro_times_add (SvSTATE (coro_current));
3379 }
3380
3381 EXTEND (SP, 2);
3382 PUSHs (sv_2mortal (newSVnv (self->t_real [0] + self->t_real [1] * 1e-9)));
3383 PUSHs (sv_2mortal (newSVnv (self->t_cpu [0] + self->t_cpu [1] * 1e-9)));
3384
3385 if (expect_false (current == self))
3386 coro_times_sub (SvSTATE (coro_current));
3387}
3388
3389void
3390swap_sv (Coro::State coro, SV *sv, SV *swapsv)
3391 CODE:
3392{
3393 struct coro *current = SvSTATE_current;
3394
3395 if (current == coro)
3396 SWAP_SVS (current);
3397
3398 if (!coro->swap_sv)
3399 coro->swap_sv = newAV ();
3400
3401 av_push (coro->swap_sv, SvREFCNT_inc_NN (SvRV (sv )));
3402 av_push (coro->swap_sv, SvREFCNT_inc_NN (SvRV (swapsv)));
3403
3404 if (current == coro)
3405 SWAP_SVS (current);
3406}
3407
3408
3409MODULE = Coro::State PACKAGE = Coro
3410
3411BOOT:
3412{
3413 sv_pool_rss = coro_get_sv (aTHX_ "Coro::POOL_RSS" , TRUE);
3414 sv_pool_size = coro_get_sv (aTHX_ "Coro::POOL_SIZE" , TRUE);
3415 cv_coro_run = get_cv ( "Coro::_coro_run" , GV_ADD);
3416 cv_coro_terminate = get_cv ( "Coro::terminate" , GV_ADD);
3417 coro_current = coro_get_sv (aTHX_ "Coro::current" , FALSE); SvREADONLY_on (coro_current);
3418 av_async_pool = coro_get_av (aTHX_ "Coro::async_pool", TRUE);
3419 av_destroy = coro_get_av (aTHX_ "Coro::destroy" , TRUE);
3420 sv_manager = coro_get_sv (aTHX_ "Coro::manager" , TRUE);
3421 sv_idle = coro_get_sv (aTHX_ "Coro::idle" , TRUE);
3422
3423 sv_async_pool_idle = newSVpv ("[async pool idle]", 0); SvREADONLY_on (sv_async_pool_idle);
3424 sv_Coro = newSVpv ("Coro", 0); SvREADONLY_on (sv_Coro);
3425 cv_pool_handler = get_cv ("Coro::pool_handler", GV_ADD); SvREADONLY_on (cv_pool_handler);
3426 CvNODEBUG_on (get_cv ("Coro::_pool_handler", 0)); /* work around a debugger bug */
3427
3428 coro_stash = gv_stashpv ("Coro", TRUE);
3429
3430 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (CORO_PRIO_MAX));
3431 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (CORO_PRIO_HIGH));
3432 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (CORO_PRIO_NORMAL));
3433 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (CORO_PRIO_LOW));
3434 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (CORO_PRIO_IDLE));
3435 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (CORO_PRIO_MIN));
3436
3437 {
3438 SV *sv = coro_get_sv (aTHX_ "Coro::API", TRUE);
3439
3440 coroapi.schedule = api_schedule;
3441 coroapi.schedule_to = api_schedule_to;
3442 coroapi.cede = api_cede;
3443 coroapi.cede_notself = api_cede_notself;
3444 coroapi.ready = api_ready;
3445 coroapi.is_ready = api_is_ready;
3446 coroapi.nready = coro_nready;
3447 coroapi.current = coro_current;
3448
3449 /*GCoroAPI = &coroapi;*/
3450 sv_setiv (sv, (IV)&coroapi);
3451 SvREADONLY_on (sv);
3452 }
3453}
3454
3455SV *
3456async (...)
3457 PROTOTYPE: &@
417 CODE: 3458 CODE:
3459 RETVAL = coro_new (aTHX_ coro_stash, &ST (0), items, 1);
3460 api_ready (aTHX_ RETVAL);
3461 OUTPUT:
3462 RETVAL
418 3463
419 if (prev != next) 3464void
3465terminate (...)
3466 CODE:
3467 CORO_EXECUTE_SLF_XS (slf_init_terminate);
3468
3469void
3470schedule (...)
3471 CODE:
3472 CORO_EXECUTE_SLF_XS (slf_init_schedule);
3473
3474void
3475schedule_to (...)
3476 CODE:
3477 CORO_EXECUTE_SLF_XS (slf_init_schedule_to);
3478
3479void
3480cede_to (...)
3481 CODE:
3482 CORO_EXECUTE_SLF_XS (slf_init_cede_to);
3483
3484void
3485cede (...)
3486 CODE:
3487 CORO_EXECUTE_SLF_XS (slf_init_cede);
3488
3489void
3490cede_notself (...)
3491 CODE:
3492 CORO_EXECUTE_SLF_XS (slf_init_cede_notself);
3493
3494void
3495_set_current (SV *current)
3496 PROTOTYPE: $
3497 CODE:
3498 SvREFCNT_dec (SvRV (coro_current));
3499 SvRV_set (coro_current, SvREFCNT_inc_NN (SvRV (current)));
3500
3501void
3502_set_readyhook (SV *hook)
3503 PROTOTYPE: $
3504 CODE:
3505 SvREFCNT_dec (coro_readyhook);
3506 SvGETMAGIC (hook);
3507 if (SvOK (hook))
3508 {
3509 coro_readyhook = newSVsv (hook);
3510 CORO_READYHOOK = invoke_sv_ready_hook_helper;
3511 }
3512 else
420 { 3513 {
421 /* 3514 coro_readyhook = 0;
422 * this could be done in newprocess which would lead to 3515 CORO_READYHOOK = 0;
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);
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 } 3516 }
473 3517
3518int
3519prio (Coro::State coro, int newprio = 0)
3520 PROTOTYPE: $;$
3521 ALIAS:
3522 nice = 1
3523 CODE:
3524{
3525 RETVAL = coro->prio;
3526
3527 if (items > 1)
3528 {
3529 if (ix)
3530 newprio = coro->prio - newprio;
3531
3532 if (newprio < CORO_PRIO_MIN) newprio = CORO_PRIO_MIN;
3533 if (newprio > CORO_PRIO_MAX) newprio = CORO_PRIO_MAX;
3534
3535 coro->prio = newprio;
3536 }
3537}
3538 OUTPUT:
3539 RETVAL
3540
3541SV *
3542ready (SV *self)
3543 PROTOTYPE: $
3544 CODE:
3545 RETVAL = boolSV (api_ready (aTHX_ self));
3546 OUTPUT:
3547 RETVAL
3548
3549int
3550nready (...)
3551 PROTOTYPE:
3552 CODE:
3553 RETVAL = coro_nready;
3554 OUTPUT:
3555 RETVAL
3556
474void 3557void
475DESTROY(coro) 3558suspend (Coro::State self)
476 Coro::State coro 3559 PROTOTYPE: $
3560 CODE:
3561 self->flags |= CF_SUSPENDED;
3562
3563void
3564resume (Coro::State self)
3565 PROTOTYPE: $
3566 CODE:
3567 self->flags &= ~CF_SUSPENDED;
3568
3569void
3570_pool_handler (...)
3571 CODE:
3572 CORO_EXECUTE_SLF_XS (slf_init_pool_handler);
3573
3574void
3575async_pool (SV *cv, ...)
3576 PROTOTYPE: &@
3577 PPCODE:
3578{
3579 HV *hv = (HV *)av_pop (av_async_pool);
3580 AV *av = newAV ();
3581 SV *cb = ST (0);
3582 int i;
3583
3584 av_extend (av, items - 2);
3585 for (i = 1; i < items; ++i)
3586 av_push (av, SvREFCNT_inc_NN (ST (i)));
3587
3588 if ((SV *)hv == &PL_sv_undef)
3589 {
3590 SV *sv = coro_new (aTHX_ coro_stash, (SV **)&cv_pool_handler, 1, 1);
3591 hv = (HV *)SvREFCNT_inc_NN (SvRV (sv));
3592 SvREFCNT_dec (sv);
3593 }
3594
3595 {
3596 struct coro *coro = SvSTATE_hv (hv);
3597
3598 assert (!coro->invoke_cb);
3599 assert (!coro->invoke_av);
3600 coro->invoke_cb = SvREFCNT_inc (cb);
3601 coro->invoke_av = av;
3602 }
3603
3604 api_ready (aTHX_ (SV *)hv);
3605
3606 if (GIMME_V != G_VOID)
3607 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
3608 else
3609 SvREFCNT_dec (hv);
3610}
3611
3612SV *
3613rouse_cb ()
3614 PROTOTYPE:
3615 CODE:
3616 RETVAL = coro_new_rouse_cb (aTHX);
3617 OUTPUT:
3618 RETVAL
3619
3620void
3621rouse_wait (...)
3622 PROTOTYPE: ;$
3623 PPCODE:
3624 CORO_EXECUTE_SLF_XS (slf_init_rouse_wait);
3625
3626void
3627on_enter (SV *block)
3628 ALIAS:
3629 on_leave = 1
3630 PROTOTYPE: &
3631 CODE:
3632{
3633 struct coro *coro = SvSTATE_current;
3634 AV **avp = ix ? &coro->on_leave : &coro->on_enter;
3635
3636 block = s_get_cv_croak (block);
3637
3638 if (!*avp)
3639 *avp = newAV ();
3640
3641 av_push (*avp, SvREFCNT_inc (block));
3642
3643 if (!ix)
3644 on_enterleave_call (aTHX_ block);
3645
3646 LEAVE; /* pp_entersub unfortunately forces an ENTER/LEAVE around XS calls */
3647 SAVEDESTRUCTOR_X (ix ? coro_pop_on_leave : coro_pop_on_enter, (void *)coro);
3648 ENTER; /* pp_entersub unfortunately forces an ENTER/LEAVE around XS calls */
3649}
3650
3651
3652MODULE = Coro::State PACKAGE = PerlIO::cede
3653
3654BOOT:
3655 PerlIO_define_layer (aTHX_ &PerlIO_cede);
3656
3657
3658MODULE = Coro::State PACKAGE = Coro::Semaphore
3659
3660SV *
3661new (SV *klass, SV *count = 0)
3662 CODE:
3663{
3664 int semcnt = 1;
3665
3666 if (count)
3667 {
3668 SvGETMAGIC (count);
3669
3670 if (SvOK (count))
3671 semcnt = SvIV (count);
3672 }
3673
3674 RETVAL = sv_bless (
3675 coro_waitarray_new (aTHX_ semcnt),
3676 GvSTASH (CvGV (cv))
3677 );
3678}
3679 OUTPUT:
3680 RETVAL
3681
3682# helper for Coro::Channel and others
3683SV *
3684_alloc (int count)
3685 CODE:
3686 RETVAL = coro_waitarray_new (aTHX_ count);
3687 OUTPUT:
3688 RETVAL
3689
3690SV *
3691count (SV *self)
3692 CODE:
3693 RETVAL = newSVsv (AvARRAY ((AV *)SvRV (self))[0]);
3694 OUTPUT:
3695 RETVAL
3696
3697void
3698up (SV *self, int adjust = 1)
3699 ALIAS:
3700 adjust = 1
477 CODE: 3701 CODE:
3702 coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), ix ? adjust : 1);
478 3703
479 if (coro->mainstack) 3704void
3705down (...)
3706 CODE:
3707 CORO_EXECUTE_SLF_XS (slf_init_semaphore_down);
3708
3709void
3710wait (...)
3711 CODE:
3712 CORO_EXECUTE_SLF_XS (slf_init_semaphore_wait);
3713
3714void
3715try (SV *self)
3716 PPCODE:
3717{
3718 AV *av = (AV *)SvRV (self);
3719 SV *count_sv = AvARRAY (av)[0];
3720 IV count = SvIVX (count_sv);
3721
3722 if (count > 0)
480 { 3723 {
481 struct coro temp; 3724 --count;
482 3725 SvIVX (count_sv) = count;
483 SAVE(aTHX_ (&temp)); 3726 XSRETURN_YES;
484 LOAD(aTHX_ coro);
485
486 destroy_stacks ();
487 SvREFCNT_dec ((SV *)GvAV (PL_defgv));
488
489 LOAD((&temp));
490 } 3727 }
3728 else
3729 XSRETURN_NO;
3730}
491 3731
492 SvREFCNT_dec (coro->args); 3732void
493 Safefree (coro); 3733waiters (SV *self)
3734 PPCODE:
3735{
3736 AV *av = (AV *)SvRV (self);
3737 int wcount = AvFILLp (av) + 1 - 1;
494 3738
3739 if (GIMME_V == G_SCALAR)
3740 XPUSHs (sv_2mortal (newSViv (wcount)));
3741 else
3742 {
3743 int i;
3744 EXTEND (SP, wcount);
3745 for (i = 1; i <= wcount; ++i)
3746 PUSHs (sv_2mortal (newRV_inc (AvARRAY (av)[i])));
3747 }
3748}
495 3749
3750MODULE = Coro::State PACKAGE = Coro::SemaphoreSet
3751
3752void
3753_may_delete (SV *sem, int count, int extra_refs)
3754 PPCODE:
3755{
3756 AV *av = (AV *)SvRV (sem);
3757
3758 if (SvREFCNT ((SV *)av) == 1 + extra_refs
3759 && AvFILLp (av) == 0 /* no waiters, just count */
3760 && SvIV (AvARRAY (av)[0]) == count)
3761 XSRETURN_YES;
3762
3763 XSRETURN_NO;
3764}
3765
3766MODULE = Coro::State PACKAGE = Coro::Signal
3767
3768SV *
3769new (SV *klass)
3770 CODE:
3771 RETVAL = sv_bless (
3772 coro_waitarray_new (aTHX_ 0),
3773 GvSTASH (CvGV (cv))
3774 );
3775 OUTPUT:
3776 RETVAL
3777
3778void
3779wait (...)
3780 CODE:
3781 CORO_EXECUTE_SLF_XS (slf_init_signal_wait);
3782
3783void
3784broadcast (SV *self)
3785 CODE:
3786{
3787 AV *av = (AV *)SvRV (self);
3788 coro_signal_wake (aTHX_ av, AvFILLp (av));
3789}
3790
3791void
3792send (SV *self)
3793 CODE:
3794{
3795 AV *av = (AV *)SvRV (self);
3796
3797 if (AvFILLp (av))
3798 coro_signal_wake (aTHX_ av, 1);
3799 else
3800 SvIVX (AvARRAY (av)[0]) = 1; /* remember the signal */
3801}
3802
3803IV
3804awaited (SV *self)
3805 CODE:
3806 RETVAL = AvFILLp ((AV *)SvRV (self)) + 1 - 1;
3807 OUTPUT:
3808 RETVAL
3809
3810
3811MODULE = Coro::State PACKAGE = Coro::AnyEvent
3812
3813BOOT:
3814 sv_activity = coro_get_sv (aTHX_ "Coro::AnyEvent::ACTIVITY", TRUE);
3815
3816void
3817_schedule (...)
3818 CODE:
3819{
3820 static int incede;
3821
3822 api_cede_notself (aTHX);
3823
3824 ++incede;
3825 while (coro_nready >= incede && api_cede (aTHX))
3826 ;
3827
3828 sv_setsv (sv_activity, &PL_sv_undef);
3829 if (coro_nready >= incede)
3830 {
3831 PUSHMARK (SP);
3832 PUTBACK;
3833 call_pv ("Coro::AnyEvent::_activity", G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
3834 }
3835
3836 --incede;
3837}
3838
3839
3840MODULE = Coro::State PACKAGE = Coro::AIO
3841
3842void
3843_register (char *target, char *proto, SV *req)
3844 CODE:
3845{
3846 SV *req_cv = s_get_cv_croak (req);
3847 /* newXSproto doesn't return the CV on 5.8 */
3848 CV *slf_cv = newXS (target, coro_aio_req_xs, __FILE__);
3849 sv_setpv ((SV *)slf_cv, proto);
3850 sv_magicext ((SV *)slf_cv, (SV *)req_cv, CORO_MAGIC_type_aio, 0, 0, 0);
3851}
3852
3853MODULE = Coro::State PACKAGE = Coro::Select
3854
3855void
3856patch_pp_sselect ()
3857 CODE:
3858 if (!coro_old_pp_sselect)
3859 {
3860 coro_select_select = (SV *)get_cv ("Coro::Select::select", 0);
3861 coro_old_pp_sselect = PL_ppaddr [OP_SSELECT];
3862 PL_ppaddr [OP_SSELECT] = coro_pp_sselect;
3863 }
3864
3865void
3866unpatch_pp_sselect ()
3867 CODE:
3868 if (coro_old_pp_sselect)
3869 {
3870 PL_ppaddr [OP_SSELECT] = coro_old_pp_sselect;
3871 coro_old_pp_sselect = 0;
3872 }
3873
3874

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines