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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines