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.254 by root, Fri Nov 7 20:27:47 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) \
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
1888 _exit (code); 1892 _exit (code);
1889 1893
1890int 1894int
1891cctx_stacksize (int new_stacksize = 0) 1895cctx_stacksize (int new_stacksize = 0)
1892 CODE: 1896 CODE:
1893 RETVAL = coro_stacksize; 1897 RETVAL = cctx_stacksize;
1894 if (new_stacksize) 1898 if (new_stacksize)
1899 {
1895 coro_stacksize = new_stacksize; 1900 cctx_stacksize = new_stacksize;
1901 ++cctx_gen;
1902 }
1903 OUTPUT:
1904 RETVAL
1905
1906int
1907cctx_max_idle (int max_idle = 0)
1908 CODE:
1909 RETVAL = cctx_max_idle;
1910 if (max_idle > 1)
1911 cctx_max_idle = max_idle;
1896 OUTPUT: 1912 OUTPUT:
1897 RETVAL 1913 RETVAL
1898 1914
1899int 1915int
1900cctx_count () 1916cctx_count ()

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines