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.10 by root, Sat Jul 21 04:19:34 2001 UTC vs.
Revision 1.13 by root, Mon Jul 23 22:09:39 2001 UTC

1#include "EXTERN.h" 1#include "EXTERN.h"
2#include "perl.h" 2#include "perl.h"
3#include "XSUB.h" 3#include "XSUB.h"
4 4
5#if 1 5#include "libcoro/coro.c"
6# define CHK(x) (void *)0 6
7#else 7#ifdef HAVE_MMAP
8# define CHK(x) if (!(x)) croak("FATAL, CHK: " #x) 8# include <unistd.h>
9# include <sys/mman.h>
9#endif 10#endif
10 11
11#define MAY_FLUSH /* increases codesize */ 12#define MAY_FLUSH /* increases codesize */
12 13
13#define SUB_INIT "Coro::State::coroutine_initialization" 14#define SUB_INIT "Coro::State::initialize"
14 15
15#define SAVE_DEFAV 0x00000001 16#define TRANSFER_SAVE_DEFAV 0x00000001
16#define SAVE_DEFSV 0x00000002 17#define TRANSFER_SAVE_DEFSV 0x00000002
17#define SAVE_ERRSV 0x00000004 18#define TRANSFER_SAVE_ERRSV 0x00000004
19#define TRANSFER_SAVE_CCTXT 0x00000008
18 20
19#define SAVE_ALL -1 21#define TRANSFER_SAVE_ALL -1
20 22
21struct coro { 23struct coro {
24 /* the optional C context */
25 coro_context cctx;
26 void *sptr;
27 long ssize;
28
22 /* optionally saved, might be zero */ 29 /* optionally saved, might be zero */
23 AV *defav; 30 AV *defav;
24 SV *defsv; 31 SV *defsv;
25 SV *errsv; 32 SV *errsv;
26 33
51 I32 savestack_max; 58 I32 savestack_max;
52 OP **retstack; 59 OP **retstack;
53 I32 retstack_ix; 60 I32 retstack_ix;
54 I32 retstack_max; 61 I32 retstack_max;
55 COP *curcop; 62 COP *curcop;
63 JMPENV start_env;
64 JMPENV *top_env;
56 65
57 /* data associated with this coroutine (initial args) */ 66 /* data associated with this coroutine (initial args) */
58 AV *args; 67 AV *args;
59}; 68};
60 69
61typedef struct coro *Coro__State; 70typedef struct coro *Coro__State;
62typedef struct coro *Coro__State_or_hashref; 71typedef struct coro *Coro__State_or_hashref;
63 72
73static AV *main_mainstack; /* used to differentiate between $main and others */
74static HV *coro_state_stash;
64static HV *padlist_cache; 75static HV *padlist_cache;
65 76
66/* mostly copied from op.c:cv_clone2 */ 77/* mostly copied from op.c:cv_clone2 */
67STATIC AV * 78STATIC AV *
68clone_padlist (AV *protopadlist) 79clone_padlist (AV *protopadlist)
231#endif 242#endif
232 243
233#define SB do { 244#define SB do {
234#define SE } while (0) 245#define SE } while (0)
235 246
236#define LOAD(state) SB load_state(aTHX_ state); SPAGAIN; SE 247#define LOAD(state) SB load_state(aTHX_ (state)); SPAGAIN; SE
237#define SAVE(state,flags) SB PUTBACK; save_state(aTHX_ state,flags); SE 248#define SAVE(state,flags) SB PUTBACK; save_state(aTHX_ (state),(flags)); SE
238 249
239#define REPLACE_SV(sv,val) SB SvREFCNT_dec(sv); (sv) = (val); SE 250#define REPLACE_SV(sv,val) SB SvREFCNT_dec(sv); (sv) = (val); SE
240 251
241static void 252static void
242load_state(pTHX_ Coro__State c) 253load_state(pTHX_ Coro__State c)
266 PL_savestack_max = c->savestack_max; 277 PL_savestack_max = c->savestack_max;
267 PL_retstack = c->retstack; 278 PL_retstack = c->retstack;
268 PL_retstack_ix = c->retstack_ix; 279 PL_retstack_ix = c->retstack_ix;
269 PL_retstack_max = c->retstack_max; 280 PL_retstack_max = c->retstack_max;
270 PL_curcop = c->curcop; 281 PL_curcop = c->curcop;
282 PL_start_env = c->start_env;
283 PL_top_env = c->top_env;
271 284
272 if (c->defav) REPLACE_SV (GvAV (PL_defgv), c->defav); 285 if (c->defav) REPLACE_SV (GvAV (PL_defgv), c->defav);
273 if (c->defsv) REPLACE_SV (DEFSV , c->defsv); 286 if (c->defsv) REPLACE_SV (DEFSV , c->defsv);
274 if (c->errsv) REPLACE_SV (ERRSV , c->errsv); 287 if (c->errsv) REPLACE_SV (ERRSV , c->errsv);
275 288
302save_state(pTHX_ Coro__State c, int flags) 315save_state(pTHX_ Coro__State c, int flags)
303{ 316{
304 { 317 {
305 dSP; 318 dSP;
306 I32 cxix = cxstack_ix; 319 I32 cxix = cxstack_ix;
320 PERL_CONTEXT *ccstk = cxstack;
307 PERL_SI *top_si = PL_curstackinfo; 321 PERL_SI *top_si = PL_curstackinfo;
308 PERL_CONTEXT *ccstk = cxstack;
309 322
310 /* 323 /*
311 * the worst thing you can imagine happens first - we have to save 324 * the worst thing you can imagine happens first - we have to save
312 * (and reinitialize) all cv's in the whole callchain :( 325 * (and reinitialize) all cv's in the whole callchain :(
313 */ 326 */
314 327
315 PUSHs (Nullsv); 328 PUSHs (Nullsv);
316 /* this loop was inspired by pp_caller */ 329 /* this loop was inspired by pp_caller */
317 for (;;) 330 for (;;)
318 { 331 {
319 do 332 do
320 { 333 {
321 PERL_CONTEXT *cx = &ccstk[cxix--]; 334 PERL_CONTEXT *cx = &ccstk[cxix--];
322 335
323 if (CxTYPE(cx) == CXt_SUB) 336 if (CxTYPE(cx) == CXt_SUB)
324 { 337 {
363 } 376 }
364 377
365 PUTBACK; 378 PUTBACK;
366 } 379 }
367 380
368 c->defav = flags & SAVE_DEFAV ? (AV *)SvREFCNT_inc (GvAV (PL_defgv)) : 0; 381 c->defav = flags & TRANSFER_SAVE_DEFAV ? (AV *)SvREFCNT_inc (GvAV (PL_defgv)) : 0;
369 c->defsv = flags & SAVE_DEFSV ? SvREFCNT_inc (DEFSV) : 0; 382 c->defsv = flags & TRANSFER_SAVE_DEFSV ? SvREFCNT_inc (DEFSV) : 0;
370 c->errsv = flags & SAVE_ERRSV ? SvREFCNT_inc (ERRSV) : 0; 383 c->errsv = flags & TRANSFER_SAVE_ERRSV ? SvREFCNT_inc (ERRSV) : 0;
384
385 /* I have not the slightest idea of why av_reify is necessary */
386 /* but if it's missing the defav contents magically get replaced sometimes */
387 if (c->defav)
388 av_reify (c->defav);
371 389
372 c->dowarn = PL_dowarn; 390 c->dowarn = PL_dowarn;
373 391
374 c->curstackinfo = PL_curstackinfo; 392 c->curstackinfo = PL_curstackinfo;
375 c->curstack = PL_curstack; 393 c->curstack = PL_curstack;
394 c->savestack_max = PL_savestack_max; 412 c->savestack_max = PL_savestack_max;
395 c->retstack = PL_retstack; 413 c->retstack = PL_retstack;
396 c->retstack_ix = PL_retstack_ix; 414 c->retstack_ix = PL_retstack_ix;
397 c->retstack_max = PL_retstack_max; 415 c->retstack_max = PL_retstack_max;
398 c->curcop = PL_curcop; 416 c->curcop = PL_curcop;
417 c->start_env = PL_start_env;
418 c->top_env = PL_top_env;
419}
420
421/*
422 * allocate various perl stacks. This is an exact copy
423 * of perl.c:init_stacks, except that it uses less memory
424 * on the assumption that coroutines do not usually need
425 * a lot of stackspace.
426 */
427STATIC void
428coro_init_stacks (pTHX)
429{
430 PL_curstackinfo = new_stackinfo(96, 1024/sizeof(PERL_CONTEXT) - 1);
431 PL_curstackinfo->si_type = PERLSI_MAIN;
432 PL_curstack = PL_curstackinfo->si_stack;
433 PL_mainstack = PL_curstack; /* remember in case we switch stacks */
434
435 PL_stack_base = AvARRAY(PL_curstack);
436 PL_stack_sp = PL_stack_base;
437 PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
438
439 New(50,PL_tmps_stack,64,SV*);
440 PL_tmps_floor = -1;
441 PL_tmps_ix = -1;
442 PL_tmps_max = 64;
443
444 New(54,PL_markstack,12,I32);
445 PL_markstack_ptr = PL_markstack;
446 PL_markstack_max = PL_markstack + 12;
447
448 SET_MARK_OFFSET;
449
450 New(54,PL_scopestack,12,I32);
451 PL_scopestack_ix = 0;
452 PL_scopestack_max = 12;
453
454 New(54,PL_savestack,64,ANY);
455 PL_savestack_ix = 0;
456 PL_savestack_max = 64;
457
458 New(54,PL_retstack,8,OP*);
459 PL_retstack_ix = 0;
460 PL_retstack_max = 8;
399} 461}
400 462
401/* 463/*
402 * destroy the stacks, the callchain etc... 464 * destroy the stacks, the callchain etc...
403 * still there is a memleak of 128 bytes... 465 * still there is a memleak of 128 bytes...
439 Safefree(PL_scopestack); 501 Safefree(PL_scopestack);
440 Safefree(PL_savestack); 502 Safefree(PL_savestack);
441 Safefree(PL_retstack); 503 Safefree(PL_retstack);
442} 504}
443 505
506static void
507allocate_stack (Coro__State ctx)
508{
509#ifdef HAVE_MMAP
510 ctx->ssize = 128 * 1024 * sizeof (long); /* mmap should do allocate-on-use */
511 ctx->sptr = mmap (0, ctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
512 if (ctx->sptr == (void *)-1)
513#endif
514 {
515 /*FIXME*//*D*//* reasonable stack size! */
516 ctx->ssize = 4096 * sizeof (long);
517 New (0, ctx->sptr, 4096, long);
518 }
519}
520
521static void
522deallocate_stack (Coro__State ctx)
523{
524#ifdef HAVE_MMAP
525 munmap (ctx->sptr, ctx->ssize);
526#else
527 Safefree (ctx->sptr);
528#endif
529}
530
531/* might go away together with optional SAVE_CCTXT */
532static void
533setup_coro (void *arg)
534{
535 /*
536 * emulate part of the perl startup here.
537 */
538 dSP;
539 Coro__State ctx = (Coro__State)arg;
540 SV *sub_init = (SV*)get_cv(SUB_INIT, FALSE);
541
542 coro_init_stacks (aTHX);
543 JMPENV_BOOTSTRAP;
544 SPAGAIN;
545
546 /*PL_curcop = 0;*/
547 SvREFCNT_dec (GvAV (PL_defgv));
548 GvAV (PL_defgv) = ctx->args;
549
550 if (ctx->sptr)
551 {
552 PUSHMARK(SP);
553 PUTBACK;
554 (void) call_sv (sub_init, G_VOID|G_NOARGS);
555 croak ("FATAL: CCTXT coroutine returned!");
556 }
557 else
558 {
559 UNOP myop;
560
561 PL_op = (OP *)&myop;
562
563 Zero(&myop, 1, UNOP);
564 myop.op_next = Nullop;
565 myop.op_flags = OPf_WANT_VOID;
566
567 PUSHMARK(SP);
568 XPUSHs (sub_init);
569 /*
570 * the next line is slightly wrong, as PL_op->op_next
571 * is actually being executed so we skip the first op.
572 * that doesn't matter, though, since it is only
573 * pp_nextstate and we never return...
574 * ah yes, and I don't care anyways ;)
575 */
576 PUTBACK;
577 PL_op = pp_entersub();
578 SPAGAIN;
579
580 ENTER; /* necessary e.g. for dounwind */
581 }
582}
583
444STATIC void 584STATIC void
445transfer(pTHX_ struct coro *prev, struct coro *next, int flags) 585transfer(pTHX_ struct coro *prev, struct coro *next, int flags)
446{ 586{
447 dSP; 587 dSP;
448 588
449 if (prev != next) 589 if (prev != next)
450 { 590 {
451 /* 591 /*
452 * this could be done in newprocess which would lead to 592 * this could be done in newprocess which would lead to
453 * extremely elegant and fast (just SAVE/LOAD) 593 * extremely elegant and fast (basically just SAVE/LOAD)
454 * code here, but lazy allocation of stacks has also 594 * code here, but lazy allocation of stacks has also
455 * some virtues and the overhead of the if() is nil. 595 * some virtues and the overhead of the if() is nil.
456 */ 596 */
457 if (next->mainstack) 597 if (next->mainstack)
458 { 598 {
459 SAVE (prev, flags); 599 SAVE (prev, flags);
460 LOAD (next); 600 LOAD (next);
601
461 /* mark this state as in-use */ 602 /* mark this state as in-use */
462 next->mainstack = 0; 603 next->mainstack = 0;
463 next->tmps_ix = -2; 604 next->tmps_ix = -2;
605
606 if (flags & TRANSFER_SAVE_CCTXT)
607 {
608 if (!next->ssize)
609 croak ("destination coroutine has no CCTXT (%p, %d)", next->sptr, next->ssize);
610
611 if (!prev->ssize)
612 prev->ssize = 1; /* mark cctx as valid ;) */
613
614 coro_transfer (&(prev->cctx), &(next->cctx));
615 }
616
464 } 617 }
465 else if (next->tmps_ix == -2) 618 else if (next->tmps_ix == -2)
466 {
467 croak ("tried to transfer to running coroutine"); 619 croak ("tried to transfer to running coroutine");
468 }
469 else 620 else
470 { 621 {
471 /*
472 * emulate part of the perl startup here.
473 */
474 UNOP myop;
475
476 SAVE (prev, -1); /* first get rid of the old state */ 622 SAVE (prev, -1); /* first get rid of the old state */
477 623
478 init_stacks (); /* from perl.c */ 624 if (flags & TRANSFER_SAVE_CCTXT)
479 SPAGAIN;
480
481 PL_op = (OP *)&myop;
482 /*PL_curcop = 0;*/
483 SvREFCNT_dec (GvAV (PL_defgv));
484 GvAV (PL_defgv) = next->args;
485
486 Zero(&myop, 1, UNOP);
487 myop.op_next = Nullop;
488 myop.op_flags = OPf_WANT_VOID;
489
490 PUSHMARK(SP);
491 XPUSHs ((SV*)get_cv(SUB_INIT, TRUE));
492 /*
493 * the next line is slightly wrong, as PL_op->op_next
494 * is actually being executed so we skip the first op.
495 * that doesn't matter, though, since it is only
496 * pp_nextstate and we never return...
497 * ah yes, and I don't care anyways ;)
498 */ 625 {
499 PUTBACK; 626 if (!next->ssize)
500 PL_op = pp_entersub(aTHX); 627 {
501 SPAGAIN; 628 allocate_stack (next);
629 coro_create (&(next->cctx),
630 setup_coro, (void *)next,
631 next->sptr, next->ssize);
632 }
502 633
503 ENTER; /* necessary e.g. for dounwind */ 634 if (!prev->ssize)
635 prev->ssize = 1; /* mark cctx as valid ;) */
636
637 coro_transfer (&(prev->cctx), &(next->cctx));
638 }
639 else
640 setup_coro (next);
504 } 641 }
505 } 642 }
506} 643}
507 644
508MODULE = Coro::State PACKAGE = Coro::State 645MODULE = Coro::State PACKAGE = Coro::State
509 646
510PROTOTYPES: ENABLE 647PROTOTYPES: ENABLE
511 648
512BOOT: 649BOOT:
513{ /* {} necessary for stoopid perl-5.6.x */ 650{ /* {} necessary for stoopid perl-5.6.x */
514 HV * stash = gv_stashpvn("Coro::State", 10, TRUE); 651 coro_state_stash = gv_stashpvn ("Coro::State", 10, TRUE);
515 652
516 newCONSTSUB (stash, "SAVE_DEFAV", newSViv (SAVE_DEFAV)); 653 newCONSTSUB (coro_state_stash, "SAVE_DEFAV", newSViv (TRANSFER_SAVE_DEFAV));
517 newCONSTSUB (stash, "SAVE_DEFSV", newSViv (SAVE_DEFSV)); 654 newCONSTSUB (coro_state_stash, "SAVE_DEFSV", newSViv (TRANSFER_SAVE_DEFSV));
518 newCONSTSUB (stash, "SAVE_ERRSV", newSViv (SAVE_ERRSV)); 655 newCONSTSUB (coro_state_stash, "SAVE_ERRSV", newSViv (TRANSFER_SAVE_ERRSV));
656 newCONSTSUB (coro_state_stash, "SAVE_CCTXT", newSViv (TRANSFER_SAVE_CCTXT));
519 657
520 if (!padlist_cache) 658 if (!padlist_cache)
521 padlist_cache = newHV (); 659 padlist_cache = newHV ();
660
661 main_mainstack = PL_mainstack;
522} 662}
523 663
524Coro::State 664Coro::State
525_newprocess(args) 665_newprocess(args)
526 SV * args 666 SV * args
531 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) 671 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV)
532 croak ("Coro::State::_newprocess expects an arrayref"); 672 croak ("Coro::State::_newprocess expects an arrayref");
533 673
534 New (0, coro, 1, struct coro); 674 New (0, coro, 1, struct coro);
535 675
676 coro->args = (AV *)SvREFCNT_inc (SvRV (args));
536 coro->mainstack = 0; /* actual work is done inside transfer */ 677 coro->mainstack = 0; /* actual work is done inside transfer */
537 coro->args = (AV *)SvREFCNT_inc (SvRV (args)); 678 coro->sptr = 0;
679 coro->ssize = 0;
538 680
539 RETVAL = coro; 681 RETVAL = coro;
540 OUTPUT: 682 OUTPUT:
541 RETVAL 683 RETVAL
542 684
543void 685void
544transfer(prev, next, flags = SAVE_DEFAV) 686transfer(prev, next, flags = TRANSFER_SAVE_ALL)
545 Coro::State_or_hashref prev 687 Coro::State_or_hashref prev
546 Coro::State_or_hashref next 688 Coro::State_or_hashref next
547 int flags 689 int flags
548 PROTOTYPE: @ 690 PROTOTYPE: @
549 CODE: 691 CODE:
550
551 transfer (aTHX_ prev, next, flags); 692 transfer (aTHX_ prev, next, flags);
552 693
553void 694void
554DESTROY(coro) 695DESTROY(coro)
555 Coro::State coro 696 Coro::State coro
556 CODE: 697 CODE:
557 698
558 if (coro->mainstack) 699 if (coro->mainstack && coro->mainstack != main_mainstack)
559 { 700 {
560 struct coro temp; 701 struct coro temp;
561 702
562 SAVE(aTHX_ (&temp), SAVE_ALL); 703 SAVE(aTHX_ (&temp), TRANSFER_SAVE_ALL);
563 LOAD(aTHX_ coro); 704 LOAD(aTHX_ coro);
564 705
565 destroy_stacks (); 706 destroy_stacks (aTHX);
566 707
567 LOAD((&temp)); /* this will get rid of defsv etc.. */ 708 LOAD((&temp)); /* this will get rid of defsv etc.. */
709
710 coro->mainstack = 0;
711 }
712
713 if (coro->sptr)
714 {
715 deallocate_stack (coro);
716 coro->sptr = 0;
568 } 717 }
569 718
570 Safefree (coro); 719 Safefree (coro);
571 720
572void 721void
576 flush_padlist_cache (); 725 flush_padlist_cache ();
577#endif 726#endif
578 727
579MODULE = Coro::State PACKAGE = Coro::Cont 728MODULE = Coro::State PACKAGE = Coro::Cont
580 729
581# this is dirty and should be in it's own .xs 730# this is slightly dirty
582 731
583void 732void
584result(...) 733yield(...)
585 PROTOTYPE: @ 734 PROTOTYPE: @
586 CODE: 735 CODE:
587 static SV *returnstk; 736 static SV *returnstk;
588 SV *sv; 737 SV *sv;
589 AV *defav = GvAV (PL_defgv); 738 AV *defav = GvAV (PL_defgv);
590 struct coro *prev, *next; 739 struct coro *prev, *next;
591 740
592 if (!returnstk) 741 if (!returnstk)
593 returnstk = SvRV (get_sv ("Coro::Cont::return", FALSE)); 742 returnstk = SvRV (get_sv ("Coro::Cont::return", FALSE));
594 743
595 /* set up @_ */ 744 /* set up @_ -- ugly */
596 av_clear (defav); 745 av_clear (defav);
597 av_fill (defav, items - 1); 746 av_fill (defav, items - 1);
598 while (items--) 747 while (items--)
599 av_store (defav, items, SvREFCNT_inc (ST(items))); 748 av_store (defav, items, SvREFCNT_inc (ST(items)));
600 749
601 mg_get (returnstk); /* isn't documentation wrong for mg_get? */ 750 mg_get (returnstk); /* isn't documentation wrong for mg_get? */
602 sv = av_pop ((AV *)SvRV (returnstk)); 751 sv = av_pop ((AV *)SvRV (returnstk));
603 prev = (struct coro *)SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 0, 0))); 752 prev = (struct coro *)SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 0, 0)));
604 next = (struct coro *)SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 1, 0))); 753 next = (struct coro *)SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 1, 0)));
605 SvREFCNT_dec (sv); 754 SvREFCNT_dec (sv);
755
606 transfer(prev, next, 0); 756 transfer(aTHX_ prev, next, 0);
607 757

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines