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

Comparing Coro/Coro/State.xs (file contents):
Revision 1.6 by root, Tue Jul 17 15:42:28 2001 UTC vs.
Revision 1.426 by root, Wed Dec 5 00:19:57 2012 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines