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.23 by root, Tue Aug 14 04:33:58 2001 UTC vs.
Revision 1.27 by root, Mon Aug 20 16:58:19 2001 UTC

195 195
196 return newpadlist; 196 return newpadlist;
197} 197}
198 198
199#ifdef MAY_FLUSH 199#ifdef MAY_FLUSH
200STATIC AV * 200STATIC void
201free_padlist (AV *padlist) 201free_padlist (AV *padlist)
202{ 202{
203 /* may be during global destruction */ 203 /* may be during global destruction */
204 if (SvREFCNT(padlist)) 204 if (SvREFCNT(padlist))
205 { 205 {
514 dSP; 514 dSP;
515 SWITCHSTACK (PL_curstack, PL_curstackinfo->si_stack); 515 SWITCHSTACK (PL_curstack, PL_curstackinfo->si_stack);
516 PUTBACK; /* possibly superfluous */ 516 PUTBACK; /* possibly superfluous */
517 } 517 }
518 518
519 if (PL_main_cv != Nullcv) /* don't during destruction. hack? */
519 dounwind(-1); 520 dounwind(-1);
520 521
521 SvREFCNT_dec(PL_curstackinfo->si_stack); 522 SvREFCNT_dec(PL_curstackinfo->si_stack);
522 Safefree(PL_curstackinfo->si_cxstack); 523 Safefree(PL_curstackinfo->si_cxstack);
523 Safefree(PL_curstackinfo); 524 Safefree(PL_curstackinfo);
524 PL_curstackinfo = p; 525 PL_curstackinfo = p;
753 } 754 }
754 755
755 /* must also be changed inside Coro::Cont::yield */ 756 /* must also be changed inside Coro::Cont::yield */
756 if (SvROK(arg) && SvSTASH(SvRV(arg)) == coro_state_stash) 757 if (SvROK(arg) && SvSTASH(SvRV(arg)) == coro_state_stash)
757 return (struct coro *) SvIV((SV*)SvRV(arg)); 758 return (struct coro *) SvIV((SV*)SvRV(arg));
758 else 759
759 croak ("%s() -- %s is not (and contains not) a Coro::State object", funcname, varname); 760 croak ("%s() -- %s is not (and contains not) a Coro::State object", funcname, varname);
761 /*NORETURN*/
760} 762}
761 763
762static void 764static void
763api_transfer(pTHX_ SV *prev, SV *next, int flags) 765api_transfer(pTHX_ SV *prev, SV *next, int flags)
764{ 766{
767 transfer(aTHX_
765 transfer(aTHX_ sv_to_coro (prev, "Coro::transfer", "prev"), 768 sv_to_coro (prev, "Coro::transfer", "prev"),
766 sv_to_coro (next, "Coro::transfer", "next"), 769 sv_to_coro (next, "Coro::transfer", "next"),
767 flags); 770 flags);
768} 771}
769 772
770/** Coro ********************************************************************/ 773/** Coro ********************************************************************/
771 774
772#define PRIO_MAX 3 775#define PRIO_MAX 3
777#define PRIO_MIN -4 780#define PRIO_MIN -4
778 781
779/* for Coro.pm */ 782/* for Coro.pm */
780static GV *coro_current, *coro_idle; 783static GV *coro_current, *coro_idle;
781static AV *coro_ready[PRIO_MAX-PRIO_MIN+1]; 784static AV *coro_ready[PRIO_MAX-PRIO_MIN+1];
785static int coro_nready;
782 786
783static void 787static void
784coro_enq (SV *sv) 788coro_enq (SV *sv)
785{ 789{
786 if (SvROK (sv)) 790 if (SvROK (sv))
794 prio = prio > PRIO_MAX ? PRIO_MAX 798 prio = prio > PRIO_MAX ? PRIO_MAX
795 : prio < PRIO_MIN ? PRIO_MIN 799 : prio < PRIO_MIN ? PRIO_MIN
796 : prio; 800 : prio;
797 801
798 av_push (coro_ready [prio - PRIO_MIN], sv); 802 av_push (coro_ready [prio - PRIO_MIN], sv);
803 coro_nready++;
799 804
800 return; 805 return;
801 } 806 }
802 } 807 }
803 808
813 if (min_prio < 0) 818 if (min_prio < 0)
814 min_prio = 0; 819 min_prio = 0;
815 820
816 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; ) 821 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; )
817 if (av_len (coro_ready[prio]) >= 0) 822 if (av_len (coro_ready[prio]) >= 0)
823 {
824 coro_nready--;
818 return av_shift (coro_ready[prio]); 825 return av_shift (coro_ready[prio]);
826 }
819 827
820 return 0; 828 return 0;
821} 829}
822 830
823static void 831static void
840 848
841 if (!next) 849 if (!next)
842 next = SvREFCNT_inc (GvSV (coro_idle)); 850 next = SvREFCNT_inc (GvSV (coro_idle));
843 851
844 GvSV (coro_current) = SvREFCNT_inc (next); 852 GvSV (coro_current) = SvREFCNT_inc (next);
853 transfer (aTHX_
845 transfer (sv_to_coro (prev, "Coro::schedule", "current coroutine"), 854 sv_to_coro (prev, "Coro::schedule", "current coroutine"),
846 sv_to_coro (next, "Coro::schedule", "next coroutine"), 855 sv_to_coro (next, "Coro::schedule", "next coroutine"),
847 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK); 856 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK);
848 SvREFCNT_dec (next); 857 SvREFCNT_dec (next);
849 SvREFCNT_dec (prev); 858 SvREFCNT_dec (prev);
850} 859}
867 if (!padlist_cache) 876 if (!padlist_cache)
868 padlist_cache = newHV (); 877 padlist_cache = newHV ();
869 878
870 main_mainstack = PL_mainstack; 879 main_mainstack = PL_mainstack;
871 880
872 {
873 SV *sv = perl_get_sv("Coro::API", 1);
874
875 coroapi.ver = CORO_API_VERSION - 1; 881 coroapi.ver = CORO_API_VERSION;
876 coroapi.transfer = api_transfer; 882 coroapi.transfer = api_transfer;
877 coroapi.schedule = api_schedule;
878 coroapi.ready = api_ready;
879
880 GCoroAPI = &coroapi;
881 sv_setiv(sv, (IV)&coroapi);
882 SvREADONLY_on(sv);
883 }
884} 883}
885 884
886Coro::State 885Coro::State
887_newprocess(args) 886_newprocess(args)
888 SV * args 887 SV * args
1006 coro_current = gv_fetchpv ("Coro::current", TRUE, SVt_PV); 1005 coro_current = gv_fetchpv ("Coro::current", TRUE, SVt_PV);
1007 coro_idle = gv_fetchpv ("Coro::idle" , TRUE, SVt_PV); 1006 coro_idle = gv_fetchpv ("Coro::idle" , TRUE, SVt_PV);
1008 1007
1009 for (i = PRIO_MAX - PRIO_MIN + 1; i--; ) 1008 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
1010 coro_ready[i] = newAV (); 1009 coro_ready[i] = newAV ();
1010
1011 {
1012 SV *sv = perl_get_sv("Coro::API", 1);
1013
1014 coroapi.schedule = api_schedule;
1015 coroapi.ready = api_ready;
1016 coroapi.nready = &coro_nready;
1017 coroapi.current = coro_current;
1018
1019 GCoroAPI = &coroapi;
1020 sv_setiv(sv, (IV)&coroapi);
1021 SvREADONLY_on(sv);
1022 }
1011} 1023}
1012 1024
1013void 1025void
1014ready(self) 1026ready(self)
1015 SV * self 1027 SV * self
1016 CODE: 1028 CODE:
1017 api_ready (self); 1029 api_ready (self);
1018 1030
1031int
1032nready(...)
1033 PROTOTYPE:
1034 CODE:
1035 RETVAL = coro_nready;
1036 OUTPUT:
1037 RETVAL
1038
1019void 1039void
1020schedule(...) 1040schedule(...)
1041 PROTOTYPE:
1021 ALIAS: 1042 ALIAS:
1022 cede = 1 1043 cede = 1
1023 CODE: 1044 CODE:
1024 api_schedule (ix); 1045 api_schedule (ix);
1025 1046

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines