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.4 by root, Tue Jul 17 02:21:56 2001 UTC vs.
Revision 1.67 by root, Mon Dec 12 20:07:44 2005 UTC

1#define PERL_NO_GET_CONTEXT
2
3#include "libcoro/coro.c"
4
1#include "EXTERN.h" 5#include "EXTERN.h"
2#include "perl.h" 6#include "perl.h"
3#include "XSUB.h" 7#include "XSUB.h"
4 8
5#if 0 9#include "patchlevel.h"
6# define CHK(x) (void *)0 10
11// threaded perls might need much more, 65536 or more,
12// which is 0.5 to 1MB
13#define STACKSIZE 16384
14
15#if PERL_VERSION < 6
16# ifndef PL_ppaddr
17# define PL_ppaddr ppaddr
18# endif
19# ifndef call_sv
20# define call_sv perl_call_sv
21# endif
22# ifndef get_sv
23# define get_sv perl_get_sv
24# endif
25# ifndef get_cv
26# define get_cv perl_get_cv
27# endif
28# ifndef IS_PADGV
29# define IS_PADGV(v) 0
30# endif
31# ifndef IS_PADCONST
32# define IS_PADCONST(v) 0
33# endif
34#endif
35
36#include <signal.h>
37
38#ifdef HAVE_MMAP
39# include <unistd.h>
40# include <sys/mman.h>
41# ifndef MAP_ANONYMOUS
42# ifdef MAP_ANON
43# define MAP_ANONYMOUS MAP_ANON
44# else
45# undef HAVE_MMAP
46# endif
47# endif
48#endif
49
50#define SUB_INIT "Coro::State::initialize"
51#define UCORO_STATE "_coro_state"
52
53/* The next macro should declare a variable stacklevel that contains and approximation
54 * to the current C stack pointer. Its property is that it changes with each call
55 * and should be unique. */
56#define dSTACKLEVEL void *stacklevel = &stacklevel
57
58#define IN_DESTRUCT (PL_main_cv == Nullcv)
59
60#define labs(l) ((l) >= 0 ? (l) : -(l))
61
62#include "CoroAPI.h"
63
64#ifdef USE_ITHREADS
65static perl_mutex coro_mutex;
66# define LOCK do { MUTEX_LOCK (&coro_mutex); } while (0)
67# define UNLOCK do { MUTEX_UNLOCK (&coro_mutex); } while (0)
7#else 68#else
8# define CHK(x) if (!(x)) croak("FATAL, CHK: " #x) 69# define LOCK 0
70# define UNLOCK 0
9#endif 71#endif
10 72
73static struct CoroAPI coroapi;
74static AV *main_mainstack; /* used to differentiate between $main and others */
75static HV *coro_state_stash;
76static SV *ucoro_state_sv;
77static U32 ucoro_state_hash;
78static SV *coro_mortal; /* will be freed after next transfer */
79
80/* this is actually not only the c stack but also c registers etc... */
81typedef struct {
82 int refcnt; /* pointer reference counter */
83 int usecnt; /* shared by how many coroutines */
84 int gencnt; /* generation counter */
85
86 coro_context cctx;
87
88 void *sptr;
89 long ssize; /* positive == mmap, otherwise malloc */
90} coro_stack;
91
11struct coro { 92struct coro {
93 /* the top-level JMPENV for each coroutine, needed to catch dies. */
94 JMPENV start_env;
95
96 /* the optional C context */
97 coro_stack *stack;
98 void *cursp;
99 int gencnt;
100
101 /* optionally saved, might be zero */
102 AV *defav;
103 SV *defsv;
104 SV *errsv;
105
106 /* saved global state not related to stacks */
12 U8 dowarn; 107 U8 dowarn;
13 AV *defav; 108 I32 in_eval;
14 109
110 /* the stacks and related info (callchain etc..) */
15 PERL_SI *curstackinfo; 111 PERL_SI *curstackinfo;
16 AV *curstack; 112 AV *curstack;
17 AV *mainstack; 113 AV *mainstack;
18 SV **stack_sp; 114 SV **stack_sp;
19 OP *op; 115 OP *op;
20 SV **curpad; 116 SV **curpad;
117 AV *comppad;
118 CV *compcv;
21 SV **stack_base; 119 SV **stack_base;
22 SV **stack_max; 120 SV **stack_max;
23 SV **tmps_stack; 121 SV **tmps_stack;
24 I32 tmps_floor; 122 I32 tmps_floor;
25 I32 tmps_ix; 123 I32 tmps_ix;
34 I32 savestack_ix; 132 I32 savestack_ix;
35 I32 savestack_max; 133 I32 savestack_max;
36 OP **retstack; 134 OP **retstack;
37 I32 retstack_ix; 135 I32 retstack_ix;
38 I32 retstack_max; 136 I32 retstack_max;
137 PMOP *curpm;
39 COP *curcop; 138 COP *curcop;
139 JMPENV *top_env;
40 140
141 /* data associated with this coroutine (initial args) */
41 AV *args; 142 AV *args;
42}; 143};
43 144
44typedef struct coro *Coro__State; 145typedef struct coro *Coro__State;
45typedef struct coro *Coro__State_or_hashref; 146typedef struct coro *Coro__State_or_hashref;
46 147
47static HV *padlist_cache;
48
49/* mostly copied from op.c:cv_clone2 */ 148/* mostly copied from op.c:cv_clone2 */
50STATIC AV * 149STATIC AV *
51clone_padlist (AV *protopadlist) 150clone_padlist (pTHX_ AV *protopadlist)
52{ 151{
53 AV *av; 152 AV *av;
54 I32 ix; 153 I32 ix;
55 AV *protopad_name = (AV *) * av_fetch (protopadlist, 0, FALSE); 154 AV *protopad_name = (AV *) * av_fetch (protopadlist, 0, FALSE);
56 AV *protopad = (AV *) * av_fetch (protopadlist, 1, FALSE); 155 AV *protopad = (AV *) * av_fetch (protopadlist, 1, FALSE);
80 AvFLAGS (av) = AVf_REIFY; 179 AvFLAGS (av) = AVf_REIFY;
81 180
82 for (ix = fpad; ix > 0; ix--) 181 for (ix = fpad; ix > 0; ix--)
83 { 182 {
84 SV *namesv = (ix <= fname) ? pname[ix] : Nullsv; 183 SV *namesv = (ix <= fname) ? pname[ix] : Nullsv;
184
85 if (namesv && namesv != &PL_sv_undef) 185 if (namesv && namesv != &PL_sv_undef)
86 { 186 {
87 char *name = SvPVX (namesv); /* XXX */ 187 char *name = SvPVX (namesv); /* XXX */
188
88 if (SvFLAGS (namesv) & SVf_FAKE || *name == '&') 189 if (SvFLAGS (namesv) & SVf_FAKE || *name == '&')
89 { /* lexical from outside? */ 190 { /* lexical from outside? */
90 npad[ix] = SvREFCNT_inc (ppad[ix]); 191 npad[ix] = SvREFCNT_inc (ppad[ix]);
91 } 192 }
92 else 193 else
98 sv = (SV *) newAV (); 199 sv = (SV *) newAV ();
99 else if (*name == '%') 200 else if (*name == '%')
100 sv = (SV *) newHV (); 201 sv = (SV *) newHV ();
101 else 202 else
102 sv = NEWSV (0, 0); 203 sv = NEWSV (0, 0);
204
205#ifdef SvPADBUSY
103 if (!SvPADBUSY (sv)) 206 if (!SvPADBUSY (sv))
207#endif
104 SvPADMY_on (sv); 208 SvPADMY_on (sv);
209
105 npad[ix] = sv; 210 npad[ix] = sv;
106 } 211 }
107 } 212 }
108 else if (IS_PADGV (ppad[ix]) || IS_PADCONST (ppad[ix])) 213 else if (IS_PADGV (ppad[ix]) || IS_PADCONST (ppad[ix]))
109 { 214 {
115 SvPADTMP_on (sv); 220 SvPADTMP_on (sv);
116 npad[ix] = sv; 221 npad[ix] = sv;
117 } 222 }
118 } 223 }
119 224
120#if 0 /* NONOTUNDERSTOOD */ 225#if 0 /* return -ENOTUNDERSTOOD */
121 /* Now that vars are all in place, clone nested closures. */ 226 /* Now that vars are all in place, clone nested closures. */
122 227
123 for (ix = fpad; ix > 0; ix--) { 228 for (ix = fpad; ix > 0; ix--) {
124 SV* namesv = (ix <= fname) ? pname[ix] : Nullsv; 229 SV* namesv = (ix <= fname) ? pname[ix] : Nullsv;
125 if (namesv 230 if (namesv
138#endif 243#endif
139 244
140 return newpadlist; 245 return newpadlist;
141} 246}
142 247
143STATIC AV * 248STATIC void
144free_padlist (AV *padlist) 249free_padlist (pTHX_ AV *padlist)
145{ 250{
146 /* may be during global destruction */ 251 /* may be during global destruction */
147 if (SvREFCNT(padlist)) 252 if (SvREFCNT (padlist))
148 { 253 {
149 I32 i = AvFILLp(padlist); 254 I32 i = AvFILLp (padlist);
150 while (i >= 0) 255 while (i >= 0)
151 { 256 {
152 SV **svp = av_fetch(padlist, i--, FALSE); 257 SV **svp = av_fetch (padlist, i--, FALSE);
153 SV *sv = svp ? *svp : Nullsv;
154 if (sv) 258 if (svp)
259 {
260 SV *sv;
261 while (&PL_sv_undef != (sv = av_pop ((AV *)*svp)))
155 SvREFCNT_dec(sv); 262 SvREFCNT_dec (sv);
263
264 SvREFCNT_dec (*svp);
265 }
156 } 266 }
157 267
158 SvREFCNT_dec((SV*)padlist); 268 SvREFCNT_dec ((SV*)padlist);
269 }
270}
271
272STATIC int
273coro_cv_free (pTHX_ SV *sv, MAGIC *mg)
274{
275 AV *padlist;
276 AV *av = (AV *)mg->mg_obj;
277
278 /* casting is fun. */
279 while (&PL_sv_undef != (SV *)(padlist = (AV *)av_pop (av)))
280 free_padlist (aTHX_ padlist);
281
282 SvREFCNT_dec (av);
283}
284
285#define PERL_MAGIC_coro PERL_MAGIC_ext
286
287static MGVTBL vtbl_coro = {0, 0, 0, 0, coro_cv_free};
288
289/* the next two functions merely cache the padlists */
290STATIC void
291get_padlist (pTHX_ CV *cv)
292{
293 MAGIC *mg = mg_find ((SV *)cv, PERL_MAGIC_coro);
294
295 if (mg && AvFILLp ((AV *)mg->mg_obj) >= 0)
296 CvPADLIST (cv) = (AV *)av_pop ((AV *)mg->mg_obj);
297 else
298 CvPADLIST (cv) = clone_padlist (aTHX_ CvPADLIST (cv));
299}
300
301STATIC void
302put_padlist (pTHX_ CV *cv)
303{
304 MAGIC *mg = mg_find ((SV *)cv, PERL_MAGIC_coro);
305
306 if (!mg)
307 {
308 sv_magic ((SV *)cv, 0, PERL_MAGIC_coro, 0, 0);
309 mg = mg_find ((SV *)cv, PERL_MAGIC_coro);
310 mg->mg_virtual = &vtbl_coro;
311 mg->mg_obj = (SV *)newAV ();
312 }
313
314 av_push ((AV *)mg->mg_obj, (SV *)CvPADLIST (cv));
315}
316
317#define SB do {
318#define SE } while (0)
319
320#define LOAD(state) load_state(aTHX_ (state));
321#define SAVE(state,flags) save_state(aTHX_ (state),(flags));
322
323#define REPLACE_SV(sv,val) SB SvREFCNT_dec(sv); (sv) = (val); (val) = 0; SE
324
325static void
326load_state(pTHX_ Coro__State c)
327{
328 PL_dowarn = c->dowarn;
329 PL_in_eval = c->in_eval;
330
331 PL_curstackinfo = c->curstackinfo;
332 PL_curstack = c->curstack;
333 PL_mainstack = c->mainstack;
334 PL_stack_sp = c->stack_sp;
335 PL_op = c->op;
336 PL_curpad = c->curpad;
337 PL_comppad = c->comppad;
338 PL_compcv = c->compcv;
339 PL_stack_base = c->stack_base;
340 PL_stack_max = c->stack_max;
341 PL_tmps_stack = c->tmps_stack;
342 PL_tmps_floor = c->tmps_floor;
343 PL_tmps_ix = c->tmps_ix;
344 PL_tmps_max = c->tmps_max;
345 PL_markstack = c->markstack;
346 PL_markstack_ptr = c->markstack_ptr;
347 PL_markstack_max = c->markstack_max;
348 PL_scopestack = c->scopestack;
349 PL_scopestack_ix = c->scopestack_ix;
350 PL_scopestack_max = c->scopestack_max;
351 PL_savestack = c->savestack;
352 PL_savestack_ix = c->savestack_ix;
353 PL_savestack_max = c->savestack_max;
354 PL_retstack = c->retstack;
355 PL_retstack_ix = c->retstack_ix;
356 PL_retstack_max = c->retstack_max;
357 PL_curpm = c->curpm;
358 PL_curcop = c->curcop;
359 PL_top_env = c->top_env;
360
361 if (c->defav) REPLACE_SV (GvAV (PL_defgv), c->defav);
362 if (c->defsv) REPLACE_SV (DEFSV , c->defsv);
363 if (c->errsv) REPLACE_SV (ERRSV , c->errsv);
364
365 {
366 dSP;
367 CV *cv;
368
369 /* now do the ugly restore mess */
370 while ((cv = (CV *)POPs))
371 {
372 AV *padlist = (AV *)POPs;
373
374 if (padlist)
375 {
376 put_padlist (aTHX_ cv); /* mark this padlist as available */
377 CvPADLIST(cv) = padlist;
378 }
379
380 ++CvDEPTH(cv);
381 }
382
383 PUTBACK;
159 } 384 }
160} 385}
161 386
162/* the next tow functions merely cache the padlists */
163STATIC void
164get_padlist (CV *cv)
165{
166 SV **he = hv_fetch (padlist_cache, (void *)&cv, sizeof (CV *), 0);
167
168 if (he && AvFILLp ((AV *)*he) >= 0)
169 CvPADLIST (cv) = (AV *)av_pop ((AV *)*he);
170 else
171 CvPADLIST (cv) = clone_padlist (CvPADLIST (cv));
172}
173
174STATIC void
175put_padlist (CV *cv)
176{
177 SV **he = hv_fetch (padlist_cache, (void *)&cv, sizeof (CV *), 1);
178
179 if (SvTYPE (*he) != SVt_PVAV)
180 {
181 SvREFCNT_dec (*he);
182 *he = (SV *)newAV ();
183 }
184
185 av_push ((AV *)*he, (SV *)CvPADLIST (cv));
186}
187
188static void 387static void
189SAVE(pTHX_ Coro__State c) 388save_state(pTHX_ Coro__State c, int flags)
190{ 389{
191 { 390 {
192 dSP; 391 dSP;
193 I32 cxix = cxstack_ix; 392 I32 cxix = cxstack_ix;
393 PERL_CONTEXT *ccstk = cxstack;
194 PERL_SI *top_si = PL_curstackinfo; 394 PERL_SI *top_si = PL_curstackinfo;
195 PERL_CONTEXT *ccstk = cxstack;
196 395
197 /* 396 /*
198 * the worst thing you can imagine happens first - we have to save 397 * the worst thing you can imagine happens first - we have to save
199 * (and reinitialize) all cv's in the whole callchain :( 398 * (and reinitialize) all cv's in the whole callchain :(
200 */ 399 */
210 if (CxTYPE(cx) == CXt_SUB) 409 if (CxTYPE(cx) == CXt_SUB)
211 { 410 {
212 CV *cv = cx->blk_sub.cv; 411 CV *cv = cx->blk_sub.cv;
213 if (CvDEPTH(cv)) 412 if (CvDEPTH(cv))
214 { 413 {
215#ifdef USE_THREADS
216 XPUSHs ((SV *)CvOWNER(cv));
217#endif
218 EXTEND (SP, 3); 414 EXTEND (SP, CvDEPTH(cv)*2);
415
416 while (--CvDEPTH(cv))
417 {
418 /* this tells the restore code to increment CvDEPTH */
419 PUSHs (Nullsv);
219 PUSHs ((SV *)CvDEPTH(cv)); 420 PUSHs ((SV *)cv);
421 }
422
220 PUSHs ((SV *)CvPADLIST(cv)); 423 PUSHs ((SV *)CvPADLIST(cv));
221 PUSHs ((SV *)cv); 424 PUSHs ((SV *)cv);
222 425
223 get_padlist (cv); 426 get_padlist (aTHX_ cv); /* this is a monster */
224
225 CvDEPTH(cv) = 0;
226#ifdef USE_THREADS
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 } 427 }
233 } 428 }
429#ifdef CXt_FORMAT
234 else if (CxTYPE(cx) == CXt_FORMAT) 430 else if (CxTYPE(cx) == CXt_FORMAT)
235 { 431 {
236 /* I never used formats, so how should I know how these are implemented? */ 432 /* I never used formats, so how should I know how these are implemented? */
237 /* my bold guess is as a simple, plain sub... */ 433 /* my bold guess is as a simple, plain sub... */
238 croak ("CXt_FORMAT not yet handled. Don't switch coroutines from within formats"); 434 croak ("CXt_FORMAT not yet handled. Don't switch coroutines from within formats");
239 } 435 }
436#endif
240 } 437 }
241 438
242 if (top_si->si_type == PERLSI_MAIN) 439 if (top_si->si_type == PERLSI_MAIN)
243 break; 440 break;
244 441
248 } 445 }
249 446
250 PUTBACK; 447 PUTBACK;
251 } 448 }
252 449
450 c->defav = flags & TRANSFER_SAVE_DEFAV ? (AV *)SvREFCNT_inc (GvAV (PL_defgv)) : 0;
451 c->defsv = flags & TRANSFER_SAVE_DEFSV ? SvREFCNT_inc (DEFSV) : 0;
452 c->errsv = flags & TRANSFER_SAVE_ERRSV ? SvREFCNT_inc (ERRSV) : 0;
453
253 c->dowarn = PL_dowarn; 454 c->dowarn = PL_dowarn;
254 c->defav = GvAV (PL_defgv); 455 c->in_eval = PL_in_eval;
456
255 c->curstackinfo = PL_curstackinfo; 457 c->curstackinfo = PL_curstackinfo;
256 c->curstack = PL_curstack; 458 c->curstack = PL_curstack;
257 c->mainstack = PL_mainstack; 459 c->mainstack = PL_mainstack;
258 c->stack_sp = PL_stack_sp; 460 c->stack_sp = PL_stack_sp;
259 c->op = PL_op; 461 c->op = PL_op;
260 c->curpad = PL_curpad; 462 c->curpad = PL_curpad;
463 c->comppad = PL_comppad;
464 c->compcv = PL_compcv;
261 c->stack_base = PL_stack_base; 465 c->stack_base = PL_stack_base;
262 c->stack_max = PL_stack_max; 466 c->stack_max = PL_stack_max;
263 c->tmps_stack = PL_tmps_stack; 467 c->tmps_stack = PL_tmps_stack;
264 c->tmps_floor = PL_tmps_floor; 468 c->tmps_floor = PL_tmps_floor;
265 c->tmps_ix = PL_tmps_ix; 469 c->tmps_ix = PL_tmps_ix;
274 c->savestack_ix = PL_savestack_ix; 478 c->savestack_ix = PL_savestack_ix;
275 c->savestack_max = PL_savestack_max; 479 c->savestack_max = PL_savestack_max;
276 c->retstack = PL_retstack; 480 c->retstack = PL_retstack;
277 c->retstack_ix = PL_retstack_ix; 481 c->retstack_ix = PL_retstack_ix;
278 c->retstack_max = PL_retstack_max; 482 c->retstack_max = PL_retstack_max;
483 c->curpm = PL_curpm;
279 c->curcop = PL_curcop; 484 c->curcop = PL_curcop;
485 c->top_env = PL_top_env;
280} 486}
281 487
282static void 488/*
283LOAD(pTHX_ Coro__State c) 489 * allocate various perl stacks. This is an exact copy
490 * of perl.c:init_stacks, except that it uses less memory
491 * on the (sometimes correct) assumption that coroutines do
492 * not usually need a lot of stackspace.
493 */
494STATIC void
495coro_init_stacks (pTHX)
284{ 496{
285 PL_dowarn = c->dowarn; 497 LOCK;
286 GvAV (PL_defgv) = c->defav; 498
287 PL_curstackinfo = c->curstackinfo; 499 PL_curstackinfo = new_stackinfo(96, 1024/sizeof(PERL_CONTEXT) - 1);
288 PL_curstack = c->curstack; 500 PL_curstackinfo->si_type = PERLSI_MAIN;
289 PL_mainstack = c->mainstack; 501 PL_curstack = PL_curstackinfo->si_stack;
502 PL_mainstack = PL_curstack; /* remember in case we switch stacks */
503
504 PL_stack_base = AvARRAY(PL_curstack);
290 PL_stack_sp = c->stack_sp; 505 PL_stack_sp = PL_stack_base;
291 PL_op = c->op; 506 PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
292 PL_curpad = c->curpad; 507
293 PL_stack_base = c->stack_base; 508 New(50,PL_tmps_stack,96,SV*);
294 PL_stack_max = c->stack_max; 509 PL_tmps_floor = -1;
295 PL_tmps_stack = c->tmps_stack; 510 PL_tmps_ix = -1;
296 PL_tmps_floor = c->tmps_floor; 511 PL_tmps_max = 96;
297 PL_tmps_ix = c->tmps_ix; 512
298 PL_tmps_max = c->tmps_max; 513 New(54,PL_markstack,16,I32);
299 PL_markstack = c->markstack;
300 PL_markstack_ptr = c->markstack_ptr; 514 PL_markstack_ptr = PL_markstack;
301 PL_markstack_max = c->markstack_max; 515 PL_markstack_max = PL_markstack + 16;
302 PL_scopestack = c->scopestack;
303 PL_scopestack_ix = c->scopestack_ix;
304 PL_scopestack_max = c->scopestack_max;
305 PL_savestack = c->savestack;
306 PL_savestack_ix = c->savestack_ix;
307 PL_savestack_max = c->savestack_max;
308 PL_retstack = c->retstack;
309 PL_retstack_ix = c->retstack_ix;
310 PL_retstack_max = c->retstack_max;
311 PL_curcop = c->curcop;
312 516
313 { 517#ifdef SET_MARK_OFFSET
314 dSP; 518 SET_MARK_OFFSET;
315 CV *cv;
316
317 /* now do the ugly restore mess */
318 while ((cv = (CV *)POPs))
319 {
320 AV *padlist = (AV *)POPs;
321
322 put_padlist (cv);
323 CvPADLIST(cv) = padlist;
324 CvDEPTH(cv) = (I32)POPs;
325
326#ifdef USE_THREADS
327 CvOWNER(cv) = (struct perl_thread *)POPs;
328 error does not work either
329#endif 519#endif
330 }
331 520
332 PUTBACK; 521 New(54,PL_scopestack,16,I32);
333 } 522 PL_scopestack_ix = 0;
334} 523 PL_scopestack_max = 16;
335 524
336/* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ 525 New(54,PL_savestack,96,ANY);
526 PL_savestack_ix = 0;
527 PL_savestack_max = 96;
528
529 New(54,PL_retstack,8,OP*);
530 PL_retstack_ix = 0;
531 PL_retstack_max = 8;
532
533 UNLOCK;
534}
535
536/*
537 * destroy the stacks, the callchain etc...
538 */
337STATIC void 539STATIC void
338destroy_stacks(pTHX) 540destroy_stacks(pTHX)
339{ 541{
340 dSP; 542 if (!IN_DESTRUCT)
341 543 {
342 /* die does this while calling POPSTACK, but I just don't see why. */
343 dounwind(-1);
344
345 /* is this ugly, I ask? */ 544 /* is this ugly, I ask? */
346 while (PL_scopestack_ix) 545 LEAVE_SCOPE (0);
347 LEAVE; 546
547 /* sure it is, but more important: is it correct?? :/ */
548 FREETMPS;
549
550 /*POPSTACK_TO (PL_mainstack);*//*D*//*use*/
551 }
348 552
349 while (PL_curstackinfo->si_next) 553 while (PL_curstackinfo->si_next)
350 PL_curstackinfo = PL_curstackinfo->si_next; 554 PL_curstackinfo = PL_curstackinfo->si_next;
351 555
352 while (PL_curstackinfo) 556 while (PL_curstackinfo)
353 { 557 {
354 PERL_SI *p = PL_curstackinfo->si_prev; 558 PERL_SI *p = PL_curstackinfo->si_prev;
355 559
560 { /*D*//*remove*/
561 dSP;
562 SWITCHSTACK (PL_curstack, PL_curstackinfo->si_stack);
563 PUTBACK; /* possibly superfluous */
564 }
565
566 if (!IN_DESTRUCT)
567 {
568 dounwind (-1);/*D*//*remove*/
356 SvREFCNT_dec(PL_curstackinfo->si_stack); 569 SvREFCNT_dec (PL_curstackinfo->si_stack);
570 }
571
357 Safefree(PL_curstackinfo->si_cxstack); 572 Safefree (PL_curstackinfo->si_cxstack);
358 Safefree(PL_curstackinfo); 573 Safefree (PL_curstackinfo);
359 PL_curstackinfo = p; 574 PL_curstackinfo = p;
360 } 575 }
361 576
362 if (PL_scopestack_ix != 0) 577 Safefree (PL_tmps_stack);
363 Perl_warner(aTHX_ WARN_INTERNAL, 578 Safefree (PL_markstack);
364 "Unbalanced scopes: %ld more ENTERs than LEAVEs\n", 579 Safefree (PL_scopestack);
365 (long)PL_scopestack_ix); 580 Safefree (PL_savestack);
366 if (PL_savestack_ix != 0) 581 Safefree (PL_retstack);
367 Perl_warner(aTHX_ WARN_INTERNAL, 582}
368 "Unbalanced saves: %ld more saves than restores\n", 583
369 (long)PL_savestack_ix); 584static void
370 if (PL_tmps_floor != -1) 585allocate_stack (Coro__State ctx, int alloc)
371 Perl_warner(aTHX_ WARN_INTERNAL,"Unbalanced tmps: %ld more allocs than frees\n", 586{
372 (long)PL_tmps_floor + 1); 587 coro_stack *stack;
588
589 New (0, stack, 1, coro_stack);
590
591 stack->refcnt = 1;
592 stack->usecnt = 1;
593 stack->gencnt = ctx->gencnt = 0;
594
595 if (alloc)
596 {
597#if HAVE_MMAP
598 stack->ssize = STACKSIZE * sizeof (long); /* mmap should do allocate-on-write for us */
599 stack->sptr = mmap (0, stack->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
600 if (stack->sptr == (void *)-1)
601#endif
602 {
603 /*FIXME*//*D*//* reasonable stack size! */
604 stack->ssize = - (STACKSIZE * sizeof (long));
605 New (0, stack->sptr, STACKSIZE, long);
606 }
607 }
608 else
609 stack->sptr = 0;
610
611 ctx->stack = stack;
612}
613
614static void
615deallocate_stack (Coro__State ctx)
616{
617 coro_stack *stack = ctx->stack;
618
619 ctx->stack = 0;
620
621 if (stack)
622 {
623 if (!--stack->refcnt)
624 {
625#ifdef HAVE_MMAP
626 if (stack->ssize > 0 && stack->sptr)
627 munmap (stack->sptr, stack->ssize);
628 else
629#endif
630 Safefree (stack->sptr);
631
632 Safefree (stack);
633 }
634 else if (ctx->gencnt == stack->gencnt)
635 --stack->usecnt;
636 }
637}
638
639static void
640setup_coro (void *arg)
641{
373 /* 642 /*
643 * emulate part of the perl startup here.
644 */
645 dTHX;
646 dSP;
647 Coro__State ctx = (Coro__State)arg;
648 SV *sub_init = (SV *)get_cv (SUB_INIT, FALSE);
649
650 coro_init_stacks (aTHX);
651 /*PL_curcop = 0;*/
652 /*PL_in_eval = PL_in_eval;*/ /* inherit */
653 SvREFCNT_dec (GvAV (PL_defgv));
654 GvAV (PL_defgv) = ctx->args; ctx->args = 0;
655
656 SPAGAIN;
657
658 if (ctx->stack)
659 {
660 ctx->cursp = 0;
661
662 PUSHMARK(SP);
663 PUTBACK;
664 (void) call_sv (sub_init, G_VOID|G_NOARGS|G_EVAL);
665
666 if (SvTRUE (ERRSV))
667 croak (NULL);
668 else
669 croak ("FATAL: CCTXT coroutine returned!");
670 }
671 else
672 {
673 UNOP myop;
674
675 PL_op = (OP *)&myop;
676
677 Zero(&myop, 1, UNOP);
678 myop.op_next = Nullop;
679 myop.op_flags = OPf_WANT_VOID;
680
681 PUSHMARK(SP);
682 XPUSHs (sub_init);
683 /*
684 * the next line is slightly wrong, as PL_op->op_next
685 * is actually being executed so we skip the first op.
686 * that doesn't matter, though, since it is only
687 * pp_nextstate and we never return...
688 * ah yes, and I don't care anyways ;)
689 */
690 PUTBACK;
691 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
692 SPAGAIN;
693
694 ENTER; /* necessary e.g. for dounwind */
695 }
696}
697
698static void
699continue_coro (void *arg)
700{
701 /*
702 * this is a _very_ stripped down perl interpreter ;)
703 */
704 dTHX;
705 Coro__State ctx = (Coro__State)arg;
706 JMPENV coro_start_env;
707
708 PL_top_env = &ctx->start_env;
709
710 ctx->cursp = 0;
711 PL_op = PL_op->op_next;
712 CALLRUNOPS(aTHX);
713
714 abort ();
715}
716
717STATIC void
718transfer (pTHX_ struct coro *prev, struct coro *next, int flags)
719{
720 dSTACKLEVEL;
721
722 if (prev != next)
723 {
724 if (next->mainstack)
725 {
726 LOCK;
727 SAVE (prev, flags);
728 LOAD (next);
729 UNLOCK;
730
731 /* mark this state as in-use */
732 next->mainstack = 0;
733 next->tmps_ix = -2;
734
735 /* stacklevel changed? if yes, grab the stack for us! */
736 if (flags & TRANSFER_SAVE_CCTXT)
737 {
738 if (!prev->stack)
739 allocate_stack (prev, 0);
740 else if (prev->cursp != stacklevel
741 && prev->stack->usecnt > 1)
374 */ 742 {
375 Safefree(PL_tmps_stack); 743 prev->gencnt = ++prev->stack->gencnt;
376 Safefree(PL_markstack); 744 prev->stack->usecnt = 1;
377 Safefree(PL_scopestack); 745 }
378 Safefree(PL_savestack);
379 Safefree(PL_retstack);
380}
381 746
382#define SUB_INIT "Coro::State::_newcoro" 747 /* has our stack been invalidated? */
748 if (next->stack && next->stack->gencnt != next->gencnt)
749 {
750 deallocate_stack (next);
751 allocate_stack (next, 1);
752 coro_create (&(next->stack->cctx),
753 continue_coro, (void *)next,
754 next->stack->sptr, labs (next->stack->ssize));
755 }
756
757 coro_transfer (&(prev->stack->cctx), &(next->stack->cctx));
758 prev->cursp = stacklevel;
759 /* don't add any code here */
760 }
761 else
762 next->cursp = stacklevel;
763 }
764 else if (next->tmps_ix == -2)
765 croak ("tried to transfer to running coroutine");
766 else
767 {
768 LOCK;
769 SAVE (prev, -1); /* first get rid of the old state */
770 UNLOCK;
771
772 if (flags & TRANSFER_SAVE_CCTXT)
773 {
774 if (!prev->stack)
775 allocate_stack (prev, 0);
776
777 if (prev->stack->sptr && flags & TRANSFER_LAZY_STACK)
778 {
779 PL_top_env = &next->start_env;
780
781 setup_coro (next);
782 next->cursp = stacklevel;
783
784 prev->stack->refcnt++;
785 prev->stack->usecnt++;
786 next->stack = prev->stack;
787 next->gencnt = prev->gencnt;
788 }
789 else
790 {
791 assert (!next->stack);
792 allocate_stack (next, 1);
793 coro_create (&(next->stack->cctx),
794 setup_coro, (void *)next,
795 next->stack->sptr, labs (next->stack->ssize));
796 coro_transfer (&(prev->stack->cctx), &(next->stack->cctx));
797 prev->cursp = stacklevel;
798 /* don't add any code here */
799 }
800 }
801 else
802 {
803 setup_coro (next);
804 next->cursp = stacklevel;
805 }
806 }
807 }
808
809 LOCK;
810 if (coro_mortal)
811 {
812 SvREFCNT_dec (coro_mortal);
813 coro_mortal = 0;
814 }
815 UNLOCK;
816}
817
818#define SV_CORO(sv,func) \
819 do { \
820 if (SvROK (sv)) \
821 sv = SvRV (sv); \
822 \
823 if (SvTYPE (sv) == SVt_PVHV) \
824 { \
825 HE *he = hv_fetch_ent ((HV *)sv, ucoro_state_sv, 0, ucoro_state_hash); \
826 \
827 if (!he) \
828 croak ("%s() -- %s is a hashref but lacks the " UCORO_STATE " key", func, # sv); \
829 \
830 (sv) = SvRV (HeVAL(he)); \
831 } \
832 \
833 /* must also be changed inside Coro::Cont::yield */ \
834 if (!SvOBJECT (sv) || SvSTASH (sv) != coro_state_stash) \
835 croak ("%s() -- %s is not (and contains not) a Coro::State object", func, # sv); \
836 \
837 } while(0)
838
839#define SvSTATE(sv) (struct coro *)SvIV (sv)
840
841static void
842api_transfer(pTHX_ SV *prev, SV *next, int flags)
843{
844 SV_CORO (prev, "Coro::transfer");
845 SV_CORO (next, "Coro::transfer");
846
847 transfer (aTHX_ SvSTATE (prev), SvSTATE (next), flags);
848}
849
850/** Coro ********************************************************************/
851
852#define PRIO_MAX 3
853#define PRIO_HIGH 1
854#define PRIO_NORMAL 0
855#define PRIO_LOW -1
856#define PRIO_IDLE -3
857#define PRIO_MIN -4
858
859/* for Coro.pm */
860static GV *coro_current, *coro_idle;
861static AV *coro_ready[PRIO_MAX-PRIO_MIN+1];
862static int coro_nready;
863
864static void
865coro_enq (pTHX_ SV *sv)
866{
867 if (SvTYPE (sv) == SVt_PVHV)
868 {
869 SV **xprio = hv_fetch ((HV *)sv, "prio", 4, 0);
870 int prio = xprio ? SvIV (*xprio) : PRIO_NORMAL;
871
872 prio = prio > PRIO_MAX ? PRIO_MAX
873 : prio < PRIO_MIN ? PRIO_MIN
874 : prio;
875
876 av_push (coro_ready [prio - PRIO_MIN], sv);
877 coro_nready++;
878
879 return;
880 }
881
882 croak ("Coro::ready tried to enqueue something that is not a coroutine");
883}
884
885static SV *
886coro_deq (pTHX_ int min_prio)
887{
888 int prio = PRIO_MAX - PRIO_MIN;
889
890 min_prio -= PRIO_MIN;
891 if (min_prio < 0)
892 min_prio = 0;
893
894 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; )
895 if (av_len (coro_ready[prio]) >= 0)
896 {
897 coro_nready--;
898 return av_shift (coro_ready[prio]);
899 }
900
901 return 0;
902}
903
904static void
905api_ready (SV *coro)
906{
907 dTHX;
908
909 if (SvROK (coro))
910 coro = SvRV (coro);
911
912 LOCK;
913 coro_enq (aTHX_ SvREFCNT_inc (coro));
914 UNLOCK;
915}
916
917static void
918api_schedule (void)
919{
920 dTHX;
921
922 SV *prev, *next;
923
924 LOCK;
925
926 prev = SvRV (GvSV (coro_current));
927 next = coro_deq (aTHX_ PRIO_MIN);
928
929 if (!next)
930 next = SvREFCNT_inc (SvRV (GvSV (coro_idle)));
931
932 /* free this only after the transfer */
933 coro_mortal = prev;
934 SV_CORO (prev, "Coro::schedule");
935
936 SvRV (GvSV (coro_current)) = next;
937
938 SV_CORO (next, "Coro::schedule");
939
940 UNLOCK;
941
942 transfer (aTHX_ SvSTATE (prev), SvSTATE (next),
943 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK);
944}
945
946static void
947api_cede (void)
948{
949 dTHX;
950
951 LOCK;
952 coro_enq (aTHX_ SvREFCNT_inc (SvRV (GvSV (coro_current))));
953 UNLOCK;
954
955 api_schedule ();
956}
383 957
384MODULE = Coro::State PACKAGE = Coro::State 958MODULE = Coro::State PACKAGE = Coro::State
385 959
386PROTOTYPES: ENABLE 960PROTOTYPES: ENABLE
387 961
388BOOT: 962BOOT:
389 if (!padlist_cache) 963{ /* {} necessary for stoopid perl-5.6.x */
390 padlist_cache = newHV (); 964#ifdef USE_ITHREADS
965 MUTEX_INIT (&coro_mutex);
966#endif
967
968 ucoro_state_sv = newSVpv (UCORO_STATE, sizeof(UCORO_STATE) - 1);
969 PERL_HASH(ucoro_state_hash, UCORO_STATE, sizeof(UCORO_STATE) - 1);
970 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
971
972 newCONSTSUB (coro_state_stash, "SAVE_DEFAV", newSViv (TRANSFER_SAVE_DEFAV));
973 newCONSTSUB (coro_state_stash, "SAVE_DEFSV", newSViv (TRANSFER_SAVE_DEFSV));
974 newCONSTSUB (coro_state_stash, "SAVE_ERRSV", newSViv (TRANSFER_SAVE_ERRSV));
975 newCONSTSUB (coro_state_stash, "SAVE_CCTXT", newSViv (TRANSFER_SAVE_CCTXT));
976
977 main_mainstack = PL_mainstack;
978
979 coroapi.ver = CORO_API_VERSION;
980 coroapi.transfer = api_transfer;
981}
391 982
392Coro::State 983Coro::State
393_newprocess(args) 984_newprocess(args)
394 SV * args 985 SV * args
395 PROTOTYPE: $ 986 PROTOTYPE: $
396 CODE: 987 CODE:
397 Coro__State coro; 988 Coro__State coro;
398 989
399 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) 990 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV)
400 croak ("Coro::State::newprocess expects an arrayref"); 991 croak ("Coro::State::_newprocess expects an arrayref");
401 992
402 New (0, coro, 1, struct coro); 993 Newz (0, coro, 1, struct coro);
403 994
404 coro->mainstack = 0; /* actual work is done inside transfer */
405 coro->args = (AV *)SvREFCNT_inc (SvRV (args)); 995 coro->args = (AV *)SvREFCNT_inc (SvRV (args));
996 /*coro->mainstack = 0; *//*actual work is done inside transfer */
997 /*coro->stack = 0;*/
998
999 /* same as JMPENV_BOOTSTRAP */
1000 /* we might be able to recycle start_env, but safe is safe */
1001 /*Zero(&coro->start_env, 1, JMPENV);*/
1002 coro->start_env.je_ret = -1;
1003 coro->start_env.je_mustcatch = TRUE;
406 1004
407 RETVAL = coro; 1005 RETVAL = coro;
408 OUTPUT: 1006 OUTPUT:
409 RETVAL 1007 RETVAL
410 1008
411void 1009void
412transfer(prev,next) 1010transfer(prev, next, flags)
413 Coro::State_or_hashref prev 1011 SV *prev
414 Coro::State_or_hashref next 1012 SV *next
1013 int flags
1014 PROTOTYPE: @
415 CODE: 1015 CODE:
416
417 if (prev != next)
418 {
419 PUTBACK; 1016 PUTBACK;
420 SAVE (aTHX_ prev); 1017 SV_CORO (next, "Coro::transfer");
421 1018 SV_CORO (prev, "Coro::transfer");
422 /* 1019 transfer (aTHX_ SvSTATE (prev), SvSTATE (next), flags);
423 * this could be done in newprocess which would lead to
424 * extremely elegant and fast (just PUTBACK/SAVE/LOAD/SPAGAIN)
425 * code here, but lazy allocation of stacks has also
426 * some virtues and the overhead of the if() is nil.
427 */
428 if (next->mainstack)
429 {
430 LOAD (aTHX_ next);
431 next->mainstack = 0; /* unnecessary but much cleaner */
432 SPAGAIN; 1020 SPAGAIN;
433 }
434 else
435 {
436 /*
437 * emulate part of the perl startup here.
438 */
439 UNOP myop;
440
441 init_stacks (); /* from perl.c */
442 PL_op = (OP *)&myop;
443 /*PL_curcop = 0;*/
444 GvAV (PL_defgv) = (SV *)SvREFCNT_inc (next->args);
445
446 SPAGAIN;
447 Zero(&myop, 1, UNOP);
448 myop.op_next = Nullop;
449 myop.op_flags = OPf_WANT_VOID;
450
451 PUSHMARK(SP);
452 XPUSHs ((SV*)get_cv(SUB_INIT, TRUE));
453 PUTBACK;
454 /*
455 * the next line is slightly wrong, as PL_op->op_next
456 * is actually being executed so we skip the first op.
457 * that doesn't matter, though, since it is only
458 * pp_nextstate and we never return...
459 */
460 PL_op = Perl_pp_entersub(aTHX);
461 SPAGAIN;
462
463 ENTER;
464 }
465 }
466 1021
467void 1022void
468DESTROY(coro) 1023DESTROY(coro)
469 Coro::State coro 1024 Coro::State coro
470 CODE: 1025 CODE:
471 1026
472 if (coro->mainstack) 1027 if (coro->mainstack && coro->mainstack != main_mainstack)
473 { 1028 {
474 struct coro temp; 1029 struct coro temp;
475 1030
476 PUTBACK; 1031 PUTBACK;
477 SAVE(aTHX_ (&temp)); 1032 SAVE (aTHX_ (&temp), TRANSFER_SAVE_ALL);
478 LOAD(aTHX_ coro); 1033 LOAD (aTHX_ coro);
479
480 destroy_stacks ();
481 SvREFCNT_dec ((SV *)GvAV (PL_defgv));
482
483 LOAD((&temp));
484 SPAGAIN; 1034 SPAGAIN;
1035
1036 destroy_stacks (aTHX);
1037
1038 LOAD ((&temp)); /* this will get rid of defsv etc.. */
1039 SPAGAIN;
1040
1041 coro->mainstack = 0;
485 } 1042 }
486 1043
1044 deallocate_stack (coro);
487 SvREFCNT_dec (coro->args); 1045 SvREFCNT_dec (coro->args);
488 Safefree (coro); 1046 Safefree (coro);
489 1047
1048void
1049_exit(code)
1050 int code
1051 PROTOTYPE: $
1052 CODE:
1053 _exit (code);
490 1054
1055MODULE = Coro::State PACKAGE = Coro::Cont
1056
1057# this is slightly dirty (should expose a c-level api)
1058
1059void
1060yield(...)
1061 PROTOTYPE: @
1062 CODE:
1063 SV *yieldstack;
1064 SV *sv;
1065 AV *defav = GvAV (PL_defgv);
1066 struct coro *prev, *next;
1067
1068 yieldstack = *hv_fetch (
1069 (HV *)SvRV (GvSV (coro_current)),
1070 "yieldstack", sizeof ("yieldstack") - 1,
1071 0
1072 );
1073
1074 /* set up @_ -- ugly */
1075 av_clear (defav);
1076 av_fill (defav, items - 1);
1077 while (items--)
1078 av_store (defav, items, SvREFCNT_inc (ST(items)));
1079
1080 sv = av_pop ((AV *)SvRV (yieldstack));
1081 prev = (struct coro *)SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 0, 0)));
1082 next = (struct coro *)SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 1, 0)));
1083 SvREFCNT_dec (sv);
1084
1085 transfer (aTHX_ prev, next, 0);
1086
1087MODULE = Coro::State PACKAGE = Coro
1088
1089# this is slightly dirty (should expose a c-level api)
1090
1091BOOT:
1092{
1093 int i;
1094 HV *stash = gv_stashpv ("Coro", TRUE);
1095
1096 newCONSTSUB (stash, "PRIO_MAX", newSViv (PRIO_MAX));
1097 newCONSTSUB (stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
1098 newCONSTSUB (stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
1099 newCONSTSUB (stash, "PRIO_LOW", newSViv (PRIO_LOW));
1100 newCONSTSUB (stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
1101 newCONSTSUB (stash, "PRIO_MIN", newSViv (PRIO_MIN));
1102
1103 coro_current = gv_fetchpv ("Coro::current", TRUE, SVt_PV);
1104 coro_idle = gv_fetchpv ("Coro::idle" , TRUE, SVt_PV);
1105
1106 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
1107 coro_ready[i] = newAV ();
1108
1109 {
1110 SV *sv = perl_get_sv("Coro::API", 1);
1111
1112 coroapi.schedule = api_schedule;
1113 coroapi.cede = api_cede;
1114 coroapi.ready = api_ready;
1115 coroapi.nready = &coro_nready;
1116 coroapi.current = coro_current;
1117
1118 GCoroAPI = &coroapi;
1119 sv_setiv(sv, (IV)&coroapi);
1120 SvREADONLY_on(sv);
1121 }
1122}
1123
1124#if !PERL_MICRO
1125
1126void
1127ready(self)
1128 SV * self
1129 PROTOTYPE: $
1130 CODE:
1131 api_ready (self);
1132
1133#endif
1134
1135int
1136nready(...)
1137 PROTOTYPE:
1138 CODE:
1139 RETVAL = coro_nready;
1140 OUTPUT:
1141 RETVAL
1142
1143void
1144schedule(...)
1145 PROTOTYPE:
1146 CODE:
1147 api_schedule ();
1148
1149void
1150cede(...)
1151 PROTOTYPE:
1152 CODE:
1153 api_cede ();
1154

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines