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.21 by root, Sat Aug 11 19:59:19 2001 UTC vs.
Revision 1.22 by root, Sat Aug 11 23:10:56 2001 UTC

110static AV *main_mainstack; /* used to differentiate between $main and others */ 110static AV *main_mainstack; /* used to differentiate between $main and others */
111static HV *coro_state_stash; 111static HV *coro_state_stash;
112static SV *ucoro_state_sv; 112static SV *ucoro_state_sv;
113static U32 ucoro_state_hash; 113static U32 ucoro_state_hash;
114static HV *padlist_cache; 114static HV *padlist_cache;
115
116/* for Coro.pm */
117static GV *coro_current, *coro_idle;
118static AV *coro_ready;
119 115
120/* mostly copied from op.c:cv_clone2 */ 116/* mostly copied from op.c:cv_clone2 */
121STATIC AV * 117STATIC AV *
122clone_padlist (AV *protopadlist) 118clone_padlist (AV *protopadlist)
123{ 119{
772 return (struct coro *) SvIV((SV*)SvRV(arg)); 768 return (struct coro *) SvIV((SV*)SvRV(arg));
773 else 769 else
774 croak ("%s() -- %s is not (and contains not) a Coro::State object", funcname, varname); 770 croak ("%s() -- %s is not (and contains not) a Coro::State object", funcname, varname);
775} 771}
776 772
773/** Coro ********************************************************************/
774
775#define PRIO_MAX 3
776#define PRIO_HIGH 1
777#define PRIO_NORMAL 0
778#define PRIO_LOW -1
779#define PRIO_IDLE -3
780#define PRIO_MIN -4
781
782/* for Coro.pm */
783static GV *coro_current, *coro_idle;
784static AV *coro_ready[PRIO_MAX-PRIO_MIN+1];
785
786static void
787coro_enq (SV *sv)
788{
789 if (SvROK (sv))
790 {
791 SV *hv = SvRV (sv);
792 if (SvTYPE (hv) == SVt_PVHV)
793 {
794 SV **xprio = hv_fetch ((HV *)hv, "prio", 4, 0);
795 int prio = xprio ? SvIV (*xprio) : PRIO_NORMAL;
796
797 prio = prio > PRIO_MAX ? PRIO_MAX
798 : prio < PRIO_MIN ? PRIO_MIN
799 : prio;
800
801 av_push (coro_ready [prio - PRIO_MIN], sv);
802
803 return;
804 }
805 }
806
807 croak ("Coro::ready tried to enqueue something that is not a coroutine");
808}
809
810static SV *
811coro_deq (int min_prio)
812{
813 int prio = PRIO_MAX - PRIO_MIN;
814
815 min_prio -= PRIO_MIN;
816 if (min_prio < 0)
817 min_prio = 0;
818
819 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; )
820 if (av_len (coro_ready[prio]) >= 0)
821 return av_shift (coro_ready[prio]);
822
823 return 0;
824}
825
777MODULE = Coro::State PACKAGE = Coro::State 826MODULE = Coro::State PACKAGE = Coro::State
778 827
779PROTOTYPES: ENABLE 828PROTOTYPES: ENABLE
780 829
781BOOT: 830BOOT:
903 952
904# this is slightly dirty (should expose a c-level api) 953# this is slightly dirty (should expose a c-level api)
905 954
906BOOT: 955BOOT:
907{ 956{
957 int i;
958 HV *stash = gv_stashpv ("Coro", TRUE);
959
960 newCONSTSUB (stash, "PRIO_MAX", newSViv (PRIO_MAX));
961 newCONSTSUB (stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
962 newCONSTSUB (stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
963 newCONSTSUB (stash, "PRIO_LOW", newSViv (PRIO_LOW));
964 newCONSTSUB (stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
965 newCONSTSUB (stash, "PRIO_MIN", newSViv (PRIO_MIN));
966
908 coro_current = gv_fetchpv ("Coro::current", TRUE, SVt_PV); 967 coro_current = gv_fetchpv ("Coro::current", TRUE, SVt_PV);
909 coro_ready = newAV ();
910 coro_idle = gv_fetchpv ("Coro::idle" , TRUE, SVt_PV); 968 coro_idle = gv_fetchpv ("Coro::idle" , TRUE, SVt_PV);
969
970 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
971 coro_ready[i] = newAV ();
911} 972}
912 973
913void 974void
914ready(self) 975ready(self)
915 SV * self 976 SV * self
916 CODE: 977 CODE:
917 av_push (coro_ready, SvREFCNT_inc (self)); 978 coro_enq (SvREFCNT_inc (self));
918 979
919void 980void
920schedule(...) 981schedule(...)
921 ALIAS: 982 ALIAS:
922 cede = 1 983 cede = 1
923 CODE: 984 CODE:
985 SV *prev, *next;
986
924 SV *prev = GvSV (coro_current); 987 prev = GvSV (coro_current);
925 SV *next = av_shift (coro_ready);
926 988
927 if (next == &PL_sv_undef) 989 if (ix)
990 coro_enq (SvREFCNT_inc (prev));
991
992 next = coro_deq (PRIO_MIN);
993
994 if (!next)
928 next = SvREFCNT_inc (GvSV (coro_idle)); 995 next = SvREFCNT_inc (GvSV (coro_idle));
929
930 if (ix)
931 av_push (coro_ready, SvREFCNT_inc (prev));
932 996
933 GvSV (coro_current) = SvREFCNT_inc (next); 997 GvSV (coro_current) = SvREFCNT_inc (next);
934 transfer (sv_to_coro (prev, "Coro::schedule", "current coroutine"), 998 transfer (sv_to_coro (prev, "Coro::schedule", "current coroutine"),
935 sv_to_coro (next, "Coro::schedule", "next coroutine"), 999 sv_to_coro (next, "Coro::schedule", "next coroutine"),
936 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK); 1000 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines