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

Comparing Coro/Coro/State.xs (file contents):
Revision 1.6 by root, Tue Jul 17 15:42:28 2001 UTC vs.
Revision 1.433 by root, Thu May 9 05:40:14 2013 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines