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.169 by root, Thu Sep 27 16:25:10 2007 UTC vs.
Revision 1.172 by root, Sun Sep 30 13:15:01 2007 UTC

199 199
200#define VAR(name,type) type name; 200#define VAR(name,type) type name;
201# include "state.h" 201# include "state.h"
202#undef VAR 202#undef VAR
203 203
204 /* statistics */
205 int usecount; /* number of switches to this coro */
206
204 /* coro process data */ 207 /* coro process data */
205 int prio; 208 int prio;
206 209
207 /* linked list */ 210 /* linked list */
208 struct coro *next, *prev; 211 struct coro *next, *prev;
307 HV *stash; 310 HV *stash;
308 MAGIC *mg; 311 MAGIC *mg;
309 312
310 if (SvROK (coro)) 313 if (SvROK (coro))
311 coro = SvRV (coro); 314 coro = SvRV (coro);
315
316 if (SvTYPE (coro) != SVt_PVHV)
317 croak ("Coro::State object required");
312 318
313 stash = SvSTASH (coro); 319 stash = SvSTASH (coro);
314 if (stash != coro_stash && stash != coro_state_stash) 320 if (stash != coro_stash && stash != coro_state_stash)
315 { 321 {
316 /* very slow, but rare, check */ 322 /* very slow, but rare, check */
576 Safefree (PL_retstack); 582 Safefree (PL_retstack);
577#endif 583#endif
578} 584}
579 585
580static size_t 586static size_t
581coro_rss (struct coro *coro) 587coro_rss (pTHX_ struct coro *coro)
582{ 588{
583 size_t rss = sizeof (coro); 589 size_t rss = sizeof (coro);
584 590
585 if (coro->mainstack) 591 if (coro->mainstack)
586 { 592 {
937 cctx_first = cctx; 943 cctx_first = cctx;
938} 944}
939 945
940/** coroutine switching *****************************************************/ 946/** coroutine switching *****************************************************/
941 947
942/* never call directly, always through the coro_state_transfer global variable */ 948static void NOINLINE
949transfer_check (pTHX_ struct coro *prev, struct coro *next)
950{
951 if (prev != next)
952 {
953 if (!(prev->flags & (CF_RUNNING | CF_NEW)))
954 croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states");
955
956 if (next->flags & CF_RUNNING)
957 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states");
958
959 if (next->flags & CF_DESTROYED)
960 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states");
961
962 if (PL_lex_state != LEX_NOTPARSING)
963 croak ("Coro::State::transfer called while parsing, but this is not supported");
964 }
965}
966
967/* always use the TRANSFER macro */
943static void NOINLINE 968static void NOINLINE
944transfer (pTHX_ struct coro *prev, struct coro *next) 969transfer (pTHX_ struct coro *prev, struct coro *next)
945{ 970{
946 dSTACKLEVEL; 971 dSTACKLEVEL;
947 972
960 /* create a new empty context */ 985 /* create a new empty context */
961 Newz (0, prev->cctx, 1, coro_cctx); 986 Newz (0, prev->cctx, 1, coro_cctx);
962 prev->flags &= ~CF_NEW; 987 prev->flags &= ~CF_NEW;
963 prev->flags |= CF_RUNNING; 988 prev->flags |= CF_RUNNING;
964 } 989 }
965
966 /*TODO: must not croak here */
967 if (!prev->flags & CF_RUNNING)
968 croak ("Coro::State::transfer called with non-running prev Coro::State, but can only transfer from running states");
969
970 if (next->flags & CF_RUNNING)
971 croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states");
972
973 if (next->flags & CF_DESTROYED)
974 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states");
975 990
976 prev->flags &= ~CF_RUNNING; 991 prev->flags &= ~CF_RUNNING;
977 next->flags |= CF_RUNNING; 992 next->flags |= CF_RUNNING;
978 993
979 LOCK; 994 LOCK;
1005 prev->cctx = 0; 1020 prev->cctx = 0;
1006 1021
1007 cctx_put (prev__cctx); 1022 cctx_put (prev__cctx);
1008 } 1023 }
1009 1024
1025 ++next->usecount;
1026
1010 if (!next->cctx) 1027 if (!next->cctx)
1011 next->cctx = cctx_get (aTHX); 1028 next->cctx = cctx_get (aTHX);
1012 1029
1013 if (prev__cctx != next->cctx) 1030 if (prev__cctx != next->cctx)
1014 { 1031 {
1026{ 1043{
1027 struct coro *prev, *next; 1044 struct coro *prev, *next;
1028}; 1045};
1029 1046
1030#define TRANSFER(ta) transfer (aTHX_ (ta).prev, (ta).next) 1047#define TRANSFER(ta) transfer (aTHX_ (ta).prev, (ta).next)
1048#define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next)
1031 1049
1032/** high level stuff ********************************************************/ 1050/** high level stuff ********************************************************/
1033 1051
1034static int 1052static int
1035coro_state_destroy (pTHX_ struct coro *coro) 1053coro_state_destroy (pTHX_ struct coro *coro)
1123static void 1141static void
1124prepare_transfer (pTHX_ struct transfer_args *ta, SV *prev_sv, SV *next_sv) 1142prepare_transfer (pTHX_ struct transfer_args *ta, SV *prev_sv, SV *next_sv)
1125{ 1143{
1126 ta->prev = SvSTATE (prev_sv); 1144 ta->prev = SvSTATE (prev_sv);
1127 ta->next = SvSTATE (next_sv); 1145 ta->next = SvSTATE (next_sv);
1146 TRANSFER_CHECK (*ta);
1128} 1147}
1129 1148
1130static void 1149static void
1131api_transfer (SV *prev_sv, SV *next_sv) 1150api_transfer (SV *prev_sv, SV *next_sv)
1132{ 1151{
1249 break; 1268 break;
1250 } 1269 }
1251 1270
1252 /* free this only after the transfer */ 1271 /* free this only after the transfer */
1253 prev_sv = SvRV (coro_current); 1272 prev_sv = SvRV (coro_current);
1254 SvRV_set (coro_current, next_sv);
1255 ta->prev = SvSTATE (prev_sv); 1273 ta->prev = SvSTATE (prev_sv);
1256 1274 TRANSFER_CHECK (*ta);
1257 assert (ta->next->flags & CF_READY); 1275 assert (ta->next->flags & CF_READY);
1258 ta->next->flags &= ~CF_READY; 1276 ta->next->flags &= ~CF_READY;
1277 SvRV_set (coro_current, next_sv);
1259 1278
1260 LOCK; 1279 LOCK;
1261 free_coro_mortal (aTHX); 1280 free_coro_mortal (aTHX);
1262 coro_mortal = prev_sv; 1281 coro_mortal = prev_sv;
1263 UNLOCK; 1282 UNLOCK;
1542 save_perl (aTHX_ coro); 1561 save_perl (aTHX_ coro);
1543 load_perl (aTHX_ &temp); 1562 load_perl (aTHX_ &temp);
1544 } 1563 }
1545 } 1564 }
1546} 1565}
1547 1566
1548SV * 1567SV *
1549is_ready (Coro::State coro) 1568is_ready (Coro::State coro)
1550 PROTOTYPE: $ 1569 PROTOTYPE: $
1551 ALIAS: 1570 ALIAS:
1552 is_ready = CF_READY 1571 is_ready = CF_READY
1599 RETVAL 1618 RETVAL
1600 1619
1601IV 1620IV
1602rss (Coro::State coro) 1621rss (Coro::State coro)
1603 PROTOTYPE: $ 1622 PROTOTYPE: $
1623 ALIAS:
1624 usecount = 1
1604 CODE: 1625 CODE:
1605 RETVAL = coro_rss (coro); 1626 switch (ix)
1627 {
1628 case 0: RETVAL = coro_rss (aTHX_ coro); break;
1629 case 1: RETVAL = coro->usecount; break;
1630 }
1606 OUTPUT: 1631 OUTPUT:
1607 RETVAL 1632 RETVAL
1608 1633
1609 1634
1610MODULE = Coro::State PACKAGE = Coro 1635MODULE = Coro::State PACKAGE = Coro
1733{ 1758{
1734 struct coro *coro = SvSTATE (coro_current); 1759 struct coro *coro = SvSTATE (coro_current);
1735 1760
1736 sv_setsv (cb, &PL_sv_undef); 1761 sv_setsv (cb, &PL_sv_undef);
1737 1762
1738 if (coro_rss (coro) > SvIV (sv_pool_rss) 1763 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss)
1739 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size)) 1764 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
1740 croak ("\3terminate\2\n"); 1765 croak ("\3terminate\2\n");
1741 1766
1742 av_clear (GvAV (PL_defgv)); 1767 av_clear (GvAV (PL_defgv));
1743 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1, 1768 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1,

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines