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.253 by root, Fri Nov 7 20:12:26 2008 UTC vs.
Revision 1.255 by root, Sat Nov 8 04:52:01 2008 UTC

52#else 52#else
53# define REGISTER_STACK(cctx,start,end) 53# define REGISTER_STACK(cctx,start,end)
54#endif 54#endif
55 55
56/* the maximum number of idle cctx that will be pooled */ 56/* the maximum number of idle cctx that will be pooled */
57#define MAX_IDLE_CCTX 8 57static int cctx_max_idle = 4;
58 58
59#define PERL_VERSION_ATLEAST(a,b,c) \ 59#define PERL_VERSION_ATLEAST(a,b,c) \
60 (PERL_REVISION > (a) \ 60 (PERL_REVISION > (a) \
61 || (PERL_REVISION == (a) \ 61 || (PERL_REVISION == (a) \
62 && (PERL_VERSION > (b) \ 62 && (PERL_VERSION > (b) \
155/* helper storage struct for Coro::AIO */ 155/* helper storage struct for Coro::AIO */
156struct io_state 156struct io_state
157{ 157{
158 AV *res; 158 AV *res;
159 int errorno; 159 int errorno;
160 I32 laststype; 160 I32 laststype; /* U16 in 5.10.0 */
161 int laststatval; 161 int laststatval;
162 Stat_t statcache; 162 Stat_t statcache;
163}; 163};
164 164
165static double (*nvtime)(); /* so why doesn't it take void? */ 165static double (*nvtime)(); /* so why doesn't it take void? */
166 166
167static U32 cctx_gen;
167static size_t coro_stacksize = CORO_STACKSIZE; 168static size_t cctx_stacksize = CORO_STACKSIZE;
168static struct CoroAPI coroapi; 169static struct CoroAPI coroapi;
169static AV *main_mainstack; /* used to differentiate between $main and others */ 170static AV *main_mainstack; /* used to differentiate between $main and others */
170static JMPENV *main_top_env; 171static JMPENV *main_top_env;
171static HV *coro_state_stash, *coro_stash; 172static HV *coro_state_stash, *coro_stash;
172static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */ 173static volatile SV *coro_mortal; /* will be freed/thrown after next transfer */
209 void *idle_sp; /* sp of top-level transfer/schedule/cede call */ 210 void *idle_sp; /* sp of top-level transfer/schedule/cede call */
210 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */ 211 JMPENV *idle_te; /* same as idle_sp, but for top_env, TODO: remove once stable */
211 JMPENV *top_env; 212 JMPENV *top_env;
212 coro_context cctx; 213 coro_context cctx;
213 214
215 U32 gen;
214#if CORO_USE_VALGRIND 216#if CORO_USE_VALGRIND
215 int valgrind_id; 217 int valgrind_id;
216#endif 218#endif
217 unsigned char flags; 219 unsigned char flags;
218} coro_cctx; 220} coro_cctx;
1082 size_t stack_size; 1084 size_t stack_size;
1083 1085
1084 ++cctx_count; 1086 ++cctx_count;
1085 Newz (0, cctx, 1, coro_cctx); 1087 Newz (0, cctx, 1, coro_cctx);
1086 1088
1089 cctx->gen = cctx_gen;
1090
1087#if HAVE_MMAP 1091#if HAVE_MMAP
1088 cctx->ssize = ((coro_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE; 1092 cctx->ssize = ((cctx_stacksize * sizeof (long) + PAGESIZE - 1) / PAGESIZE + CORO_STACKGUARD) * PAGESIZE;
1089 /* mmap supposedly does allocate-on-write for us */ 1093 /* mmap supposedly does allocate-on-write for us */
1090 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); 1094 cctx->sptr = mmap (0, cctx->ssize, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
1091 1095
1092 if (cctx->sptr != (void *)-1) 1096 if (cctx->sptr != (void *)-1)
1093 { 1097 {
1099 cctx->flags |= CC_MAPPED; 1103 cctx->flags |= CC_MAPPED;
1100 } 1104 }
1101 else 1105 else
1102#endif 1106#endif
1103 { 1107 {
1104 cctx->ssize = coro_stacksize * (long)sizeof (long); 1108 cctx->ssize = cctx_stacksize * (long)sizeof (long);
1105 New (0, cctx->sptr, coro_stacksize, long); 1109 New (0, cctx->sptr, cctx_stacksize, long);
1106 1110
1107 if (!cctx->sptr) 1111 if (!cctx->sptr)
1108 { 1112 {
1109 perror ("FATAL: unable to allocate stack for coroutine"); 1113 perror ("FATAL: unable to allocate stack for coroutine");
1110 _exit (EXIT_FAILURE); 1114 _exit (EXIT_FAILURE);
1146 1150
1147 Safefree (cctx); 1151 Safefree (cctx);
1148} 1152}
1149 1153
1150/* wether this cctx should be destructed */ 1154/* wether this cctx should be destructed */
1151#define CCTX_EXPIRED(cctx) ((cctx)->ssize < coro_stacksize || ((cctx)->flags & CC_NOREUSE)) 1155#define CCTX_EXPIRED(cctx) ((cctx)->gen != cctx_gen || ((cctx)->flags & CC_NOREUSE))
1152 1156
1153static coro_cctx * 1157static coro_cctx *
1154cctx_get (pTHX) 1158cctx_get (pTHX)
1155{ 1159{
1156 while (expect_true (cctx_first)) 1160 while (expect_true (cctx_first))
1172cctx_put (coro_cctx *cctx) 1176cctx_put (coro_cctx *cctx)
1173{ 1177{
1174 assert (("cctx_put called on non-initialised cctx", cctx->sptr)); 1178 assert (("cctx_put called on non-initialised cctx", cctx->sptr));
1175 1179
1176 /* free another cctx if overlimit */ 1180 /* free another cctx if overlimit */
1177 if (expect_false (cctx_idle >= MAX_IDLE_CCTX)) 1181 if (expect_false (cctx_idle >= cctx_max_idle))
1178 { 1182 {
1179 coro_cctx *first = cctx_first; 1183 coro_cctx *first = cctx_first;
1180 cctx_first = first->next; 1184 cctx_first = first->next;
1181 --cctx_idle; 1185 --cctx_idle;
1182 1186
1648 else 1652 else
1649 coro->slot->runops = RUNOPS_DEFAULT; 1653 coro->slot->runops = RUNOPS_DEFAULT;
1650 } 1654 }
1651} 1655}
1652 1656
1657#if 0
1653static int 1658static int
1654coro_gensub_free (pTHX_ SV *sv, MAGIC *mg) 1659coro_gensub_free (pTHX_ SV *sv, MAGIC *mg)
1655{ 1660{
1656 AV *padlist; 1661 AV *padlist;
1657 AV *av = (AV *)mg->mg_obj; 1662 AV *av = (AV *)mg->mg_obj;
1663 1668
1664static MGVTBL coro_gensub_vtbl = { 1669static MGVTBL coro_gensub_vtbl = {
1665 0, 0, 0, 0, 1670 0, 0, 0, 0,
1666 coro_gensub_free 1671 coro_gensub_free
1667}; 1672};
1673#endif
1668 1674
1669/*****************************************************************************/ 1675/*****************************************************************************/
1670/* PerlIO::cede */ 1676/* PerlIO::cede */
1671 1677
1672typedef struct 1678typedef struct
1888 _exit (code); 1894 _exit (code);
1889 1895
1890int 1896int
1891cctx_stacksize (int new_stacksize = 0) 1897cctx_stacksize (int new_stacksize = 0)
1892 CODE: 1898 CODE:
1893 RETVAL = coro_stacksize; 1899 RETVAL = cctx_stacksize;
1894 if (new_stacksize) 1900 if (new_stacksize)
1901 {
1895 coro_stacksize = new_stacksize; 1902 cctx_stacksize = new_stacksize;
1903 ++cctx_gen;
1904 }
1905 OUTPUT:
1906 RETVAL
1907
1908int
1909cctx_max_idle (int max_idle = 0)
1910 CODE:
1911 RETVAL = cctx_max_idle;
1912 if (max_idle > 1)
1913 cctx_max_idle = max_idle;
1896 OUTPUT: 1914 OUTPUT:
1897 RETVAL 1915 RETVAL
1898 1916
1899int 1917int
1900cctx_count () 1918cctx_count ()
1996 CODE: 2014 CODE:
1997 RETVAL = (coro->cctx ? coro->cctx->flags : 0) & CC_TRACE_ALL; 2015 RETVAL = (coro->cctx ? coro->cctx->flags : 0) & CC_TRACE_ALL;
1998 OUTPUT: 2016 OUTPUT:
1999 RETVAL 2017 RETVAL
2000 2018
2001IV 2019UV
2002rss (Coro::State coro) 2020rss (Coro::State coro)
2003 PROTOTYPE: $ 2021 PROTOTYPE: $
2004 ALIAS: 2022 ALIAS:
2005 usecount = 1 2023 usecount = 1
2006 CODE: 2024 CODE:
2188 sv_setsv (cb, &PL_sv_undef); 2206 sv_setsv (cb, &PL_sv_undef);
2189 2207
2190 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh; 2208 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
2191 coro->saved_deffh = 0; 2209 coro->saved_deffh = 0;
2192 2210
2193 if (coro_rss (aTHX_ coro) > SvIV (sv_pool_rss) 2211 if (coro_rss (aTHX_ coro) > SvUV (sv_pool_rss)
2194 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size)) 2212 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
2195 { 2213 {
2196 SV *old = PL_diehook; 2214 SV *old = PL_diehook;
2197 PL_diehook = 0; 2215 PL_diehook = 0;
2198 SvREFCNT_dec (old); 2216 SvREFCNT_dec (old);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines