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.81 by root, Fri Nov 3 00:56:03 2006 UTC vs.
Revision 1.86 by root, Fri Nov 24 11:36:57 2006 UTC

667 CALLRUNOPS(aTHX); 667 CALLRUNOPS(aTHX);
668 668
669 abort (); 669 abort ();
670} 670}
671 671
672/* never call directly, always through the coro_state_transfer global variable */
672static void 673static void
673transfer (pTHX_ struct coro *prev, struct coro *next, int flags) 674transfer_impl (pTHX_ struct coro *prev, struct coro *next, int flags)
674{ 675{
675 dSTACKLEVEL; 676 dSTACKLEVEL;
676 677
677 if (prev != next) 678 if (prev != next)
678 { 679 {
771 coro_mortal = 0; 772 coro_mortal = 0;
772 } 773 }
773 UNLOCK; 774 UNLOCK;
774} 775}
775 776
777/* use this function pointer to call the above function */
778/* this is done to increase chances of the compiler not inlining the call */
779void (*coro_state_transfer)(pTHX_ struct coro *prev, struct coro *next, int flags) = transfer_impl;
780
776#define SV_CORO(sv,func) \ 781#define SV_CORO(sv,func) \
777 do { \ 782 do { \
778 if (SvROK (sv)) \ 783 if (SvROK (sv)) \
779 sv = SvRV (sv); \ 784 sv = SvRV (sv); \
780 \ 785 \
792 if (!SvOBJECT (sv) || SvSTASH (sv) != coro_state_stash) \ 797 if (!SvOBJECT (sv) || SvSTASH (sv) != coro_state_stash) \
793 croak ("%s() -- %s is not (and contains not) a Coro::State object", func, # sv); \ 798 croak ("%s() -- %s is not (and contains not) a Coro::State object", func, # sv); \
794 \ 799 \
795 } while(0) 800 } while(0)
796 801
797#define SvSTATE(sv) INT2PTR (struct coro *, SvIV (sv)) 802#define SvSTATE(sv) INT2PTR (struct coro *, SvIVX (sv))
798 803
799static void 804static void
800api_transfer(pTHX_ SV *prev, SV *next, int flags) 805api_transfer (pTHX_ SV *prev, SV *next, int flags)
801{ 806{
802 SV_CORO (prev, "Coro::transfer"); 807 SV_CORO (prev, "Coro::transfer");
803 SV_CORO (next, "Coro::transfer"); 808 SV_CORO (next, "Coro::transfer");
804 809
805 transfer (aTHX_ SvSTATE (prev), SvSTATE (next), flags); 810 coro_state_transfer (aTHX_ SvSTATE (prev), SvSTATE (next), flags);
806} 811}
807 812
808/** Coro ********************************************************************/ 813/** Coro ********************************************************************/
809 814
810#define PRIO_MAX 3 815#define PRIO_MAX 3
814#define PRIO_IDLE -3 819#define PRIO_IDLE -3
815#define PRIO_MIN -4 820#define PRIO_MIN -4
816 821
817/* for Coro.pm */ 822/* for Coro.pm */
818static GV *coro_current, *coro_idle; 823static GV *coro_current, *coro_idle;
819static AV *coro_ready[PRIO_MAX-PRIO_MIN+1]; 824static AV *coro_ready [PRIO_MAX-PRIO_MIN+1];
820static int coro_nready; 825static int coro_nready;
821 826
822static void 827static void
823coro_enq (pTHX_ SV *sv) 828coro_enq (pTHX_ SV *sv)
824{ 829{
847 min_prio -= PRIO_MIN; 852 min_prio -= PRIO_MIN;
848 if (min_prio < 0) 853 if (min_prio < 0)
849 min_prio = 0; 854 min_prio = 0;
850 855
851 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; ) 856 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; )
852 if (av_len (coro_ready[prio]) >= 0) 857 if (AvFILLp (coro_ready [prio]) >= 0)
853 { 858 {
854 coro_nready--; 859 coro_nready--;
855 return av_shift (coro_ready[prio]); 860 return av_shift (coro_ready [prio]);
856 } 861 }
857 862
858 return 0; 863 return 0;
859} 864}
860 865
894 899
895 SV_CORO (next, "Coro::schedule"); 900 SV_CORO (next, "Coro::schedule");
896 901
897 UNLOCK; 902 UNLOCK;
898 903
899 transfer (aTHX_ SvSTATE (prev), SvSTATE (next), 904 coro_state_transfer (aTHX_ SvSTATE (prev), SvSTATE (next),
900 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK); 905 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK);
901} 906}
902 907
903static void 908static void
904api_cede (void) 909api_cede (void)
905{ 910{
937 coroapi.ver = CORO_API_VERSION; 942 coroapi.ver = CORO_API_VERSION;
938 coroapi.transfer = api_transfer; 943 coroapi.transfer = api_transfer;
939} 944}
940 945
941Coro::State 946Coro::State
942_newprocess(args) 947new (char *klass, ...)
943 SV * args
944 PROTOTYPE: $ 948 PROTOTYPE: $@
945 CODE: 949 CODE:
950{
946 Coro__State coro; 951 Coro__State coro;
952 int i;
947 953
948 if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) 954 if (!SvOK (ST (1)))
949 croak ("Coro::State::_newprocess expects an arrayref"); 955 croak ("Coro::State::new needs something callable as first argument");
950 956
951 Newz (0, coro, 1, struct coro); 957 Newz (0, coro, 1, struct coro);
958 coro->args = newAV ();
952 959
953 coro->args = (AV *)SvREFCNT_inc (SvRV (args)); 960 for (i = 1; i < items; i++)
961 av_push (coro->args, newSVsv (ST (i)));
962
963 RETVAL = coro;
964
954 /*coro->mainstack = 0; *//*actual work is done inside transfer */ 965 /*coro->mainstack = 0; *//*actual work is done inside transfer */
955 /*coro->stack = 0;*/ 966 /*coro->stack = 0;*/
956 967}
957 RETVAL = coro;
958 OUTPUT: 968 OUTPUT:
959 RETVAL 969 RETVAL
960 970
961void 971void
962transfer(prev, next, flags) 972transfer(prev, next, flags)
966 PROTOTYPE: @ 976 PROTOTYPE: @
967 CODE: 977 CODE:
968 PUTBACK; 978 PUTBACK;
969 SV_CORO (next, "Coro::transfer"); 979 SV_CORO (next, "Coro::transfer");
970 SV_CORO (prev, "Coro::transfer"); 980 SV_CORO (prev, "Coro::transfer");
971 transfer (aTHX_ SvSTATE (prev), SvSTATE (next), flags); 981 coro_state_transfer (aTHX_ SvSTATE (prev), SvSTATE (next), flags);
972 SPAGAIN; 982 SPAGAIN;
973 983
974void 984void
975DESTROY(coro) 985DESTROY(coro)
976 Coro::State coro 986 Coro::State coro
1026 av_fill (defav, items - 1); 1036 av_fill (defav, items - 1);
1027 while (items--) 1037 while (items--)
1028 av_store (defav, items, SvREFCNT_inc (ST(items))); 1038 av_store (defav, items, SvREFCNT_inc (ST(items)));
1029 1039
1030 sv = av_pop ((AV *)SvRV (yieldstack)); 1040 sv = av_pop ((AV *)SvRV (yieldstack));
1031 prev = INT2PTR (struct coro *, SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 0, 0)))); 1041 prev = SvSTATE ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 0, 0)));
1032 next = INT2PTR (struct coro *, SvIV ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 1, 0)))); 1042 next = SvSTATE ((SV*)SvRV (*av_fetch ((AV *)SvRV (sv), 1, 0)));
1033 SvREFCNT_dec (sv); 1043 SvREFCNT_dec (sv);
1034 1044
1035 transfer (aTHX_ prev, next, 0); 1045 coro_state_transfer (aTHX_ prev, next, 0);
1036 1046
1037MODULE = Coro::State PACKAGE = Coro 1047MODULE = Coro::State PACKAGE = Coro
1038 1048
1039BOOT: 1049BOOT:
1040{ 1050{

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines