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.145 by root, Mon Mar 12 21:40:14 2007 UTC vs.
Revision 1.146 by root, Sat Mar 17 19:51:57 2007 UTC

1#include "libcoro/coro.c" 1#include "libcoro/coro.c"
2
3#define PERL_NO_GET_CONTEXT
2 4
3#include "EXTERN.h" 5#include "EXTERN.h"
4#include "perl.h" 6#include "perl.h"
5#include "XSUB.h" 7#include "XSUB.h"
6 8
206static int coro_nready; 208static int coro_nready;
207 209
208/** lowlevel stuff **********************************************************/ 210/** lowlevel stuff **********************************************************/
209 211
210static AV * 212static AV *
211coro_clone_padlist (CV *cv) 213coro_clone_padlist (pTHX_ CV *cv)
212{ 214{
213 AV *padlist = CvPADLIST (cv); 215 AV *padlist = CvPADLIST (cv);
214 AV *newpadlist, *newpad; 216 AV *newpadlist, *newpad;
215 217
216 newpadlist = newAV (); 218 newpadlist = newAV ();
228 230
229 return newpadlist; 231 return newpadlist;
230} 232}
231 233
232static void 234static void
233free_padlist (AV *padlist) 235free_padlist (pTHX_ AV *padlist)
234{ 236{
235 /* may be during global destruction */ 237 /* may be during global destruction */
236 if (SvREFCNT (padlist)) 238 if (SvREFCNT (padlist))
237 { 239 {
238 I32 i = AvFILLp (padlist); 240 I32 i = AvFILLp (padlist);
259 AV *padlist; 261 AV *padlist;
260 AV *av = (AV *)mg->mg_obj; 262 AV *av = (AV *)mg->mg_obj;
261 263
262 /* casting is fun. */ 264 /* casting is fun. */
263 while (&PL_sv_undef != (SV *)(padlist = (AV *)av_pop (av))) 265 while (&PL_sv_undef != (SV *)(padlist = (AV *)av_pop (av)))
264 free_padlist (padlist); 266 free_padlist (aTHX_ padlist);
265 267
266 SvREFCNT_dec (av); 268 SvREFCNT_dec (av);
267 269
268 return 0; 270 return 0;
269} 271}
279 : mg_find ((SV *)cv, PERL_MAGIC_coro) \ 281 : mg_find ((SV *)cv, PERL_MAGIC_coro) \
280 : 0 282 : 0
281 283
282/* the next two functions merely cache the padlists */ 284/* the next two functions merely cache the padlists */
283static void 285static void
284get_padlist (CV *cv) 286get_padlist (pTHX_ CV *cv)
285{ 287{
286 MAGIC *mg = CORO_MAGIC (cv); 288 MAGIC *mg = CORO_MAGIC (cv);
287 AV *av; 289 AV *av;
288 290
289 if (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0) 291 if (mg && AvFILLp ((av = (AV *)mg->mg_obj)) >= 0)
295 CV *cp = Perl_cv_clone (cv); 297 CV *cp = Perl_cv_clone (cv);
296 CvPADLIST (cv) = CvPADLIST (cp); 298 CvPADLIST (cv) = CvPADLIST (cp);
297 CvPADLIST (cp) = 0; 299 CvPADLIST (cp) = 0;
298 SvREFCNT_dec (cp); 300 SvREFCNT_dec (cp);
299#else 301#else
300 CvPADLIST (cv) = coro_clone_padlist (cv); 302 CvPADLIST (cv) = coro_clone_padlist (aTHX_ cv);
301#endif 303#endif
302 } 304 }
303} 305}
304 306
305static void 307static void
306put_padlist (CV *cv) 308put_padlist (pTHX_ CV *cv)
307{ 309{
308 MAGIC *mg = CORO_MAGIC (cv); 310 MAGIC *mg = CORO_MAGIC (cv);
309 AV *av; 311 AV *av;
310 312
311 if (!mg) 313 if (!mg)
330#define SE } while (0) 332#define SE } while (0)
331 333
332#define REPLACE_SV(sv,val) SB SvREFCNT_dec (sv); (sv) = (val); (val) = 0; SE 334#define REPLACE_SV(sv,val) SB SvREFCNT_dec (sv); (sv) = (val); (val) = 0; SE
333 335
334static void 336static void
335load_perl (Coro__State c) 337load_perl (pTHX_ Coro__State c)
336{ 338{
337#define VAR(name,type) PL_ ## name = c->name; 339#define VAR(name,type) PL_ ## name = c->name;
338# include "state.h" 340# include "state.h"
339#undef VAR 341#undef VAR
340 342
358 CV *cv; 360 CV *cv;
359 361
360 /* now do the ugly restore mess */ 362 /* now do the ugly restore mess */
361 while ((cv = (CV *)POPs)) 363 while ((cv = (CV *)POPs))
362 { 364 {
363 put_padlist (cv); /* mark this padlist as available */ 365 put_padlist (aTHX_ cv); /* mark this padlist as available */
364 CvDEPTH (cv) = PTR2IV (POPs); 366 CvDEPTH (cv) = PTR2IV (POPs);
365 CvPADLIST (cv) = (AV *)POPs; 367 CvPADLIST (cv) = (AV *)POPs;
366 } 368 }
367 369
368 PUTBACK; 370 PUTBACK;
369 } 371 }
370 assert (!PL_comppad || AvARRAY (PL_comppad));//D 372 assert (!PL_comppad || AvARRAY (PL_comppad));//D
371} 373}
372 374
373static void 375static void
374save_perl (Coro__State c) 376save_perl (pTHX_ Coro__State c)
375{ 377{
376 assert (!PL_comppad || AvARRAY (PL_comppad));//D 378 assert (!PL_comppad || AvARRAY (PL_comppad));//D
377 { 379 {
378 dSP; 380 dSP;
379 I32 cxix = cxstack_ix; 381 I32 cxix = cxstack_ix;
404 PUSHs ((SV *)CvPADLIST (cv)); 406 PUSHs ((SV *)CvPADLIST (cv));
405 PUSHs (INT2PTR (SV *, CvDEPTH (cv))); 407 PUSHs (INT2PTR (SV *, CvDEPTH (cv)));
406 PUSHs ((SV *)cv); 408 PUSHs ((SV *)cv);
407 409
408 CvDEPTH (cv) = 0; 410 CvDEPTH (cv) = 0;
409 get_padlist (cv); 411 get_padlist (aTHX_ cv);
410 } 412 }
411 } 413 }
412 } 414 }
413 415
414 if (top_si->si_type == PERLSI_MAIN) 416 if (top_si->si_type == PERLSI_MAIN)
440 */ 442 */
441#if CORO_PREFER_PERL_FUNCTIONS 443#if CORO_PREFER_PERL_FUNCTIONS
442# define coro_init_stacks init_stacks 444# define coro_init_stacks init_stacks
443#else 445#else
444static void 446static void
445coro_init_stacks () 447coro_init_stacks (pTHX)
446{ 448{
447 PL_curstackinfo = new_stackinfo(128, 1024/sizeof(PERL_CONTEXT)); 449 PL_curstackinfo = new_stackinfo(128, 1024/sizeof(PERL_CONTEXT));
448 PL_curstackinfo->si_type = PERLSI_MAIN; 450 PL_curstackinfo->si_type = PERLSI_MAIN;
449 PL_curstack = PL_curstackinfo->si_stack; 451 PL_curstack = PL_curstackinfo->si_stack;
450 PL_mainstack = PL_curstack; /* remember in case we switch stacks */ 452 PL_mainstack = PL_curstack; /* remember in case we switch stacks */
484 486
485/* 487/*
486 * destroy the stacks, the callchain etc... 488 * destroy the stacks, the callchain etc...
487 */ 489 */
488static void 490static void
489coro_destroy_stacks () 491coro_destroy_stacks (pTHX)
490{ 492{
491 if (!IN_DESTRUCT) 493 if (!IN_DESTRUCT)
492 { 494 {
493 /* restore all saved variables and stuff */ 495 /* restore all saved variables and stuff */
494 LEAVE_SCOPE (0); 496 LEAVE_SCOPE (0);
530} 532}
531 533
532/** coroutine stack handling ************************************************/ 534/** coroutine stack handling ************************************************/
533 535
534static void 536static void
535setup_coro (struct coro *coro) 537setup_coro (pTHX_ struct coro *coro)
536{ 538{
537 /* 539 /*
538 * emulate part of the perl startup here. 540 * emulate part of the perl startup here.
539 */ 541 */
540
541 coro_init_stacks (); 542 coro_init_stacks (aTHX);
542 543
543 PL_curcop = &PL_compiling; 544 PL_curcop = &PL_compiling;
544 PL_in_eval = EVAL_NULL; 545 PL_in_eval = EVAL_NULL;
545 PL_comppad = 0; 546 PL_comppad = 0;
546 PL_curpm = 0; 547 PL_curpm = 0;
569 570
570 ENTER; /* necessary e.g. for dounwind */ 571 ENTER; /* necessary e.g. for dounwind */
571} 572}
572 573
573static void 574static void
574free_coro_mortal () 575free_coro_mortal (pTHX)
575{ 576{
576 if (coro_mortal) 577 if (coro_mortal)
577 { 578 {
578 SvREFCNT_dec (coro_mortal); 579 SvREFCNT_dec (coro_mortal);
579 coro_mortal = 0; 580 coro_mortal = 0;
580 } 581 }
581} 582}
582 583
583/* inject a fake call to Coro::State::_cctx_init into the execution */ 584/* inject a fake call to Coro::State::_cctx_init into the execution */
584static void NOINLINE 585static void NOINLINE
585prepare_cctx (coro_cctx *cctx) 586prepare_cctx (pTHX_ coro_cctx *cctx)
586{ 587{
587 dSP; 588 dSP;
588 LOGOP myop; 589 LOGOP myop;
589 590
590 Zero (&myop, 1, LOGOP); 591 Zero (&myop, 1, LOGOP);
602} 603}
603 604
604static void 605static void
605coro_run (void *arg) 606coro_run (void *arg)
606{ 607{
608 dTHX;
609
607 /* coro_run is the alternative tail of transfer(), so unlock here. */ 610 /* coro_run is the alternative tail of transfer(), so unlock here. */
608 UNLOCK; 611 UNLOCK;
609 612
610 /* 613 /*
611 * this is a _very_ stripped down perl interpreter ;) 614 * this is a _very_ stripped down perl interpreter ;)
612 */ 615 */
613 PL_top_env = &PL_start_env; 616 PL_top_env = &PL_start_env;
614 617
615 /* inject call to cctx_init */ 618 /* inject call to cctx_init */
616 prepare_cctx ((coro_cctx *)arg); 619 prepare_cctx (aTHX_ (coro_cctx *)arg);
617 620
618 /* somebody will hit me for both perl_run and PL_restartop */ 621 /* somebody will hit me for both perl_run and PL_restartop */
619 PL_restartop = PL_op; 622 PL_restartop = PL_op;
620 perl_run (PL_curinterp); 623 perl_run (PL_curinterp);
621 624
692 695
693 Safefree (cctx); 696 Safefree (cctx);
694} 697}
695 698
696static coro_cctx * 699static coro_cctx *
697cctx_get () 700cctx_get (pTHX)
698{ 701{
699 while (cctx_first) 702 while (cctx_first)
700 { 703 {
701 coro_cctx *cctx = cctx_first; 704 coro_cctx *cctx = cctx_first;
702 cctx_first = cctx->next; 705 cctx_first = cctx->next;
733 736
734/** coroutine switching *****************************************************/ 737/** coroutine switching *****************************************************/
735 738
736/* never call directly, always through the coro_state_transfer global variable */ 739/* never call directly, always through the coro_state_transfer global variable */
737static void NOINLINE 740static void NOINLINE
738transfer (struct coro *prev, struct coro *next) 741transfer (pTHX_ struct coro *prev, struct coro *next)
739{ 742{
740 dSTACKLEVEL; 743 dSTACKLEVEL;
741 744
742 /* sometimes transfer is only called to set idle_sp */ 745 /* sometimes transfer is only called to set idle_sp */
743 if (!next) 746 if (!next)
776 if (next->flags & CF_NEW) 779 if (next->flags & CF_NEW)
777 { 780 {
778 /* need to start coroutine */ 781 /* need to start coroutine */
779 next->flags &= ~CF_NEW; 782 next->flags &= ~CF_NEW;
780 /* first get rid of the old state */ 783 /* first get rid of the old state */
781 save_perl (prev); 784 save_perl (aTHX_ prev);
782 /* setup coroutine call */ 785 /* setup coroutine call */
783 setup_coro (next); 786 setup_coro (aTHX_ next);
784 /* need a new stack */ 787 /* need a new stack */
785 assert (!next->cctx); 788 assert (!next->cctx);
786 } 789 }
787 else 790 else
788 { 791 {
789 /* coroutine already started */ 792 /* coroutine already started */
790 save_perl (prev); 793 save_perl (aTHX_ prev);
791 load_perl (next); 794 load_perl (aTHX_ next);
792 } 795 }
793 796
794 prev__cctx = prev->cctx; 797 prev__cctx = prev->cctx;
795 798
796 /* possibly "free" the cctx */ 799 /* possibly "free" the cctx */
805 prev__cctx->inuse = 0; 808 prev__cctx->inuse = 0;
806 } 809 }
807 810
808 if (!next->cctx) 811 if (!next->cctx)
809 { 812 {
810 next->cctx = cctx_get (); 813 next->cctx = cctx_get (aTHX);
811 assert (!next->cctx->inuse); 814 assert (!next->cctx->inuse);
812 next->cctx->inuse = 1; 815 next->cctx->inuse = 1;
813 } 816 }
814 817
815 if (prev__cctx != next->cctx) 818 if (prev__cctx != next->cctx)
817 prev__cctx->top_env = PL_top_env; 820 prev__cctx->top_env = PL_top_env;
818 PL_top_env = next->cctx->top_env; 821 PL_top_env = next->cctx->top_env;
819 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx); 822 coro_transfer (&prev__cctx->cctx, &next->cctx->cctx);
820 } 823 }
821 824
822 free_coro_mortal (); 825 free_coro_mortal (aTHX);
823 UNLOCK; 826 UNLOCK;
824 } 827 }
825} 828}
826 829
827struct transfer_args 830struct transfer_args
828{ 831{
829 struct coro *prev, *next; 832 struct coro *prev, *next;
830}; 833};
831 834
832#define TRANSFER(ta) transfer ((ta).prev, (ta).next) 835#define TRANSFER(ta) transfer (aTHX_ (ta).prev, (ta).next)
833 836
834/** high level stuff ********************************************************/ 837/** high level stuff ********************************************************/
835 838
836static int 839static int
837coro_state_destroy (struct coro *coro) 840coro_state_destroy (pTHX_ struct coro *coro)
838{ 841{
839 if (coro->flags & CF_DESTROYED) 842 if (coro->flags & CF_DESTROYED)
840 return 0; 843 return 0;
841 844
842 coro->flags |= CF_DESTROYED; 845 coro->flags |= CF_DESTROYED;
862 temp.save = CORO_SAVE_ALL; 865 temp.save = CORO_SAVE_ALL;
863 866
864 if (coro->flags & CF_RUNNING) 867 if (coro->flags & CF_RUNNING)
865 croak ("FATAL: tried to destroy currently running coroutine"); 868 croak ("FATAL: tried to destroy currently running coroutine");
866 869
867 save_perl (&temp); 870 save_perl (aTHX_ &temp);
868 load_perl (coro); 871 load_perl (aTHX_ coro);
869 872
870 coro_destroy_stacks (); 873 coro_destroy_stacks (aTHX);
871 874
872 load_perl (&temp); /* this will get rid of defsv etc.. */ 875 load_perl (aTHX_ &temp); /* this will get rid of defsv etc.. */
873 876
874 coro->mainstack = 0; 877 coro->mainstack = 0;
875 } 878 }
876 879
877 cctx_destroy (coro->cctx); 880 cctx_destroy (coro->cctx);
886 struct coro *coro = (struct coro *)mg->mg_ptr; 889 struct coro *coro = (struct coro *)mg->mg_ptr;
887 mg->mg_ptr = 0; 890 mg->mg_ptr = 0;
888 891
889 if (--coro->refcnt < 0) 892 if (--coro->refcnt < 0)
890 { 893 {
891 coro_state_destroy (coro); 894 coro_state_destroy (aTHX_ coro);
892 Safefree (coro); 895 Safefree (coro);
893 } 896 }
894 897
895 return 0; 898 return 0;
896} 899}
915# define MGf_DUP 0 918# define MGf_DUP 0
916#endif 919#endif
917}; 920};
918 921
919static struct coro * 922static struct coro *
920SvSTATE (SV *coro) 923SvSTATE_ (pTHX_ SV *coro)
921{ 924{
922 HV *stash; 925 HV *stash;
923 MAGIC *mg; 926 MAGIC *mg;
924 927
925 if (SvROK (coro)) 928 if (SvROK (coro))
935 938
936 mg = CORO_MAGIC (coro); 939 mg = CORO_MAGIC (coro);
937 return (struct coro *)mg->mg_ptr; 940 return (struct coro *)mg->mg_ptr;
938} 941}
939 942
943#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv))
944
940static void 945static void
941prepare_transfer (struct transfer_args *ta, SV *prev_sv, SV *next_sv) 946prepare_transfer (pTHX_ struct transfer_args *ta, SV *prev_sv, SV *next_sv)
942{ 947{
943 ta->prev = SvSTATE (prev_sv); 948 ta->prev = SvSTATE (prev_sv);
944 ta->next = SvSTATE (next_sv); 949 ta->next = SvSTATE (next_sv);
945} 950}
946 951
947static void 952static void
948api_transfer (SV *prev_sv, SV *next_sv) 953api_transfer (SV *prev_sv, SV *next_sv)
949{ 954{
955 dTHX;
950 struct transfer_args ta; 956 struct transfer_args ta;
951 957
952 prepare_transfer (&ta, prev_sv, next_sv); 958 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
953 TRANSFER (ta); 959 TRANSFER (ta);
954} 960}
955 961
956static int 962static int
957api_save (SV *coro_sv, int new_save) 963api_save (SV *coro_sv, int new_save)
958{ 964{
965 dTHX;
959 struct coro *coro = SvSTATE (coro_sv); 966 struct coro *coro = SvSTATE (coro_sv);
960 int old_save = coro->save; 967 int old_save = coro->save;
961 968
962 if (new_save >= 0) 969 if (new_save >= 0)
963 coro->save = new_save; 970 coro->save = new_save;
966} 973}
967 974
968/** Coro ********************************************************************/ 975/** Coro ********************************************************************/
969 976
970static void 977static void
971coro_enq (SV *coro_sv) 978coro_enq (pTHX_ SV *coro_sv)
972{ 979{
973 av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv); 980 av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv);
974} 981}
975 982
976static SV * 983static SV *
977coro_deq (int min_prio) 984coro_deq (pTHX_ int min_prio)
978{ 985{
979 int prio = PRIO_MAX - PRIO_MIN; 986 int prio = PRIO_MAX - PRIO_MIN;
980 987
981 min_prio -= PRIO_MIN; 988 min_prio -= PRIO_MIN;
982 if (min_prio < 0) 989 if (min_prio < 0)
990} 997}
991 998
992static int 999static int
993api_ready (SV *coro_sv) 1000api_ready (SV *coro_sv)
994{ 1001{
1002 dTHX;
995 struct coro *coro; 1003 struct coro *coro;
996 1004
997 if (SvROK (coro_sv)) 1005 if (SvROK (coro_sv))
998 coro_sv = SvRV (coro_sv); 1006 coro_sv = SvRV (coro_sv);
999 1007
1003 return 0; 1011 return 0;
1004 1012
1005 coro->flags |= CF_READY; 1013 coro->flags |= CF_READY;
1006 1014
1007 LOCK; 1015 LOCK;
1008 coro_enq (SvREFCNT_inc (coro_sv)); 1016 coro_enq (aTHX_ SvREFCNT_inc (coro_sv));
1009 ++coro_nready; 1017 ++coro_nready;
1010 UNLOCK; 1018 UNLOCK;
1011 1019
1012 return 1; 1020 return 1;
1013} 1021}
1014 1022
1015static int 1023static int
1016api_is_ready (SV *coro_sv) 1024api_is_ready (SV *coro_sv)
1017{ 1025{
1026 dTHX;
1018 return !!(SvSTATE (coro_sv)->flags & CF_READY); 1027 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1019} 1028}
1020 1029
1021static void 1030static void
1022prepare_schedule (struct transfer_args *ta) 1031prepare_schedule (pTHX_ struct transfer_args *ta)
1023{ 1032{
1024 SV *prev_sv, *next_sv; 1033 SV *prev_sv, *next_sv;
1025 1034
1026 for (;;) 1035 for (;;)
1027 { 1036 {
1028 LOCK; 1037 LOCK;
1029 next_sv = coro_deq (PRIO_MIN); 1038 next_sv = coro_deq (aTHX_ PRIO_MIN);
1030 1039
1031 /* nothing to schedule: call the idle handler */ 1040 /* nothing to schedule: call the idle handler */
1032 if (!next_sv) 1041 if (!next_sv)
1033 { 1042 {
1034 dSP; 1043 dSP;
1069 1078
1070 assert (ta->next->flags & CF_READY); 1079 assert (ta->next->flags & CF_READY);
1071 ta->next->flags &= ~CF_READY; 1080 ta->next->flags &= ~CF_READY;
1072 1081
1073 LOCK; 1082 LOCK;
1074 free_coro_mortal (); 1083 free_coro_mortal (aTHX);
1075 coro_mortal = prev_sv; 1084 coro_mortal = prev_sv;
1076 UNLOCK; 1085 UNLOCK;
1077} 1086}
1078 1087
1079static void 1088static void
1080prepare_cede (struct transfer_args *ta) 1089prepare_cede (pTHX_ struct transfer_args *ta)
1081{ 1090{
1082 api_ready (coro_current); 1091 api_ready (coro_current);
1083 prepare_schedule (ta); 1092 prepare_schedule (aTHX_ ta);
1084} 1093}
1085 1094
1086static int 1095static int
1087prepare_cede_notself (struct transfer_args *ta) 1096prepare_cede_notself (pTHX_ struct transfer_args *ta)
1088{ 1097{
1089 if (coro_nready) 1098 if (coro_nready)
1090 { 1099 {
1091 SV *prev = SvRV (coro_current); 1100 SV *prev = SvRV (coro_current);
1092 prepare_schedule (ta); 1101 prepare_schedule (aTHX_ ta);
1093 api_ready (prev); 1102 api_ready (prev);
1094 return 1; 1103 return 1;
1095 } 1104 }
1096 else 1105 else
1097 return 0; 1106 return 0;
1098} 1107}
1099 1108
1100static void 1109static void
1101api_schedule (void) 1110api_schedule (void)
1102{ 1111{
1112 dTHX;
1103 struct transfer_args ta; 1113 struct transfer_args ta;
1104 1114
1105 prepare_schedule (&ta); 1115 prepare_schedule (aTHX_ &ta);
1106 TRANSFER (ta); 1116 TRANSFER (ta);
1107} 1117}
1108 1118
1109static int 1119static int
1110api_cede (void) 1120api_cede (void)
1111{ 1121{
1122 dTHX;
1112 struct transfer_args ta; 1123 struct transfer_args ta;
1113 1124
1114 prepare_cede (&ta); 1125 prepare_cede (aTHX_ &ta);
1115 1126
1116 if (ta.prev != ta.next) 1127 if (ta.prev != ta.next)
1117 { 1128 {
1118 TRANSFER (ta); 1129 TRANSFER (ta);
1119 return 1; 1130 return 1;
1123} 1134}
1124 1135
1125static int 1136static int
1126api_cede_notself (void) 1137api_cede_notself (void)
1127{ 1138{
1139 dTHX;
1128 struct transfer_args ta; 1140 struct transfer_args ta;
1129 1141
1130 if (prepare_cede_notself (&ta)) 1142 if (prepare_cede_notself (aTHX_ &ta))
1131 { 1143 {
1132 TRANSFER (ta); 1144 TRANSFER (ta);
1133 return 1; 1145 return 1;
1134 } 1146 }
1135 else 1147 else
1213 1225
1214 case 1: 1226 case 1:
1215 if (items != 2) 1227 if (items != 2)
1216 croak ("Coro::State::transfer (prev,next) expects two arguments, not %d", items); 1228 croak ("Coro::State::transfer (prev,next) expects two arguments, not %d", items);
1217 1229
1218 prepare_transfer (&ta, ST (0), ST (1)); 1230 prepare_transfer (aTHX_ &ta, ST (0), ST (1));
1219 break; 1231 break;
1220 1232
1221 case 2: 1233 case 2:
1222 prepare_schedule (&ta); 1234 prepare_schedule (aTHX_ &ta);
1223 break; 1235 break;
1224 1236
1225 case 3: 1237 case 3:
1226 prepare_cede (&ta); 1238 prepare_cede (aTHX_ &ta);
1227 break; 1239 break;
1228 1240
1229 case 4: 1241 case 4:
1230 if (!prepare_cede_notself (&ta)) 1242 if (!prepare_cede_notself (aTHX_ &ta))
1231 XSRETURN_EMPTY; 1243 XSRETURN_EMPTY;
1232 1244
1233 break; 1245 break;
1234 } 1246 }
1235 1247
1241} 1253}
1242 1254
1243bool 1255bool
1244_destroy (SV *coro_sv) 1256_destroy (SV *coro_sv)
1245 CODE: 1257 CODE:
1246 RETVAL = coro_state_destroy (SvSTATE (coro_sv)); 1258 RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv));
1247 OUTPUT: 1259 OUTPUT:
1248 RETVAL 1260 RETVAL
1249 1261
1250void 1262void
1251_exit (code) 1263_exit (code)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines