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.198 by root, Sun Oct 7 03:58:37 2007 UTC vs.
Revision 1.201 by root, Mon Oct 8 01:23:14 2007 UTC

130#else 130#else
131# define LOCK (void)0 131# define LOCK (void)0
132# define UNLOCK (void)0 132# define UNLOCK (void)0
133#endif 133#endif
134 134
135#define strpair(const) const, sizeof (const) - 1
136
135/* helper storage struct for Coro::AIO */ 137/* helper storage struct for Coro::AIO */
136struct io_state 138struct io_state
137{ 139{
138 int errorno; 140 int errorno;
139 I32 laststype; 141 I32 laststype;
148static HV *coro_state_stash, *coro_stash; 150static HV *coro_state_stash, *coro_stash;
149static SV *coro_mortal; /* will be freed after next transfer */ 151static SV *coro_mortal; /* will be freed after next transfer */
150 152
151static GV *irsgv; /* $/ */ 153static GV *irsgv; /* $/ */
152static GV *stdoutgv; /* *STDOUT */ 154static GV *stdoutgv; /* *STDOUT */
155
156static HV *hv_sig; /* %SIG */
157static SV *sv_diehook;
158static SV *sv_warnhook;
153 159
154/* async_pool helper stuff */ 160/* async_pool helper stuff */
155static SV *sv_pool_rss; 161static SV *sv_pool_rss;
156static SV *sv_pool_size; 162static SV *sv_pool_size;
157static AV *av_async_pool; 163static AV *av_async_pool;
254static AV *coro_ready [PRIO_MAX-PRIO_MIN+1]; 260static AV *coro_ready [PRIO_MAX-PRIO_MIN+1];
255static int coro_nready; 261static int coro_nready;
256static struct coro *coro_first; 262static struct coro *coro_first;
257 263
258/** lowlevel stuff **********************************************************/ 264/** lowlevel stuff **********************************************************/
265
266static SV *
267coro_get_sv (const char *name, int create)
268{
269#if PERL_VERSION_ATLEAST (5,9,0)
270 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
271 get_sv (name, create);
272#endif
273 return get_sv (name, create);
274}
275
276static AV *
277coro_get_av (const char *name, int create)
278{
279#if PERL_VERSION_ATLEAST (5,9,0)
280 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
281 get_av (name, create);
282#endif
283 return get_av (name, create);
284}
285
286static HV *
287coro_get_hv (const char *name, int create)
288{
289#if PERL_VERSION_ATLEAST (5,9,0)
290 /* silence stupid and wrong 5.10 warning that I am unable to switch off */
291 get_hv (name, create);
292#endif
293 return get_hv (name, create);
294}
259 295
260static AV * 296static AV *
261coro_clone_padlist (pTHX_ CV *cv) 297coro_clone_padlist (pTHX_ CV *cv)
262{ 298{
263 AV *padlist = CvPADLIST (cv); 299 AV *padlist = CvPADLIST (cv);
649 PL_curpm = 0; 685 PL_curpm = 0;
650 PL_curpad = 0; 686 PL_curpad = 0;
651 PL_localizing = 0; 687 PL_localizing = 0;
652 PL_dirty = 0; 688 PL_dirty = 0;
653 PL_restartop = 0; 689 PL_restartop = 0;
654 PL_diehook = 0; 690 SvREFCNT_inc (PL_diehook ); hv_store (hv_sig, strpair ("__DIE__" ), SvREFCNT_inc (sv_diehook ), 0);
655 PL_warnhook = 0; 691 SvREFCNT_inc (PL_warnhook); hv_store (hv_sig, strpair ("__WARN__"), SvREFCNT_inc (sv_warnhook), 0);
656 692
657 GvSV (PL_defgv) = newSV (0); 693 GvSV (PL_defgv) = newSV (0);
658 GvAV (PL_defgv) = coro->args; coro->args = 0; 694 GvAV (PL_defgv) = coro->args; coro->args = 0;
659 GvSV (PL_errgv) = newSV (0); 695 GvSV (PL_errgv) = newSV (0);
660 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0); 696 GvSV (irsgv) = newSVpvn ("\n", 1); sv_magic (GvSV (irsgv), (SV *)irsgv, PERL_MAGIC_sv, "/", 0);
769 PUSHMARK (SP); 805 PUSHMARK (SP);
770 PUSHs (&PL_sv_no); 806 PUSHs (&PL_sv_no);
771 PUSHs (fullname); 807 PUSHs (fullname);
772 PUSHs (sv_2mortal (newRV_noinc ((SV *)av))); 808 PUSHs (sv_2mortal (newRV_noinc ((SV *)av)));
773 PUTBACK; 809 PUTBACK;
774 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0); 810 cb = hv_fetch ((HV *)SvRV (coro_current), strpair ("_trace_sub_cb"), 0);
775 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 811 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
776 SPAGAIN; 812 SPAGAIN;
777 FREETMPS; 813 FREETMPS;
778 LEAVE; 814 LEAVE;
779 PL_runops = runops_trace; 815 PL_runops = runops_trace;
808 PUSHMARK (SP); 844 PUSHMARK (SP);
809 PUSHs (&PL_sv_yes); 845 PUSHs (&PL_sv_yes);
810 PUSHs (fullname); 846 PUSHs (fullname);
811 PUSHs (cx->blk_sub.hasargs ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef); 847 PUSHs (cx->blk_sub.hasargs ? sv_2mortal (newRV_inc ((SV *)cx->blk_sub.argarray)) : &PL_sv_undef);
812 PUTBACK; 848 PUTBACK;
813 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_sub_cb", sizeof ("_trace_sub_cb") - 1, 0); 849 cb = hv_fetch ((HV *)SvRV (coro_current), strpair ("_trace_sub_cb"), 0);
814 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 850 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
815 SPAGAIN; 851 SPAGAIN;
816 FREETMPS; 852 FREETMPS;
817 LEAVE; 853 LEAVE;
818 PL_runops = runops_trace; 854 PL_runops = runops_trace;
832 PL_runops = RUNOPS_DEFAULT; 868 PL_runops = RUNOPS_DEFAULT;
833 PUSHMARK (SP); 869 PUSHMARK (SP);
834 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0))); 870 PUSHs (sv_2mortal (newSVpv (OutCopFILE (oldcop), 0)));
835 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop)))); 871 PUSHs (sv_2mortal (newSViv (CopLINE (oldcop))));
836 PUTBACK; 872 PUTBACK;
837 cb = hv_fetch ((HV *)SvRV (coro_current), "_trace_line_cb", sizeof ("_trace_line_cb") - 1, 0); 873 cb = hv_fetch ((HV *)SvRV (coro_current), strpair ("_trace_line_cb"), 0);
838 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 874 if (cb) call_sv (*cb, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
839 SPAGAIN; 875 SPAGAIN;
840 FREETMPS; 876 FREETMPS;
841 LEAVE; 877 LEAVE;
842 PL_runops = runops_trace; 878 PL_runops = runops_trace;
852 888
853/* inject a fake call to Coro::State::_cctx_init into the execution */ 889/* inject a fake call to Coro::State::_cctx_init into the execution */
854/* _cctx_init should be careful, as it could be called at almost any time */ 890/* _cctx_init should be careful, as it could be called at almost any time */
855/* during execution of a perl program */ 891/* during execution of a perl program */
856static void NOINLINE 892static void NOINLINE
857prepare_cctx (pTHX_ coro_cctx *cctx) 893cctx_prepare (pTHX_ coro_cctx *cctx)
858{ 894{
859 dSP; 895 dSP;
860 LOGOP myop; 896 LOGOP myop;
861 897
862 PL_top_env = &PL_start_env; 898 PL_top_env = &PL_start_env;
880 916
881/* 917/*
882 * this is a _very_ stripped down perl interpreter ;) 918 * this is a _very_ stripped down perl interpreter ;)
883 */ 919 */
884static void 920static void
885coro_run (void *arg) 921cctx_run (void *arg)
886{ 922{
887 dTHX; 923 dTHX;
888 924
889 /* coro_run is the alternative tail of transfer(), so unlock here. */ 925 /* cctx_run is the alternative tail of transfer(), so unlock here. */
890 UNLOCK; 926 UNLOCK;
891 927
892 /* we now skip the entersub that lead to transfer() */ 928 /* we now skip the entersub that lead to transfer() */
893 PL_op = PL_op->op_next; 929 PL_op = PL_op->op_next;
894 930
895 /* inject a fake subroutine call to cctx_init */ 931 /* inject a fake subroutine call to cctx_init */
896 prepare_cctx (aTHX_ (coro_cctx *)arg); 932 cctx_prepare (aTHX_ (coro_cctx *)arg);
897 933
898 /* somebody or something will hit me for both perl_run and PL_restartop */ 934 /* somebody or something will hit me for both perl_run and PL_restartop */
899 PL_restartop = PL_op; 935 PL_restartop = PL_op;
900 perl_run (PL_curinterp); 936 perl_run (PL_curinterp);
901 937
920 ++cctx_count; 956 ++cctx_count;
921 957
922 Newz (0, cctx, 1, coro_cctx); 958 Newz (0, cctx, 1, coro_cctx);
923 959
924#if HAVE_MMAP 960#if HAVE_MMAP
925
926 cctx->ssize = ((coro_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE; 961 cctx->ssize = ((coro_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
927 /* mmap supposedly does allocate-on-write for us */ 962 /* mmap supposedly does allocate-on-write for us */
928 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); 963 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
929 964
930 if (cctx->sptr != (void *)-1) 965 if (cctx->sptr != (void *)-1)
951 stack_start = cctx->sptr; 986 stack_start = cctx->sptr;
952 stack_size = cctx->ssize; 987 stack_size = cctx->ssize;
953 } 988 }
954 989
955 REGISTER_STACK (cctx, (char *)stack_start, (char *)stack_start + stack_size); 990 REGISTER_STACK (cctx, (char *)stack_start, (char *)stack_start + stack_size);
956 coro_create (&cctx->cctx, coro_run, (void *)cctx, stack_start, stack_size); 991 coro_create (&cctx->cctx, cctx_run, (void *)cctx, stack_start, stack_size);
957 992
958 return cctx; 993 return cctx;
959} 994}
960 995
961static void 996static void
1102 prev->cctx = 0; 1137 prev->cctx = 0;
1103 1138
1104 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */ 1139 /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */
1105 /* without this the next cctx_get might destroy the prev__cctx while still in use */ 1140 /* without this the next cctx_get might destroy the prev__cctx while still in use */
1106 if (expect_false (CCTX_EXPIRED (prev__cctx))) 1141 if (expect_false (CCTX_EXPIRED (prev__cctx)))
1142 if (!next->cctx)
1107 next->cctx = cctx_get (aTHX); 1143 next->cctx = cctx_get (aTHX);
1108 1144
1109 cctx_put (prev__cctx); 1145 cctx_put (prev__cctx);
1110 } 1146 }
1111 1147
1112 ++next->usecount; 1148 ++next->usecount;
1464#endif 1500#endif
1465 BOOT_PAGESIZE; 1501 BOOT_PAGESIZE;
1466 1502
1467 irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV); 1503 irsgv = gv_fetchpv ("/" , GV_ADD|GV_NOTQUAL, SVt_PV);
1468 stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO); 1504 stdoutgv = gv_fetchpv ("STDOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
1505
1506 hv_sig = coro_get_hv ("SIG", TRUE);
1507 sv_diehook = coro_get_sv ("Coro::State::DIEHOOK" , TRUE);
1508 sv_warnhook = coro_get_sv ("Coro::State::WARNHOOK", TRUE);
1509
1510 if (!PL_diehook ) hv_store (hv_sig, strpair ("__DIE__" ), SvREFCNT_inc (sv_diehook ), 0);
1511 if (!PL_warnhook) hv_store (hv_sig, strpair ("__WARN__"), SvREFCNT_inc (sv_warnhook), 0);
1469 1512
1470 coro_state_stash = gv_stashpv ("Coro::State", TRUE); 1513 coro_state_stash = gv_stashpv ("Coro::State", TRUE);
1471 1514
1472 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE)); 1515 newCONSTSUB (coro_state_stash, "CC_TRACE" , newSViv (CC_TRACE));
1473 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB)); 1516 newCONSTSUB (coro_state_stash, "CC_TRACE_SUB" , newSViv (CC_TRACE_SUB));
1703 1746
1704BOOT: 1747BOOT:
1705{ 1748{
1706 int i; 1749 int i;
1707 1750
1708 sv_pool_rss = get_sv ("Coro::POOL_RSS" , TRUE); 1751 sv_pool_rss = coro_get_sv ("Coro::POOL_RSS" , TRUE);
1709 get_sv ("Coro::POOL_RSS" , TRUE); /* silence stupid 5.10 warning */
1710 sv_pool_size = get_sv ("Coro::POOL_SIZE" , TRUE); 1752 sv_pool_size = coro_get_sv ("Coro::POOL_SIZE" , TRUE);
1711 get_sv ("Coro::POOL_SIZE" , TRUE); /* silence stupid 5.10 warning */
1712 av_async_pool = get_av ("Coro::async_pool", TRUE); 1753 av_async_pool = coro_get_av ("Coro::async_pool", TRUE);
1713 get_av ("Coro::async_pool", TRUE); /* silence stupid 5.10 warning */
1714 1754
1715 coro_current = get_sv ("Coro::current", FALSE); 1755 coro_current = coro_get_sv ("Coro::current", FALSE);
1716 SvREADONLY_on (coro_current); 1756 SvREADONLY_on (coro_current);
1717 1757
1718 coro_stash = gv_stashpv ("Coro", TRUE); 1758 coro_stash = gv_stashpv ("Coro", TRUE);
1719 1759
1720 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX)); 1760 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
1803 CODE: 1843 CODE:
1804{ 1844{
1805 struct coro *coro = SvSTATE (coro_current); 1845 struct coro *coro = SvSTATE (coro_current);
1806 HV *hv = (HV *)SvRV (coro_current); 1846 HV *hv = (HV *)SvRV (coro_current);
1807 AV *defav = GvAV (PL_defgv); 1847 AV *defav = GvAV (PL_defgv);
1808 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0); 1848 SV *invoke = hv_delete (hv, strpair ("_invoke"), 0);
1809 AV *invoke_av; 1849 AV *invoke_av;
1810 int i, len; 1850 int i, len;
1811 1851
1812 if (!invoke) 1852 if (!invoke)
1813 croak ("\3async_pool terminate\2\n"); 1853 croak ("\3async_pool terminate\2\n");
1814 1854
1815 SvREFCNT_dec (coro->saved_deffh); 1855 SvREFCNT_dec (coro->saved_deffh);
1816 coro->saved_deffh = SvREFCNT_inc ((SV *)PL_defoutgv); 1856 coro->saved_deffh = SvREFCNT_inc ((SV *)PL_defoutgv);
1817 1857
1818 hv_store (hv, "desc", sizeof ("desc") - 1, 1858 hv_store (hv, "desc", sizeof ("desc") - 1,
1819 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0); 1859 newSVpvn (strpair ("[async_pool]")), 0);
1820 1860
1821 invoke_av = (AV *)SvRV (invoke); 1861 invoke_av = (AV *)SvRV (invoke);
1822 len = av_len (invoke_av); 1862 len = av_len (invoke_av);
1823 1863
1824 sv_setsv (cb, AvARRAY (invoke_av)[0]); 1864 sv_setsv (cb, AvARRAY (invoke_av)[0]);
1847 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss) 1887 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss)
1848 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size)) 1888 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
1849 croak ("\3async_pool terminate\2\n"); 1889 croak ("\3async_pool terminate\2\n");
1850 1890
1851 av_clear (GvAV (PL_defgv)); 1891 av_clear (GvAV (PL_defgv));
1852 hv_store ((HV *)SvRV (coro_current), "desc", sizeof ("desc") - 1, 1892 hv_store ((HV *)SvRV (coro_current), strpair ("desc"),
1853 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0); 1893 newSVpvn (strpair ("[async_pool idle]")), 0);
1854 1894
1855 coro->prio = 0; 1895 coro->prio = 0;
1856 1896
1857 if (coro->cctx && (coro->cctx->flags & CC_TRACE)) 1897 if (coro->cctx && (coro->cctx->flags & CC_TRACE))
1858 api_trace (coro_current, 0); 1898 api_trace (coro_current, 0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines