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.5 by root, Tue Jul 17 02:55:29 2001 UTC vs.
Revision 1.414 by root, Wed Jun 29 16:08:31 2011 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines