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.22 by root, Sat Aug 11 23:10:56 2001 UTC vs.
Revision 1.23 by root, Tue Aug 14 04:33:58 2001 UTC

18# endif 18# endif
19#endif 19#endif
20 20
21#define MAY_FLUSH /* increases codesize */ 21#define MAY_FLUSH /* increases codesize */
22 22
23/* perl-related */
24#define TRANSFER_SAVE_DEFAV 0x00000001
25#define TRANSFER_SAVE_DEFSV 0x00000002
26#define TRANSFER_SAVE_ERRSV 0x00000004
27/* c-related */
28#define TRANSFER_SAVE_CCTXT 0x00000008
29#ifdef CORO_LAZY_STACK
30# define TRANSFER_LAZY_STACK 0x00000010
31#else
32# define TRANSFER_LAZY_STACK 0x00000000
33#endif
34
35#define TRANSFER_SAVE_ALL (TRANSFER_SAVE_DEFAV|TRANSFER_SAVE_DEFSV \
36 |TRANSFER_SAVE_ERRSV|TRANSFER_SAVE_CCTXT)
37
38#define SUB_INIT "Coro::State::initialize" 23#define SUB_INIT "Coro::State::initialize"
39#define UCORO_STATE "_coro_state" 24#define UCORO_STATE "_coro_state"
40 25
41/* The next macro should delcare a variable stacklevel that contains and approximation 26/* The next macro should delcare a variable stacklevel that contains and approximation
42 * to the current C stack pointer. It's property is that it changes with each call 27 * to the current C stack pointer. Its property is that it changes with each call
43 * and should be unique. */ 28 * and should be unique. */
44#define dSTACKLEVEL void *stacklevel = &stacklevel 29#define dSTACKLEVEL void *stacklevel = &stacklevel
45 30
46#define labs(l) ((l) >= 0 ? (l) : -(l)) 31#define labs(l) ((l) >= 0 ? (l) : -(l))
32
33#include "CoroAPI.h"
34
35static struct CoroAPI coroapi;
47 36
48/* this is actually not only the c stack but also c registers etc... */ 37/* this is actually not only the c stack but also c registers etc... */
49typedef struct { 38typedef struct {
50 int refcnt; /* pointer reference counter */ 39 int refcnt; /* pointer reference counter */
51 int usecnt; /* shared by how many coroutines */ 40 int usecnt; /* shared by how many coroutines */
751} 740}
752 741
753static struct coro * 742static struct coro *
754sv_to_coro (SV *arg, const char *funcname, const char *varname) 743sv_to_coro (SV *arg, const char *funcname, const char *varname)
755{ 744{
756 if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVHV) 745 if (SvROK(arg) && SvTYPE(SvRV(arg)) == SVt_PVHV)
757 { 746 {
758 HE *he = hv_fetch_ent((HV *)SvRV(arg), ucoro_state_sv, 0, ucoro_state_hash); 747 HE *he = hv_fetch_ent((HV *)SvRV(arg), ucoro_state_sv, 0, ucoro_state_hash);
759 748
760 if (!he) 749 if (!he)
761 croak ("%s() -- %s is a hashref but lacks the " UCORO_STATE " key", funcname, varname); 750 croak ("%s() -- %s is a hashref but lacks the " UCORO_STATE " key", funcname, varname);
762 751
763 arg = HeVAL(he); 752 arg = HeVAL(he);
764 } 753 }
765 754
766 /* must also be changed inside Coro::Cont::yield */ 755 /* must also be changed inside Coro::Cont::yield */
767 if (SvROK(arg) && SvSTASH(SvRV(arg)) == coro_state_stash) 756 if (SvROK(arg) && SvSTASH(SvRV(arg)) == coro_state_stash)
768 return (struct coro *) SvIV((SV*)SvRV(arg)); 757 return (struct coro *) SvIV((SV*)SvRV(arg));
769 else 758 else
770 croak ("%s() -- %s is not (and contains not) a Coro::State object", funcname, varname); 759 croak ("%s() -- %s is not (and contains not) a Coro::State object", funcname, varname);
760}
761
762static void
763api_transfer(pTHX_ SV *prev, SV *next, int flags)
764{
765 transfer(aTHX_ sv_to_coro (prev, "Coro::transfer", "prev"),
766 sv_to_coro (next, "Coro::transfer", "next"),
767 flags);
771} 768}
772 769
773/** Coro ********************************************************************/ 770/** Coro ********************************************************************/
774 771
775#define PRIO_MAX 3 772#define PRIO_MAX 3
821 return av_shift (coro_ready[prio]); 818 return av_shift (coro_ready[prio]);
822 819
823 return 0; 820 return 0;
824} 821}
825 822
823static void
824api_ready (SV *coro)
825{
826 coro_enq (SvREFCNT_inc (coro));
827}
828
829static void
830api_schedule (int cede)
831{
832 SV *prev, *next;
833
834 prev = GvSV (coro_current);
835
836 if (cede)
837 coro_enq (SvREFCNT_inc (prev));
838
839 next = coro_deq (PRIO_MIN);
840
841 if (!next)
842 next = SvREFCNT_inc (GvSV (coro_idle));
843
844 GvSV (coro_current) = SvREFCNT_inc (next);
845 transfer (sv_to_coro (prev, "Coro::schedule", "current coroutine"),
846 sv_to_coro (next, "Coro::schedule", "next coroutine"),
847 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK);
848 SvREFCNT_dec (next);
849 SvREFCNT_dec (prev);
850}
851
826MODULE = Coro::State PACKAGE = Coro::State 852MODULE = Coro::State PACKAGE = Coro::State
827 853
828PROTOTYPES: ENABLE 854PROTOTYPES: ENABLE
829 855
830BOOT: 856BOOT:
840 866
841 if (!padlist_cache) 867 if (!padlist_cache)
842 padlist_cache = newHV (); 868 padlist_cache = newHV ();
843 869
844 main_mainstack = PL_mainstack; 870 main_mainstack = PL_mainstack;
871
872 {
873 SV *sv = perl_get_sv("Coro::API", 1);
874
875 coroapi.ver = CORO_API_VERSION - 1;
876 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 }
845} 884}
846 885
847Coro::State 886Coro::State
848_newprocess(args) 887_newprocess(args)
849 SV * args 888 SV * args
973 1012
974void 1013void
975ready(self) 1014ready(self)
976 SV * self 1015 SV * self
977 CODE: 1016 CODE:
978 coro_enq (SvREFCNT_inc (self)); 1017 api_ready (self);
979 1018
980void 1019void
981schedule(...) 1020schedule(...)
982 ALIAS: 1021 ALIAS:
983 cede = 1 1022 cede = 1
984 CODE: 1023 CODE:
985 SV *prev, *next; 1024 api_schedule (ix);
986 1025
987 prev = GvSV (coro_current);
988
989 if (ix)
990 coro_enq (SvREFCNT_inc (prev));
991
992 next = coro_deq (PRIO_MIN);
993
994 if (!next)
995 next = SvREFCNT_inc (GvSV (coro_idle));
996
997 GvSV (coro_current) = SvREFCNT_inc (next);
998 transfer (sv_to_coro (prev, "Coro::schedule", "current coroutine"),
999 sv_to_coro (next, "Coro::schedule", "next coroutine"),
1000 TRANSFER_SAVE_ALL | TRANSFER_LAZY_STACK);
1001 SvREFCNT_dec (next);
1002 SvREFCNT_dec (prev);
1003

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines