ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
Revision: 1.99
Committed: Sun Nov 26 23:53:20 2006 UTC (17 years, 5 months ago) by root
Branch: MAIN
Changes since 1.98: +24 -22 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.63 #include "libcoro/coro.c"
2    
3 root 1.1 #include "EXTERN.h"
4     #include "perl.h"
5     #include "XSUB.h"
6    
7 pcg 1.46 #include "patchlevel.h"
8    
9 root 1.65 #if PERL_VERSION < 6
10 pcg 1.46 # ifndef PL_ppaddr
11     # define PL_ppaddr ppaddr
12     # endif
13     # ifndef call_sv
14     # define call_sv perl_call_sv
15     # endif
16     # ifndef get_sv
17     # define get_sv perl_get_sv
18     # endif
19     # ifndef get_cv
20     # define get_cv perl_get_cv
21     # endif
22     # ifndef IS_PADGV
23     # define IS_PADGV(v) 0
24     # endif
25     # ifndef IS_PADCONST
26     # define IS_PADCONST(v) 0
27     # endif
28     #endif
29    
30 root 1.92 #include <stdio.h>
31 root 1.70 #include <errno.h>
32 root 1.20
33 root 1.78 #if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
34     # undef STACKGUARD
35     #endif
36    
37     #ifndef STACKGUARD
38     # define STACKGUARD 0
39     #endif
40    
41 root 1.13 #ifdef HAVE_MMAP
42     # include <unistd.h>
43     # include <sys/mman.h>
44 root 1.36 # ifndef MAP_ANONYMOUS
45     # ifdef MAP_ANON
46     # define MAP_ANONYMOUS MAP_ANON
47 root 1.16 # else
48     # undef HAVE_MMAP
49     # endif
50     # endif
51 root 1.78 # include <limits.h>
52     # ifndef PAGESIZE
53     # define PAGESIZE pagesize
54     # define BOOT_PAGESIZE pagesize = sysconf (_SC_PAGESIZE)
55     static long pagesize;
56     # else
57     # define BOOT_PAGESIZE
58     # endif
59 root 1.3 #endif
60    
61 root 1.28 /* The next macro should declare a variable stacklevel that contains and approximation
62 root 1.23 * to the current C stack pointer. Its property is that it changes with each call
63 root 1.15 * and should be unique. */
64 root 1.92 #define dSTACKLEVEL int stacklevel
65     #define STACKLEVEL ((void *)&stacklevel)
66 root 1.15
67 root 1.34 #define IN_DESTRUCT (PL_main_cv == Nullcv)
68    
69 root 1.23 #include "CoroAPI.h"
70    
71 root 1.92 #define TRANSFER_SET_STACKLEVEL 0x8bfbfbfb /* magic cookie */
72    
73 pcg 1.55 #ifdef USE_ITHREADS
74     static perl_mutex coro_mutex;
75 root 1.69 # define LOCK do { MUTEX_LOCK (&coro_mutex); } while (0)
76 pcg 1.55 # define UNLOCK do { MUTEX_UNLOCK (&coro_mutex); } while (0)
77     #else
78 root 1.69 # define LOCK (void)0
79     # define UNLOCK (void)0
80 pcg 1.55 #endif
81    
82 root 1.23 static struct CoroAPI coroapi;
83 pcg 1.56 static AV *main_mainstack; /* used to differentiate between $main and others */
84 root 1.88 static HV *coro_state_stash, *coro_stash;
85 pcg 1.58 static SV *coro_mortal; /* will be freed after next transfer */
86 root 1.23
87 root 1.92 /* this is a structure representing a c-level coroutine */
88 root 1.89 typedef struct coro_stack {
89     struct coro_stack *next;
90 root 1.15
91 root 1.93 /* the stack */
92 root 1.15 void *sptr;
93     long ssize; /* positive == mmap, otherwise malloc */
94 root 1.89
95     /* cpu state */
96 root 1.96 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
97 root 1.93 JMPENV *top_env;
98 root 1.89 coro_context cctx;
99 root 1.15 } coro_stack;
100    
101 root 1.92 /* this is a structure representing a perl-level coroutine */
102 root 1.1 struct coro {
103 root 1.92 /* the c coroutine allocated to this perl coroutine, if any */
104     coro_stack *stack;
105    
106     /* data associated with this coroutine (initial args) */
107     AV *args;
108     int refcnt;
109    
110 root 1.7 /* optionally saved, might be zero */
111 root 1.3 AV *defav;
112 root 1.7 SV *defsv;
113     SV *errsv;
114 root 1.1
115 root 1.7 /* saved global state not related to stacks */
116     U8 dowarn;
117 root 1.19 I32 in_eval;
118 root 1.7
119     /* the stacks and related info (callchain etc..) */
120 root 1.1 PERL_SI *curstackinfo;
121     AV *curstack;
122     AV *mainstack;
123     SV **stack_sp;
124     OP *op;
125     SV **curpad;
126 root 1.44 AV *comppad;
127 root 1.62 CV *compcv;
128 root 1.1 SV **stack_base;
129     SV **stack_max;
130     SV **tmps_stack;
131     I32 tmps_floor;
132     I32 tmps_ix;
133     I32 tmps_max;
134     I32 *markstack;
135     I32 *markstack_ptr;
136     I32 *markstack_max;
137     I32 *scopestack;
138     I32 scopestack_ix;
139     I32 scopestack_max;
140     ANY *savestack;
141     I32 savestack_ix;
142     I32 savestack_max;
143     OP **retstack;
144     I32 retstack_ix;
145     I32 retstack_max;
146 root 1.66 PMOP *curpm;
147 root 1.1 COP *curcop;
148    
149 root 1.87 /* coro process data */
150     int prio;
151 root 1.1 };
152    
153     typedef struct coro *Coro__State;
154     typedef struct coro *Coro__State_or_hashref;
155    
156 root 1.77 static AV *
157 root 1.98 coro_clone_padlist (CV *cv)
158 root 1.77 {
159     AV *padlist = CvPADLIST (cv);
160     AV *newpadlist, *newpad;
161 root 1.3
162     newpadlist = newAV ();
163     AvREAL_off (newpadlist);
164 root 1.79 #if PERL_VERSION < 9
165 root 1.77 Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1, 1);
166 root 1.79 #else
167     Perl_pad_push (aTHX_ padlist, AvFILLp (padlist) + 1);
168     #endif
169 root 1.77 newpad = (AV *)AvARRAY (padlist)[AvFILLp (padlist)];
170     --AvFILLp (padlist);
171 root 1.3
172 root 1.77 av_store (newpadlist, 0, SvREFCNT_inc (*av_fetch (padlist, 0, FALSE)));
173     av_store (newpadlist, 1, (SV *)newpad);
174 root 1.3
175     return newpadlist;
176     }
177    
178 root 1.77 static void
179 root 1.98 free_padlist (AV *padlist)
180 root 1.3 {
181     /* may be during global destruction */
182 pcg 1.50 if (SvREFCNT (padlist))
183 root 1.3 {
184 pcg 1.50 I32 i = AvFILLp (padlist);
185 root 1.3 while (i >= 0)
186     {
187 pcg 1.50 SV **svp = av_fetch (padlist, i--, FALSE);
188     if (svp)
189     {
190     SV *sv;
191     while (&PL_sv_undef != (sv = av_pop ((AV *)*svp)))
192     SvREFCNT_dec (sv);
193    
194     SvREFCNT_dec (*svp);
195     }
196 root 1.3 }
197    
198 pcg 1.50 SvREFCNT_dec ((SV*)padlist);
199     }
200     }
201    
202 root 1.77 static int
203 pcg 1.54 coro_cv_free (pTHX_ SV *sv, MAGIC *mg)
204 pcg 1.50 {
205     AV *padlist;
206     AV *av = (AV *)mg->mg_obj;
207    
208     /* casting is fun. */
209     while (&PL_sv_undef != (SV *)(padlist = (AV *)av_pop (av)))
210 root 1.98 free_padlist (padlist);
211 root 1.61
212     SvREFCNT_dec (av);
213 root 1.76
214     return 0;
215 root 1.3 }
216 pcg 1.50
217     #define PERL_MAGIC_coro PERL_MAGIC_ext
218    
219     static MGVTBL vtbl_coro = {0, 0, 0, 0, coro_cv_free};
220 root 1.3
221 root 1.7 /* the next two functions merely cache the padlists */
222 root 1.77 static void
223 root 1.98 get_padlist (CV *cv)
224 root 1.3 {
225 pcg 1.50 MAGIC *mg = mg_find ((SV *)cv, PERL_MAGIC_coro);
226 root 1.4
227 pcg 1.50 if (mg && AvFILLp ((AV *)mg->mg_obj) >= 0)
228     CvPADLIST (cv) = (AV *)av_pop ((AV *)mg->mg_obj);
229 root 1.4 else
230 root 1.77 {
231     #if 0
232 root 1.96 /* this is probably cleaner, but also slower? */
233 root 1.98 CV *cp = Perl_cv_clone (cv);
234 root 1.77 CvPADLIST (cv) = CvPADLIST (cp);
235     CvPADLIST (cp) = 0;
236     SvREFCNT_dec (cp);
237     #else
238 root 1.98 CvPADLIST (cv) = coro_clone_padlist (cv);
239 root 1.77 #endif
240     }
241 root 1.4 }
242    
243 root 1.77 static void
244 root 1.98 put_padlist (CV *cv)
245 root 1.4 {
246 pcg 1.50 MAGIC *mg = mg_find ((SV *)cv, PERL_MAGIC_coro);
247 root 1.7
248 pcg 1.50 if (!mg)
249 root 1.7 {
250 pcg 1.50 sv_magic ((SV *)cv, 0, PERL_MAGIC_coro, 0, 0);
251     mg = mg_find ((SV *)cv, PERL_MAGIC_coro);
252     mg->mg_virtual = &vtbl_coro;
253     mg->mg_obj = (SV *)newAV ();
254 root 1.7 }
255    
256 pcg 1.50 av_push ((AV *)mg->mg_obj, (SV *)CvPADLIST (cv));
257 root 1.7 }
258    
259     #define SB do {
260     #define SE } while (0)
261    
262 root 1.98 #define LOAD(state) load_state((state));
263     #define SAVE(state,flags) save_state((state),(flags));
264 root 1.7
265 pcg 1.47 #define REPLACE_SV(sv,val) SB SvREFCNT_dec(sv); (sv) = (val); (val) = 0; SE
266 root 1.7
267     static void
268 root 1.98 load_state(Coro__State c)
269 root 1.7 {
270     PL_dowarn = c->dowarn;
271 root 1.19 PL_in_eval = c->in_eval;
272 root 1.7
273     PL_curstackinfo = c->curstackinfo;
274     PL_curstack = c->curstack;
275     PL_mainstack = c->mainstack;
276     PL_stack_sp = c->stack_sp;
277     PL_op = c->op;
278     PL_curpad = c->curpad;
279 root 1.44 PL_comppad = c->comppad;
280 root 1.62 PL_compcv = c->compcv;
281 root 1.7 PL_stack_base = c->stack_base;
282     PL_stack_max = c->stack_max;
283     PL_tmps_stack = c->tmps_stack;
284     PL_tmps_floor = c->tmps_floor;
285     PL_tmps_ix = c->tmps_ix;
286     PL_tmps_max = c->tmps_max;
287     PL_markstack = c->markstack;
288     PL_markstack_ptr = c->markstack_ptr;
289     PL_markstack_max = c->markstack_max;
290     PL_scopestack = c->scopestack;
291     PL_scopestack_ix = c->scopestack_ix;
292     PL_scopestack_max = c->scopestack_max;
293     PL_savestack = c->savestack;
294     PL_savestack_ix = c->savestack_ix;
295     PL_savestack_max = c->savestack_max;
296 root 1.72 #if PERL_VERSION < 9
297 root 1.7 PL_retstack = c->retstack;
298     PL_retstack_ix = c->retstack_ix;
299     PL_retstack_max = c->retstack_max;
300 root 1.71 #endif
301 root 1.66 PL_curpm = c->curpm;
302 root 1.7 PL_curcop = c->curcop;
303    
304     if (c->defav) REPLACE_SV (GvAV (PL_defgv), c->defav);
305     if (c->defsv) REPLACE_SV (DEFSV , c->defsv);
306     if (c->errsv) REPLACE_SV (ERRSV , c->errsv);
307    
308     {
309     dSP;
310     CV *cv;
311    
312     /* now do the ugly restore mess */
313     while ((cv = (CV *)POPs))
314     {
315     AV *padlist = (AV *)POPs;
316    
317     if (padlist)
318     {
319 root 1.98 put_padlist (cv); /* mark this padlist as available */
320 root 1.7 CvPADLIST(cv) = padlist;
321     }
322    
323     ++CvDEPTH(cv);
324     }
325    
326     PUTBACK;
327     }
328     }
329    
330 root 1.3 static void
331 root 1.98 save_state(Coro__State c, int flags)
332 root 1.3 {
333     {
334     dSP;
335     I32 cxix = cxstack_ix;
336 root 1.11 PERL_CONTEXT *ccstk = cxstack;
337 root 1.3 PERL_SI *top_si = PL_curstackinfo;
338    
339     /*
340     * the worst thing you can imagine happens first - we have to save
341     * (and reinitialize) all cv's in the whole callchain :(
342     */
343    
344     PUSHs (Nullsv);
345     /* this loop was inspired by pp_caller */
346     for (;;)
347     {
348 root 1.30 while (cxix >= 0)
349 root 1.3 {
350 root 1.4 PERL_CONTEXT *cx = &ccstk[cxix--];
351 root 1.3
352     if (CxTYPE(cx) == CXt_SUB)
353     {
354     CV *cv = cx->blk_sub.cv;
355     if (CvDEPTH(cv))
356     {
357 root 1.7 EXTEND (SP, CvDEPTH(cv)*2);
358    
359     while (--CvDEPTH(cv))
360     {
361     /* this tells the restore code to increment CvDEPTH */
362     PUSHs (Nullsv);
363     PUSHs ((SV *)cv);
364     }
365    
366 root 1.3 PUSHs ((SV *)CvPADLIST(cv));
367     PUSHs ((SV *)cv);
368    
369 root 1.98 get_padlist (cv);
370 root 1.3 }
371     }
372 pcg 1.46 #ifdef CXt_FORMAT
373 root 1.3 else if (CxTYPE(cx) == CXt_FORMAT)
374     {
375     /* I never used formats, so how should I know how these are implemented? */
376     /* my bold guess is as a simple, plain sub... */
377     croak ("CXt_FORMAT not yet handled. Don't switch coroutines from within formats");
378     }
379 pcg 1.46 #endif
380 root 1.3 }
381    
382     if (top_si->si_type == PERLSI_MAIN)
383     break;
384    
385     top_si = top_si->si_prev;
386     ccstk = top_si->si_cxstack;
387     cxix = top_si->si_cxix;
388     }
389    
390     PUTBACK;
391     }
392    
393 root 1.12 c->defav = flags & TRANSFER_SAVE_DEFAV ? (AV *)SvREFCNT_inc (GvAV (PL_defgv)) : 0;
394     c->defsv = flags & TRANSFER_SAVE_DEFSV ? SvREFCNT_inc (DEFSV) : 0;
395     c->errsv = flags & TRANSFER_SAVE_ERRSV ? SvREFCNT_inc (ERRSV) : 0;
396 root 1.7
397 root 1.3 c->dowarn = PL_dowarn;
398 root 1.19 c->in_eval = PL_in_eval;
399 root 1.7
400 root 1.3 c->curstackinfo = PL_curstackinfo;
401     c->curstack = PL_curstack;
402     c->mainstack = PL_mainstack;
403     c->stack_sp = PL_stack_sp;
404     c->op = PL_op;
405     c->curpad = PL_curpad;
406 root 1.44 c->comppad = PL_comppad;
407 root 1.62 c->compcv = PL_compcv;
408 root 1.3 c->stack_base = PL_stack_base;
409     c->stack_max = PL_stack_max;
410     c->tmps_stack = PL_tmps_stack;
411     c->tmps_floor = PL_tmps_floor;
412     c->tmps_ix = PL_tmps_ix;
413     c->tmps_max = PL_tmps_max;
414     c->markstack = PL_markstack;
415     c->markstack_ptr = PL_markstack_ptr;
416     c->markstack_max = PL_markstack_max;
417     c->scopestack = PL_scopestack;
418     c->scopestack_ix = PL_scopestack_ix;
419     c->scopestack_max = PL_scopestack_max;
420     c->savestack = PL_savestack;
421     c->savestack_ix = PL_savestack_ix;
422     c->savestack_max = PL_savestack_max;
423 root 1.72 #if PERL_VERSION < 9
424 root 1.3 c->retstack = PL_retstack;
425     c->retstack_ix = PL_retstack_ix;
426     c->retstack_max = PL_retstack_max;
427 root 1.71 #endif
428 root 1.66 c->curpm = PL_curpm;
429 root 1.3 c->curcop = PL_curcop;
430 root 1.13 }
431    
432     /*
433     * allocate various perl stacks. This is an exact copy
434     * of perl.c:init_stacks, except that it uses less memory
435 pcg 1.52 * on the (sometimes correct) assumption that coroutines do
436     * not usually need a lot of stackspace.
437 root 1.13 */
438 root 1.77 static void
439 root 1.98 coro_init_stacks ()
440 root 1.13 {
441     PL_curstackinfo = new_stackinfo(96, 1024/sizeof(PERL_CONTEXT) - 1);
442     PL_curstackinfo->si_type = PERLSI_MAIN;
443     PL_curstack = PL_curstackinfo->si_stack;
444     PL_mainstack = PL_curstack; /* remember in case we switch stacks */
445    
446     PL_stack_base = AvARRAY(PL_curstack);
447     PL_stack_sp = PL_stack_base;
448     PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
449    
450 root 1.15 New(50,PL_tmps_stack,96,SV*);
451 root 1.13 PL_tmps_floor = -1;
452     PL_tmps_ix = -1;
453 root 1.15 PL_tmps_max = 96;
454 root 1.13
455 root 1.15 New(54,PL_markstack,16,I32);
456 root 1.13 PL_markstack_ptr = PL_markstack;
457 root 1.15 PL_markstack_max = PL_markstack + 16;
458 root 1.13
459 pcg 1.46 #ifdef SET_MARK_OFFSET
460 root 1.13 SET_MARK_OFFSET;
461 pcg 1.46 #endif
462 root 1.13
463 root 1.15 New(54,PL_scopestack,16,I32);
464 root 1.13 PL_scopestack_ix = 0;
465 root 1.15 PL_scopestack_max = 16;
466 root 1.13
467 root 1.15 New(54,PL_savestack,96,ANY);
468 root 1.13 PL_savestack_ix = 0;
469 root 1.15 PL_savestack_max = 96;
470 root 1.13
471 root 1.72 #if PERL_VERSION < 9
472 root 1.13 New(54,PL_retstack,8,OP*);
473     PL_retstack_ix = 0;
474     PL_retstack_max = 8;
475 root 1.71 #endif
476 root 1.3 }
477 root 1.1
478 root 1.7 /*
479     * destroy the stacks, the callchain etc...
480     */
481 root 1.77 static void
482 root 1.98 destroy_stacks()
483 root 1.1 {
484 root 1.34 if (!IN_DESTRUCT)
485 root 1.31 {
486     /* is this ugly, I ask? */
487 pcg 1.52 LEAVE_SCOPE (0);
488 root 1.31
489     /* sure it is, but more important: is it correct?? :/ */
490 pcg 1.52 FREETMPS;
491 pcg 1.57
492     /*POPSTACK_TO (PL_mainstack);*//*D*//*use*/
493 root 1.31 }
494 root 1.7
495 root 1.4 while (PL_curstackinfo->si_next)
496     PL_curstackinfo = PL_curstackinfo->si_next;
497    
498     while (PL_curstackinfo)
499     {
500     PERL_SI *p = PL_curstackinfo->si_prev;
501    
502 pcg 1.57 { /*D*//*remove*/
503 root 1.7 dSP;
504     SWITCHSTACK (PL_curstack, PL_curstackinfo->si_stack);
505     PUTBACK; /* possibly superfluous */
506     }
507    
508 root 1.34 if (!IN_DESTRUCT)
509 root 1.31 {
510 pcg 1.57 dounwind (-1);/*D*//*remove*/
511     SvREFCNT_dec (PL_curstackinfo->si_stack);
512 root 1.31 }
513 root 1.7
514 pcg 1.57 Safefree (PL_curstackinfo->si_cxstack);
515     Safefree (PL_curstackinfo);
516 root 1.4 PL_curstackinfo = p;
517     }
518    
519 pcg 1.57 Safefree (PL_tmps_stack);
520     Safefree (PL_markstack);
521     Safefree (PL_scopestack);
522     Safefree (PL_savestack);
523 root 1.72 #if PERL_VERSION < 9
524 pcg 1.57 Safefree (PL_retstack);
525 root 1.71 #endif
526 root 1.1 }
527    
528 root 1.13 static void
529 root 1.89 setup_coro (struct coro *coro)
530 root 1.13 {
531 root 1.89 /*
532     * emulate part of the perl startup here.
533     */
534     dTHX;
535     dSP;
536     UNOP myop;
537 root 1.92 SV *sub_init = (SV *)get_cv ("Coro::State::coro_init", FALSE);
538 root 1.15
539 root 1.98 coro_init_stacks ();
540 root 1.89 /*PL_curcop = 0;*/
541     /*PL_in_eval = PL_in_eval;*/ /* inherit */
542     SvREFCNT_dec (GvAV (PL_defgv));
543     GvAV (PL_defgv) = coro->args; coro->args = 0;
544 root 1.15
545 root 1.89 SPAGAIN;
546 pcg 1.55
547 root 1.89 Zero (&myop, 1, UNOP);
548     myop.op_next = Nullop;
549     myop.op_flags = OPf_WANT_VOID;
550    
551     PL_op = (OP *)&myop;
552    
553     PUSHMARK(SP);
554     XPUSHs (sub_init);
555     PUTBACK;
556     PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
557     SPAGAIN;
558 root 1.15
559 root 1.89 ENTER; /* necessary e.g. for dounwind */
560 root 1.13 }
561    
562     static void
563 root 1.92 free_coro_mortal ()
564 root 1.13 {
565 root 1.89 if (coro_mortal)
566 root 1.15 {
567 root 1.89 SvREFCNT_dec (coro_mortal);
568     coro_mortal = 0;
569     }
570 root 1.13 }
571    
572     static void
573 root 1.99 prepare_cctx (coro_stack *cctx)
574     {
575     dSP;
576     UNOP myop;
577    
578     Zero (&myop, 1, UNOP);
579     myop.op_next = PL_op;
580     myop.op_flags = OPf_WANT_VOID | OPf_STACKED;
581    
582     PUSHMARK(SP);
583     EXTEND (SP, 2);
584     PUSHs (newSViv (PTR2IV (cctx)));
585     PUSHs ((SV *)get_cv ("Coro::State::cctx_init", FALSE));
586     PUTBACK;
587     PL_restartop = PL_ppaddr[OP_ENTERSUB](aTHX);
588     SPAGAIN;
589     }
590    
591     static void
592 root 1.89 coro_run (void *arg)
593 root 1.13 {
594     /*
595 root 1.89 * this is a _very_ stripped down perl interpreter ;)
596 root 1.13 */
597 root 1.92 UNLOCK;
598 root 1.13
599 root 1.93 PL_top_env = &PL_start_env;
600 root 1.99 prepare_cctx ((coro_stack *)arg);
601 root 1.89
602 root 1.94 /* somebody will hit me for both perl_run and PL_restartop */
603 root 1.99 perl_run (PERL_GET_CONTEXT);
604 root 1.89
605 root 1.94 fputs ("FATAL: C coroutine fell over the edge of the world, aborting.\n", stderr);
606 root 1.89 abort ();
607     }
608    
609     static coro_stack *
610     stack_new ()
611     {
612     coro_stack *stack;
613    
614     New (0, stack, 1, coro_stack);
615    
616     #if HAVE_MMAP
617 root 1.13
618 root 1.94 stack->ssize = ((STACKSIZE * sizeof (long) + PAGESIZE - 1) / PAGESIZE + STACKGUARD) * PAGESIZE;
619     /* mmap suppsedly does allocate-on-write for us */
620 root 1.89 stack->sptr = mmap (0, stack->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
621 root 1.19
622 root 1.89 if (stack->sptr == (void *)-1)
623 root 1.13 {
624 root 1.92 perror ("FATAL: unable to mmap stack for coroutine");
625 root 1.89 _exit (EXIT_FAILURE);
626     }
627 root 1.15
628 root 1.94 # if STACKGUARD
629 root 1.89 mprotect (stack->sptr, STACKGUARD * PAGESIZE, PROT_NONE);
630 root 1.94 # endif
631 root 1.19
632 root 1.89 #else
633    
634     stack->ssize = STACKSIZE * (long)sizeof (long);
635     New (0, stack->sptr, STACKSIZE, long);
636    
637     if (!stack->sptr)
638     {
639 root 1.92 perror (stderr, "FATAL: unable to malloc stack for coroutine");
640 root 1.89 _exit (EXIT_FAILURE);
641 root 1.13 }
642    
643 root 1.89 #endif
644    
645 root 1.92 coro_create (&stack->cctx, coro_run, (void *)stack, stack->sptr, stack->ssize);
646 root 1.13
647 root 1.89 return stack;
648 root 1.13 }
649    
650 root 1.15 static void
651 root 1.89 stack_free (coro_stack *stack)
652 root 1.15 {
653 root 1.95 if (!stack)
654 root 1.89 return;
655    
656     #if HAVE_MMAP
657     munmap (stack->sptr, stack->ssize);
658     #else
659     Safefree (stack->sptr);
660     #endif
661    
662     Safefree (stack);
663     }
664 root 1.32
665 root 1.89 static coro_stack *stack_first;
666 root 1.15
667 root 1.91 static coro_stack *
668     stack_get ()
669 root 1.89 {
670 root 1.91 coro_stack *stack;
671    
672 root 1.89 if (stack_first)
673     {
674 root 1.91 stack = stack_first;
675     stack_first = stack->next;
676 root 1.89 }
677     else
678 root 1.91 {
679     stack = stack_new ();
680     PL_op = PL_op->op_next;
681     }
682    
683     return stack;
684 root 1.89 }
685 root 1.19
686 root 1.89 static void
687     stack_put (coro_stack *stack)
688     {
689     stack->next = stack_first;
690     stack_first = stack;
691 root 1.15 }
692    
693 root 1.84 /* never call directly, always through the coro_state_transfer global variable */
694 root 1.77 static void
695 root 1.98 transfer_impl (struct coro *prev, struct coro *next, int flags)
696 root 1.8 {
697 root 1.15 dSTACKLEVEL;
698 root 1.8
699 root 1.89 /* sometimes transfer is only called to set idle_sp */
700 root 1.92 if (flags == TRANSFER_SET_STACKLEVEL)
701     ((coro_stack *)prev)->idle_sp = STACKLEVEL;
702     else if (prev != next)
703 root 1.8 {
704 root 1.92 coro_stack *prev__stack;
705 root 1.89
706 root 1.92 LOCK;
707 root 1.13
708 root 1.90 if (next->mainstack)
709 root 1.89 {
710 root 1.90 /* coroutine already started */
711     SAVE (prev, flags);
712     LOAD (next);
713     }
714     else
715     {
716     /* need to start coroutine */
717 root 1.89 /* first get rid of the old state */
718     SAVE (prev, -1);
719     /* setup coroutine call */
720     setup_coro (next);
721 root 1.92 /* need a stack */
722 root 1.89 next->stack = 0;
723 root 1.8 }
724 root 1.15
725 root 1.95 if (!prev->stack)
726     /* create a new empty context */
727     Newz (0, prev->stack, 1, coro_stack);
728    
729 root 1.92 prev__stack = prev->stack;
730    
731     /* possibly "free" the stack */
732     if (prev__stack->idle_sp == STACKLEVEL)
733     {
734     stack_put (prev__stack);
735     prev->stack = 0;
736     }
737    
738 root 1.89 if (!next->stack)
739 root 1.91 next->stack = stack_get ();
740 root 1.81
741 root 1.92 if (prev__stack != next->stack)
742     {
743     prev__stack->top_env = PL_top_env;
744     PL_top_env = next->stack->top_env;
745     coro_transfer (&prev__stack->cctx, &next->stack->cctx);
746     }
747    
748     free_coro_mortal ();
749    
750     UNLOCK;
751 root 1.8 }
752 root 1.39 }
753 root 1.23
754 root 1.85 /* use this function pointer to call the above function */
755     /* this is done to increase chances of the compiler not inlining the call */
756 root 1.92 /* not static to make it even harder for the compiler (and theoretically impossible in most cases */
757 root 1.98 void (*coro_state_transfer)(struct coro *prev, struct coro *next, int flags) = transfer_impl;
758 root 1.84
759 root 1.92 struct transfer_args
760     {
761     struct coro *prev, *next;
762     int flags;
763     };
764    
765     #define TRANSFER(ta) coro_state_transfer ((ta).prev, (ta).next, (ta).flags)
766    
767 root 1.87 static void
768     coro_state_destroy (struct coro *coro)
769     {
770     if (coro->refcnt--)
771     return;
772    
773     if (coro->mainstack && coro->mainstack != main_mainstack)
774     {
775     struct coro temp;
776    
777 root 1.98 SAVE ((&temp), TRANSFER_SAVE_ALL);
778     LOAD (coro);
779 root 1.87
780 root 1.98 destroy_stacks ();
781 root 1.87
782     LOAD ((&temp)); /* this will get rid of defsv etc.. */
783    
784     coro->mainstack = 0;
785     }
786    
787 root 1.89 stack_free (coro->stack);
788 root 1.87 SvREFCNT_dec (coro->args);
789     Safefree (coro);
790     }
791    
792     static int
793 root 1.98 coro_state_clear (pTHX_ SV *sv, MAGIC *mg)
794 root 1.87 {
795     struct coro *coro = (struct coro *)mg->mg_ptr;
796     mg->mg_ptr = 0;
797    
798     coro_state_destroy (coro);
799    
800     return 0;
801     }
802    
803     static int
804 root 1.98 coro_state_dup (pTHX_ MAGIC *mg, CLONE_PARAMS *params)
805 root 1.87 {
806     struct coro *coro = (struct coro *)mg->mg_ptr;
807    
808     ++coro->refcnt;
809    
810     return 0;
811     }
812    
813     static MGVTBL coro_state_vtbl = { 0, 0, 0, 0, coro_state_clear, 0, coro_state_dup, 0 };
814    
815     static struct coro *
816     SvSTATE (SV *coro)
817     {
818 root 1.88 HV *stash;
819     MAGIC *mg;
820    
821     if (SvROK (coro))
822     coro = SvRV (coro);
823    
824     stash = SvSTASH (coro);
825     if (stash != coro_stash && stash != coro_state_stash)
826     {
827     /* very slow, but rare, check */
828     if (!sv_derived_from (sv_2mortal (newRV_inc (coro)), "Coro::State"))
829     croak ("Coro::State object required");
830     }
831    
832     mg = SvMAGIC (coro);
833 root 1.87 assert (mg->mg_type == PERL_MAGIC_ext);
834     return (struct coro *)mg->mg_ptr;
835     }
836 root 1.23
837     static void
838 root 1.98 prepare_transfer (struct transfer_args *ta, SV *prev, SV *next, int flags)
839 root 1.23 {
840 root 1.92 ta->prev = SvSTATE (prev);
841     ta->next = SvSTATE (next);
842     ta->flags = flags;
843     }
844    
845     static void
846     api_transfer (SV *prev, SV *next, int flags)
847     {
848     dTHX;
849     struct transfer_args ta;
850    
851 root 1.98 prepare_transfer (&ta, prev, next, flags);
852 root 1.92 TRANSFER (ta);
853 root 1.21 }
854    
855 root 1.22 /** Coro ********************************************************************/
856    
857     #define PRIO_MAX 3
858     #define PRIO_HIGH 1
859     #define PRIO_NORMAL 0
860     #define PRIO_LOW -1
861     #define PRIO_IDLE -3
862     #define PRIO_MIN -4
863    
864     /* for Coro.pm */
865     static GV *coro_current, *coro_idle;
866 root 1.83 static AV *coro_ready [PRIO_MAX-PRIO_MIN+1];
867 root 1.25 static int coro_nready;
868 root 1.22
869     static void
870 root 1.98 coro_enq (SV *sv)
871 root 1.22 {
872 root 1.74 int prio;
873    
874 root 1.73 if (SvTYPE (sv) != SVt_PVHV)
875     croak ("Coro::ready tried to enqueue something that is not a coroutine");
876 root 1.22
877 root 1.88 prio = SvSTATE (sv)->prio;
878 root 1.22
879 root 1.73 av_push (coro_ready [prio - PRIO_MIN], sv);
880     coro_nready++;
881 root 1.22 }
882    
883     static SV *
884 root 1.98 coro_deq (int min_prio)
885 root 1.22 {
886     int prio = PRIO_MAX - PRIO_MIN;
887    
888     min_prio -= PRIO_MIN;
889     if (min_prio < 0)
890     min_prio = 0;
891    
892     for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; )
893 root 1.83 if (AvFILLp (coro_ready [prio]) >= 0)
894 root 1.25 {
895     coro_nready--;
896 root 1.83 return av_shift (coro_ready [prio]);
897 root 1.25 }
898 root 1.22
899     return 0;
900     }
901    
902 root 1.23 static void
903     api_ready (SV *coro)
904     {
905 pcg 1.56 dTHX;
906    
907 root 1.39 if (SvROK (coro))
908     coro = SvRV (coro);
909    
910 pcg 1.55 LOCK;
911 root 1.98 coro_enq (SvREFCNT_inc (coro));
912 pcg 1.55 UNLOCK;
913 root 1.23 }
914    
915     static void
916 root 1.98 prepare_schedule (struct transfer_args *ta)
917 root 1.23 {
918 root 1.92 SV *current, *prev, *next;
919    
920     current = GvSV (coro_current);
921 root 1.88
922     for (;;)
923     {
924     LOCK;
925 root 1.98 next = coro_deq (PRIO_MIN);
926 root 1.99 UNLOCK;
927 root 1.88
928     if (next)
929     break;
930 root 1.23
931 root 1.88 {
932     dSP;
933    
934     ENTER;
935     SAVETMPS;
936 pcg 1.55
937 root 1.88 PUSHMARK (SP);
938     PUTBACK;
939     call_sv (GvSV (coro_idle), G_DISCARD);
940 root 1.23
941 root 1.88 FREETMPS;
942     LEAVE;
943     }
944     }
945    
946     prev = SvRV (current);
947     SvRV (current) = next;
948 root 1.23
949 root 1.40 /* free this only after the transfer */
950 root 1.99 LOCK;
951 root 1.92 free_coro_mortal ();
952 root 1.99 UNLOCK;
953 root 1.39 coro_mortal = prev;
954 root 1.23
955 root 1.92 ta->prev = SvSTATE (prev);
956     ta->next = SvSTATE (next);
957     ta->flags = TRANSFER_SAVE_ALL;
958     }
959    
960     static void
961 root 1.98 prepare_cede (struct transfer_args *ta)
962 root 1.92 {
963     LOCK;
964 root 1.98 coro_enq (SvREFCNT_inc (SvRV (GvSV (coro_current))));
965 pcg 1.55 UNLOCK;
966    
967 root 1.92 prepare_schedule (ta);
968 root 1.39 }
969    
970 root 1.92 static void
971     api_schedule (void)
972     {
973     dTHX;
974     struct transfer_args ta;
975    
976     prepare_schedule (&ta);
977     TRANSFER (ta);
978     }
979 root 1.89
980 root 1.39 static void
981     api_cede (void)
982     {
983 pcg 1.56 dTHX;
984 root 1.92 struct transfer_args ta;
985 root 1.89
986 root 1.92 prepare_cede (&ta);
987     TRANSFER (ta);
988 root 1.23 }
989    
990 root 1.3 MODULE = Coro::State PACKAGE = Coro::State
991 root 1.1
992 root 1.87 PROTOTYPES: DISABLE
993 root 1.1
994 root 1.3 BOOT:
995 root 1.88 {
996 pcg 1.55 #ifdef USE_ITHREADS
997     MUTEX_INIT (&coro_mutex);
998     #endif
999 root 1.78 BOOT_PAGESIZE;
1000 pcg 1.55
1001 root 1.14 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
1002 root 1.7
1003 root 1.13 newCONSTSUB (coro_state_stash, "SAVE_DEFAV", newSViv (TRANSFER_SAVE_DEFAV));
1004     newCONSTSUB (coro_state_stash, "SAVE_DEFSV", newSViv (TRANSFER_SAVE_DEFSV));
1005     newCONSTSUB (coro_state_stash, "SAVE_ERRSV", newSViv (TRANSFER_SAVE_ERRSV));
1006 root 1.7
1007 root 1.12 main_mainstack = PL_mainstack;
1008 root 1.23
1009 root 1.26 coroapi.ver = CORO_API_VERSION;
1010     coroapi.transfer = api_transfer;
1011 root 1.87
1012     assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL));
1013 root 1.9 }
1014 root 1.3
1015 root 1.87 SV *
1016 root 1.86 new (char *klass, ...)
1017 root 1.1 CODE:
1018 root 1.86 {
1019 root 1.87 struct coro *coro;
1020     HV *hv;
1021 root 1.86 int i;
1022    
1023 pcg 1.47 Newz (0, coro, 1, struct coro);
1024 root 1.86 coro->args = newAV ();
1025    
1026 root 1.89 hv = newHV ();
1027     sv_magicext ((SV *)hv, 0, PERL_MAGIC_ext, &coro_state_vtbl, (char *)coro, 0)->mg_flags |= MGf_DUP;
1028     RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
1029    
1030 root 1.86 for (i = 1; i < items; i++)
1031     av_push (coro->args, newSVsv (ST (i)));
1032    
1033 root 1.59 /*coro->mainstack = 0; *//*actual work is done inside transfer */
1034     /*coro->stack = 0;*/
1035 root 1.86 }
1036 root 1.1 OUTPUT:
1037     RETVAL
1038    
1039     void
1040 root 1.94 _set_stacklevel (...)
1041 root 1.92 ALIAS:
1042 root 1.94 Coro::State::transfer = 1
1043     Coro::schedule = 2
1044     Coro::cede = 3
1045     Coro::Cont::yield = 4
1046 root 1.1 CODE:
1047 root 1.87 {
1048 root 1.92 struct transfer_args ta;
1049 root 1.1
1050 root 1.92 switch (ix)
1051 root 1.1 {
1052 root 1.92 case 0:
1053 root 1.94 ta.prev = (struct coro *)INT2PTR (coro_stack *, SvIV (ST (0)));
1054     ta.next = 0;
1055     ta.flags = TRANSFER_SET_STACKLEVEL;
1056     break;
1057    
1058     case 1:
1059 root 1.92 if (items != 3)
1060     croak ("Coro::State::transfer(prev,next,flags) expects three arguments, not %d", items);
1061    
1062     prepare_transfer (&ta, ST (0), ST (1), SvIV (ST (2)));
1063     break;
1064    
1065 root 1.94 case 2:
1066 root 1.92 prepare_schedule (&ta);
1067     break;
1068    
1069 root 1.94 case 3:
1070 root 1.92 prepare_cede (&ta);
1071     break;
1072    
1073 root 1.94 case 4:
1074     {
1075     SV *yieldstack;
1076     SV *sv;
1077     AV *defav = GvAV (PL_defgv);
1078    
1079     yieldstack = *hv_fetch (
1080     (HV *)SvRV (GvSV (coro_current)),
1081     "yieldstack", sizeof ("yieldstack") - 1,
1082     0
1083     );
1084    
1085     /* set up @_ -- ugly */
1086     av_clear (defav);
1087     av_fill (defav, items - 1);
1088     while (items--)
1089     av_store (defav, items, SvREFCNT_inc (ST(items)));
1090    
1091     sv = av_pop ((AV *)SvRV (yieldstack));
1092     ta.prev = SvSTATE (*av_fetch ((AV *)SvRV (sv), 0, 0));
1093     ta.next = SvSTATE (*av_fetch ((AV *)SvRV (sv), 1, 0));
1094     ta.flags = 0;
1095     SvREFCNT_dec (sv);
1096     }
1097     break;
1098    
1099 root 1.92 }
1100 root 1.1
1101 root 1.92 TRANSFER (ta);
1102 root 1.87 }
1103 root 1.1
1104 root 1.87 void
1105     _clone_state_from (SV *dst, SV *src)
1106     CODE:
1107     {
1108     struct coro *coro_src = SvSTATE (src);
1109 root 1.13
1110 root 1.87 sv_unmagic (SvRV (dst), PERL_MAGIC_ext);
1111 root 1.13
1112 root 1.87 ++coro_src->refcnt;
1113     sv_magicext (SvRV (dst), 0, PERL_MAGIC_ext, &coro_state_vtbl, (char *)coro_src, 0)->mg_flags |= MGf_DUP;
1114     }
1115 root 1.12
1116 root 1.7 void
1117 root 1.92 _nonlocal_goto (IV nextop)
1118     CODE:
1119     /* uuh, somebody will kill me again for this */
1120     PL_op->op_next = INT2PTR (OP *, nextop);
1121    
1122     void
1123 root 1.87 _exit (code)
1124 root 1.20 int code
1125     PROTOTYPE: $
1126     CODE:
1127     _exit (code);
1128 root 1.1
1129 root 1.21 MODULE = Coro::State PACKAGE = Coro
1130    
1131     BOOT:
1132     {
1133 root 1.22 int i;
1134    
1135 root 1.88 coro_stash = gv_stashpv ("Coro", TRUE);
1136    
1137     newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
1138     newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
1139     newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
1140     newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW));
1141     newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
1142     newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN));
1143 root 1.22
1144 root 1.21 coro_current = gv_fetchpv ("Coro::current", TRUE, SVt_PV);
1145     coro_idle = gv_fetchpv ("Coro::idle" , TRUE, SVt_PV);
1146 root 1.22
1147     for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
1148     coro_ready[i] = newAV ();
1149 root 1.26
1150     {
1151     SV *sv = perl_get_sv("Coro::API", 1);
1152    
1153     coroapi.schedule = api_schedule;
1154 root 1.39 coroapi.cede = api_cede;
1155 root 1.26 coroapi.ready = api_ready;
1156     coroapi.nready = &coro_nready;
1157     coroapi.current = coro_current;
1158    
1159     GCoroAPI = &coroapi;
1160 root 1.81 sv_setiv (sv, (IV)&coroapi);
1161     SvREADONLY_on (sv);
1162 root 1.26 }
1163 root 1.21 }
1164    
1165 root 1.92 int
1166     prio (Coro::State coro, int newprio = 0)
1167     ALIAS:
1168     nice = 1
1169     CODE:
1170     {
1171     RETVAL = coro->prio;
1172    
1173     if (items > 1)
1174     {
1175     if (ix)
1176     newprio += coro->prio;
1177    
1178     if (newprio < PRIO_MIN) newprio = PRIO_MIN;
1179     if (newprio > PRIO_MAX) newprio = PRIO_MAX;
1180    
1181     coro->prio = newprio;
1182     }
1183     }
1184    
1185 root 1.21 void
1186 root 1.89 ready (SV *self)
1187 root 1.35 PROTOTYPE: $
1188 root 1.21 CODE:
1189 root 1.23 api_ready (self);
1190 pcg 1.50
1191 root 1.25 int
1192 root 1.87 nready (...)
1193 root 1.25 PROTOTYPE:
1194     CODE:
1195     RETVAL = coro_nready;
1196     OUTPUT:
1197     RETVAL
1198    
1199 root 1.89 MODULE = Coro::State PACKAGE = Coro::AIO
1200    
1201 root 1.70 SV *
1202 root 1.89 _get_state ()
1203 root 1.70 CODE:
1204     {
1205     struct {
1206     int errorno;
1207     int laststype;
1208     int laststatval;
1209     Stat_t statcache;
1210     } data;
1211    
1212     data.errorno = errno;
1213     data.laststype = PL_laststype;
1214     data.laststatval = PL_laststatval;
1215     data.statcache = PL_statcache;
1216    
1217     RETVAL = newSVpvn ((char *)&data, sizeof data);
1218     }
1219     OUTPUT:
1220     RETVAL
1221    
1222     void
1223 root 1.89 _set_state (char *data_)
1224 root 1.70 PROTOTYPE: $
1225     CODE:
1226     {
1227     struct {
1228     int errorno;
1229     int laststype;
1230     int laststatval;
1231     Stat_t statcache;
1232     } *data = (void *)data_;
1233    
1234     errno = data->errorno;
1235     PL_laststype = data->laststype;
1236     PL_laststatval = data->laststatval;
1237     PL_statcache = data->statcache;
1238     }