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.220 by root, Thu Jan 10 05:43:14 2008 UTC vs.
Revision 1.227 by root, Sat Apr 5 22:29:54 2008 UTC

72# ifndef IS_PADCONST 72# ifndef IS_PADCONST
73# define IS_PADCONST(v) 0 73# define IS_PADCONST(v) 0
74# endif 74# endif
75#endif 75#endif
76 76
77/* 5.8.8 */
78#ifndef GV_NOTQUAL
79# define GV_NOTQUAL 0
80#endif
81#ifndef newSV
82# define newSV(l) NEWSV(0,l)
83#endif
84
85/* 5.11 */
86#ifndef CxHASARGS
87# define CxHASARGS(cx) (cx)->blk_sub.hasargs
88#endif
89
77/* 5.8.7 */ 90/* 5.8.7 */
78#ifndef SvRV_set 91#ifndef SvRV_set
79# define SvRV_set(s,v) SvRV(s) = (v) 92# define SvRV_set(s,v) SvRV(s) = (v)
80#endif
81
82/* 5.8.8 */
83#ifndef GV_NOTQUAL
84# define GV_NOTQUAL 0
85#endif
86#ifndef newSV
87# define newSV(l) NEWSV(0,l)
88#endif 93#endif
89 94
90#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64 95#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
91# undef CORO_STACKGUARD 96# undef CORO_STACKGUARD
92#endif 97#endif
895 SAVETMPS; 900 SAVETMPS;
896 EXTEND (SP, 3); 901 EXTEND (SP, 3);
897 PUSHMARK (SP); 902 PUSHMARK (SP);
898 PUSHs (&PL_sv_yes); 903 PUSHs (&PL_sv_yes);
899 PUSHs (fullname); 904 PUSHs (fullname);
900 PUSHs (cx->blk_sub.hasargs ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef); 905 PUSHs (CxHASARGS (cx) ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef);
901 PUTBACK; 906 PUTBACK;
902 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0); 907 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0);
903 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 908 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
904 SPAGAIN; 909 SPAGAIN;
905 FREETMPS; 910 FREETMPS;
1123 if (expect_false (next->flags & CF_DESTROYED)) 1128 if (expect_false (next->flags & CF_DESTROYED))
1124 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states"); 1129 croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states");
1125 1130
1126 if ( 1131 if (
1127#if PERL_VERSION_ATLEAST (5,9,0) 1132#if PERL_VERSION_ATLEAST (5,9,0)
1128 expect_false (PL_parser) 1133 expect_false (PL_parser && PL_parser->lex_state != LEX_NOTPARSING)
1129#else 1134#else
1130 expect_false (PL_lex_state != LEX_NOTPARSING) 1135 expect_false (PL_lex_state != LEX_NOTPARSING)
1131#endif 1136#endif
1132 ) 1137 )
1133 croak ("Coro::State::transfer called while parsing, but this is not supported"); 1138 croak ("Coro::State::transfer called while parsing, but this is not supported");
1134 } 1139 }
1135} 1140}
1136 1141
1137/* always use the TRANSFER macro */ 1142/* always use the TRANSFER macro */
1138static void NOINLINE 1143static void NOINLINE
1139transfer (pTHX_ struct coro *prev, struct coro *next) 1144transfer (pTHX_ struct coro *prev, struct coro *next, int force_cctx)
1140{ 1145{
1141 dSTACKLEVEL; 1146 dSTACKLEVEL;
1142 static volatile int has_throw; 1147 static volatile int has_throw;
1143 1148
1144 /* sometimes transfer is only called to set idle_sp */ 1149 /* sometimes transfer is only called to set idle_sp */
1178 load_perl (aTHX_ next); 1183 load_perl (aTHX_ next);
1179 1184
1180 prev__cctx = prev->cctx; 1185 prev__cctx = prev->cctx;
1181 1186
1182 /* possibly "free" the cctx */ 1187 /* possibly "free" the cctx */
1183 if (expect_true (prev__cctx->idle_sp == STACKLEVEL && !(prev__cctx->flags & CC_TRACE))) 1188 if (expect_true (
1189 prev__cctx->idle_sp == STACKLEVEL
1190 && !(prev__cctx->flags & CC_TRACE)
1191 && !force_cctx
1192 ))
1184 { 1193 {
1185 /* I assume that STACKLEVEL is a stronger indicator than PL_top_env changes */ 1194 /* I assume that STACKLEVEL is a stronger indicator than PL_top_env changes */
1186 assert (("ERROR: current top_env must equal previous top_env", PL_top_env == prev__cctx->idle_te)); 1195 assert (("ERROR: current top_env must equal previous top_env", PL_top_env == prev__cctx->idle_te));
1187 1196
1188 prev->cctx = 0; 1197 prev->cctx = 0;
1231struct transfer_args 1240struct transfer_args
1232{ 1241{
1233 struct coro *prev, *next; 1242 struct coro *prev, *next;
1234}; 1243};
1235 1244
1236#define TRANSFER(ta) transfer (aTHX_ (ta).prev, (ta).next) 1245#define TRANSFER(ta, force_cctx) transfer (aTHX_ (ta).prev, (ta).next, (force_cctx))
1237#define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next) 1246#define TRANSFER_CHECK(ta) transfer_check (aTHX_ (ta).prev, (ta).next)
1238 1247
1239/** high level stuff ********************************************************/ 1248/** high level stuff ********************************************************/
1240 1249
1241static int 1250static int
1335{ 1344{
1336 dTHX; 1345 dTHX;
1337 struct transfer_args ta; 1346 struct transfer_args ta;
1338 1347
1339 prepare_transfer (aTHX_ &ta, prev_sv, next_sv); 1348 prepare_transfer (aTHX_ &ta, prev_sv, next_sv);
1340 TRANSFER (ta); 1349 TRANSFER (ta, 1);
1341} 1350}
1342 1351
1343/** Coro ********************************************************************/ 1352/** Coro ********************************************************************/
1344 1353
1345static void 1354static void
1476{ 1485{
1477 dTHX; 1486 dTHX;
1478 struct transfer_args ta; 1487 struct transfer_args ta;
1479 1488
1480 prepare_schedule (aTHX_ &ta); 1489 prepare_schedule (aTHX_ &ta);
1481 TRANSFER (ta); 1490 TRANSFER (ta, 1);
1482} 1491}
1483 1492
1484static int 1493static int
1485api_cede (void) 1494api_cede (void)
1486{ 1495{
1489 1498
1490 prepare_cede (aTHX_ &ta); 1499 prepare_cede (aTHX_ &ta);
1491 1500
1492 if (expect_true (ta.prev != ta.next)) 1501 if (expect_true (ta.prev != ta.next))
1493 { 1502 {
1494 TRANSFER (ta); 1503 TRANSFER (ta, 1);
1495 return 1; 1504 return 1;
1496 } 1505 }
1497 else 1506 else
1498 return 0; 1507 return 0;
1499} 1508}
1504 dTHX; 1513 dTHX;
1505 struct transfer_args ta; 1514 struct transfer_args ta;
1506 1515
1507 if (prepare_cede_notself (aTHX_ &ta)) 1516 if (prepare_cede_notself (aTHX_ &ta))
1508 { 1517 {
1509 TRANSFER (ta); 1518 TRANSFER (ta, 1);
1510 return 1; 1519 return 1;
1511 } 1520 }
1512 else 1521 else
1513 return 0; 1522 return 0;
1514} 1523}
1656 } 1665 }
1657 SPAGAIN; 1666 SPAGAIN;
1658 1667
1659 BARRIER; 1668 BARRIER;
1660 PUTBACK; 1669 PUTBACK;
1661 TRANSFER (ta); 1670 TRANSFER (ta, 0);
1662 SPAGAIN; /* might be the sp of a different coroutine now */ 1671 SPAGAIN; /* might be the sp of a different coroutine now */
1663 /* be extra careful not to ever do anything after TRANSFER */ 1672 /* be extra careful not to ever do anything after TRANSFER */
1664} 1673}
1665 1674
1666bool 1675bool
1800 case 1: RETVAL = coro->usecount; break; 1809 case 1: RETVAL = coro->usecount; break;
1801 } 1810 }
1802 OUTPUT: 1811 OUTPUT:
1803 RETVAL 1812 RETVAL
1804 1813
1814void
1815force_cctx ()
1816 CODE:
1817 struct coro *coro = SvSTATE (coro_current);
1818 coro->cctx->idle_sp = 0;
1805 1819
1806MODULE = Coro::State PACKAGE = Coro 1820MODULE = Coro::State PACKAGE = Coro
1807 1821
1808BOOT: 1822BOOT:
1809{ 1823{
1896 PROTOTYPE: $;$ 1910 PROTOTYPE: $;$
1897 CODE: 1911 CODE:
1898 SvREFCNT_dec (self->throw); 1912 SvREFCNT_dec (self->throw);
1899 self->throw = SvOK (throw) ? newSVsv (throw) : 0; 1913 self->throw = SvOK (throw) ? newSVsv (throw) : 0;
1900 1914
1915void
1916swap_defsv (Coro::State self)
1917 PROTOTYPE: $
1918 ALIAS:
1919 swap_defav = 1
1920 CODE:
1921 if (!self->slot)
1922 croak ("cannot swap state with coroutine that has no saved state");
1923 else
1924 {
1925 SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv);
1926 SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv;
1927
1928 SV *tmp = *src; *src = *dst; *dst = tmp;
1929 }
1930
1901# for async_pool speedup 1931# for async_pool speedup
1902void 1932void
1903_pool_1 (SV *cb) 1933_pool_1 (SV *cb)
1904 CODE: 1934 CODE:
1905{ 1935{
1909 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0); 1939 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
1910 AV *invoke_av; 1940 AV *invoke_av;
1911 int i, len; 1941 int i, len;
1912 1942
1913 if (!invoke) 1943 if (!invoke)
1944 {
1945 SvREFCNT_dec (PL_diehook); PL_diehook = 0;
1914 croak ("\3async_pool terminate\2\n"); 1946 croak ("\3async_pool terminate\2\n");
1947 }
1915 1948
1916 SvREFCNT_dec (coro->saved_deffh); 1949 SvREFCNT_dec (coro->saved_deffh);
1917 coro->saved_deffh = SvREFCNT_inc ((SV *)PL_defoutgv); 1950 coro->saved_deffh = SvREFCNT_inc ((SV *)PL_defoutgv);
1918 1951
1919 hv_store (hv, "desc", sizeof ("desc") - 1, 1952 hv_store (hv, "desc", sizeof ("desc") - 1,
1945 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh; 1978 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
1946 coro->saved_deffh = 0; 1979 coro->saved_deffh = 0;
1947 1980
1948 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss) 1981 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss)
1949 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size)) 1982 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
1983 {
1984 SvREFCNT_dec (PL_diehook); PL_diehook = 0;
1950 croak ("\3async_pool terminate\2\n"); 1985 croak ("\3async_pool terminate\2\n");
1986 }
1951 1987
1952 av_clear (GvAV (PL_defgv)); 1988 av_clear (GvAV (PL_defgv));
1953 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1, 1989 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1,
1954 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0); 1990 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
1955 1991

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines