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

Comparing Coro/Coro/State.xs (file contents):
Revision 1.5 by root, Tue Jul 17 02:55:29 2001 UTC vs.
Revision 1.377 by root, Sat Oct 3 17:55:04 2009 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines