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.136 by root, Fri Jan 12 01:05:55 2007 UTC vs.
Revision 1.137 by root, Sun Jan 14 20:47:53 2007 UTC

186}; 186};
187 187
188typedef struct coro *Coro__State; 188typedef struct coro *Coro__State;
189typedef struct coro *Coro__State_or_hashref; 189typedef struct coro *Coro__State_or_hashref;
190 190
191/** Coro ********************************************************************/
192
193#define PRIO_MAX 3
194#define PRIO_HIGH 1
195#define PRIO_NORMAL 0
196#define PRIO_LOW -1
197#define PRIO_IDLE -3
198#define PRIO_MIN -4
199
200/* for Coro.pm */
201static SV *coro_current;
202static AV *coro_ready [PRIO_MAX-PRIO_MIN+1];
203static int coro_nready;
204
205/** lowlevel stuff **********************************************************/
206
191static AV * 207static AV *
192coro_clone_padlist (CV *cv) 208coro_clone_padlist (CV *cv)
193{ 209{
194 AV *padlist = CvPADLIST (cv); 210 AV *padlist = CvPADLIST (cv);
195 AV *newpadlist, *newpad; 211 AV *newpadlist, *newpad;
303 av_extend (av, AvMAX (av) + 1); 319 av_extend (av, AvMAX (av) + 1);
304 320
305 AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv); 321 AvARRAY (av)[++AvFILLp (av)] = (SV *)CvPADLIST (cv);
306} 322}
307 323
324/** load & save, init *******************************************************/
325
308#define SB do { 326#define SB do {
309#define SE } while (0) 327#define SE } while (0)
310 328
311#define REPLACE_SV(sv,val) SB SvREFCNT_dec (sv); (sv) = (val); (val) = 0; SE 329#define REPLACE_SV(sv,val) SB SvREFCNT_dec (sv); (sv) = (val); (val) = 0; SE
312 330
504#if !PERL_VERSION_ATLEAST (5,9,0) 522#if !PERL_VERSION_ATLEAST (5,9,0)
505 Safefree (PL_retstack); 523 Safefree (PL_retstack);
506#endif 524#endif
507} 525}
508 526
527/** coroutine stack handling ************************************************/
528
509static void 529static void
510setup_coro (struct coro *coro) 530setup_coro (struct coro *coro)
511{ 531{
512 /* 532 /*
513 * emulate part of the perl startup here. 533 * emulate part of the perl startup here.
704 724
705 ++cctx_idle; 725 ++cctx_idle;
706 cctx->next = cctx_first; 726 cctx->next = cctx_first;
707 cctx_first = cctx; 727 cctx_first = cctx;
708} 728}
729
730/** coroutine switching *****************************************************/
709 731
710/* never call directly, always through the coro_state_transfer global variable */ 732/* never call directly, always through the coro_state_transfer global variable */
711static void NOINLINE 733static void NOINLINE
712transfer (struct coro *prev, struct coro *next) 734transfer (struct coro *prev, struct coro *next)
713{ 735{
803 struct coro *prev, *next; 825 struct coro *prev, *next;
804}; 826};
805 827
806#define TRANSFER(ta) transfer ((ta).prev, (ta).next) 828#define TRANSFER(ta) transfer ((ta).prev, (ta).next)
807 829
830/** high level stuff ********************************************************/
831
808static int 832static int
809coro_state_destroy (struct coro *coro) 833coro_state_destroy (struct coro *coro)
810{ 834{
811 if (coro->flags & CF_DESTROYED) 835 if (coro->flags & CF_DESTROYED)
812 return 0; 836 return 0;
813 837
814 coro->flags |= CF_DESTROYED; 838 coro->flags |= CF_DESTROYED;
839
840 if (coro->flags & CF_READY)
841 {
842 /* reduce nready, as destroying a ready coro effectively unreadies it */
843 /* alternative: look through all ready queues and remove it */
844 LOCK;
845 --coro_nready;
846 UNLOCK;
847 }
848 else
849 coro->flags |= CF_READY; /* make sure it is NOT put into the readyqueue */
815 850
816 if (coro->mainstack && coro->mainstack != main_mainstack) 851 if (coro->mainstack && coro->mainstack != main_mainstack)
817 { 852 {
818 assert (!(coro->flags & CF_RUNNING)); 853 assert (!(coro->flags & CF_RUNNING));
819 854
926 return old_save; 961 return old_save;
927} 962}
928 963
929/** Coro ********************************************************************/ 964/** Coro ********************************************************************/
930 965
931#define PRIO_MAX 3
932#define PRIO_HIGH 1
933#define PRIO_NORMAL 0
934#define PRIO_LOW -1
935#define PRIO_IDLE -3
936#define PRIO_MIN -4
937
938/* for Coro.pm */
939static SV *coro_current;
940static AV *coro_ready [PRIO_MAX-PRIO_MIN+1];
941static int coro_nready;
942
943static void 966static void
944coro_enq (SV *coro_sv) 967coro_enq (SV *coro_sv)
945{ 968{
946 av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv); 969 av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv);
947 coro_nready++;
948} 970}
949 971
950static SV * 972static SV *
951coro_deq (int min_prio) 973coro_deq (int min_prio)
952{ 974{
956 if (min_prio < 0) 978 if (min_prio < 0)
957 min_prio = 0; 979 min_prio = 0;
958 980
959 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; ) 981 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= min_prio; )
960 if (AvFILLp (coro_ready [prio]) >= 0) 982 if (AvFILLp (coro_ready [prio]) >= 0)
961 {
962 coro_nready--;
963 return av_shift (coro_ready [prio]); 983 return av_shift (coro_ready [prio]);
964 }
965 984
966 return 0; 985 return 0;
967} 986}
968 987
969static int 988static int
981 1000
982 coro->flags |= CF_READY; 1001 coro->flags |= CF_READY;
983 1002
984 LOCK; 1003 LOCK;
985 coro_enq (SvREFCNT_inc (coro_sv)); 1004 coro_enq (SvREFCNT_inc (coro_sv));
1005 ++coro_nready;
986 UNLOCK; 1006 UNLOCK;
987 1007
988 return 1; 1008 return 1;
989} 1009}
990 1010
1026 1046
1027 /* cannot transfer to destroyed coros, skip and look for next */ 1047 /* cannot transfer to destroyed coros, skip and look for next */
1028 if (ta->next->flags & CF_DESTROYED) 1048 if (ta->next->flags & CF_DESTROYED)
1029 { 1049 {
1030 SvREFCNT_dec (next_sv); 1050 SvREFCNT_dec (next_sv);
1051 /* coro_nready is already taken care of by destroy */
1031 continue; 1052 continue;
1032 } 1053 }
1033 1054
1055 LOCK;
1056 --coro_nready;
1057 UNLOCK;
1034 break; 1058 break;
1035 } 1059 }
1036 1060
1037 /* free this only after the transfer */ 1061 /* free this only after the transfer */
1038 prev_sv = SvRV (coro_current); 1062 prev_sv = SvRV (coro_current);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines