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.151 by root, Wed Sep 19 21:39:15 2007 UTC vs.
Revision 1.162 by root, Sun Sep 23 21:49:58 2007 UTC

88/* prefer perl internal functions over our own? */ 88/* prefer perl internal functions over our own? */
89#ifndef CORO_PREFER_PERL_FUNCTIONS 89#ifndef CORO_PREFER_PERL_FUNCTIONS
90# define CORO_PREFER_PERL_FUNCTIONS 0 90# define CORO_PREFER_PERL_FUNCTIONS 0
91#endif 91#endif
92 92
93/* The next macro should declare a variable stacklevel that contains and approximation 93/* The next macros try to return the current stack pointer, in an as
94 * to the current C stack pointer. Its property is that it changes with each call 94 * portable way as possible. */
95 * and should be unique. */
96#define dSTACKLEVEL int stacklevel 95#define dSTACKLEVEL volatile char stacklevel
97#define STACKLEVEL ((void *)&stacklevel) 96#define STACKLEVEL ((void *)&stacklevel)
98 97
99#define IN_DESTRUCT (PL_main_cv == Nullcv) 98#define IN_DESTRUCT (PL_main_cv == Nullcv)
100 99
101#if __GNUC__ >= 3 100#if __GNUC__ >= 3
132static struct CoroAPI coroapi; 131static struct CoroAPI coroapi;
133static AV *main_mainstack; /* used to differentiate between $main and others */ 132static AV *main_mainstack; /* used to differentiate between $main and others */
134static JMPENV *main_top_env; 133static JMPENV *main_top_env;
135static HV *coro_state_stash, *coro_stash; 134static HV *coro_state_stash, *coro_stash;
136static SV *coro_mortal; /* will be freed after next transfer */ 135static SV *coro_mortal; /* will be freed after next transfer */
136
137/* async_pool helper stuff */
138static SV *sv_pool_rss;
139static SV *sv_pool_size;
140static AV *av_async_pool;
137 141
138static struct coro_cctx *cctx_first; 142static struct coro_cctx *cctx_first;
139static int cctx_count, cctx_idle; 143static int cctx_count, cctx_idle;
140 144
141/* this is a structure representing a c-level coroutine */ 145/* this is a structure representing a c-level coroutine */
210 214
211/* for Coro.pm */ 215/* for Coro.pm */
212static SV *coro_current; 216static SV *coro_current;
213static AV *coro_ready [PRIO_MAX-PRIO_MIN+1]; 217static AV *coro_ready [PRIO_MAX-PRIO_MIN+1];
214static int coro_nready; 218static int coro_nready;
215static struct coro *first; 219static struct coro *coro_first;
216 220
217/** lowlevel stuff **********************************************************/ 221/** lowlevel stuff **********************************************************/
218 222
219static AV * 223static AV *
220coro_clone_padlist (pTHX_ CV *cv) 224coro_clone_padlist (pTHX_ CV *cv)
395 /* 399 /*
396 * the worst thing you can imagine happens first - we have to save 400 * the worst thing you can imagine happens first - we have to save
397 * (and reinitialize) all cv's in the whole callchain :( 401 * (and reinitialize) all cv's in the whole callchain :(
398 */ 402 */
399 403
400 EXTEND (SP, 3 + 1);
401 PUSHs (Nullsv); 404 XPUSHs (Nullsv);
402 /* this loop was inspired by pp_caller */ 405 /* this loop was inspired by pp_caller */
403 for (;;) 406 for (;;)
404 { 407 {
405 while (cxix >= 0) 408 while (cxix >= 0)
406 { 409 {
425 428
426 if (top_si->si_type == PERLSI_MAIN) 429 if (top_si->si_type == PERLSI_MAIN)
427 break; 430 break;
428 431
429 top_si = top_si->si_prev; 432 top_si = top_si->si_prev;
430 ccstk = top_si->si_cxstack; 433 ccstk = top_si->si_cxstack;
431 cxix = top_si->si_cxix; 434 cxix = top_si->si_cxix;
432 } 435 }
433 436
434 PUTBACK; 437 PUTBACK;
435 } 438 }
436 439
455# define coro_init_stacks init_stacks 458# define coro_init_stacks init_stacks
456#else 459#else
457static void 460static void
458coro_init_stacks (pTHX) 461coro_init_stacks (pTHX)
459{ 462{
460 PL_curstackinfo = new_stackinfo(128, 1024/sizeof(PERL_CONTEXT)); 463 PL_curstackinfo = new_stackinfo(64, 6);
461 PL_curstackinfo->si_type = PERLSI_MAIN; 464 PL_curstackinfo->si_type = PERLSI_MAIN;
462 PL_curstack = PL_curstackinfo->si_stack; 465 PL_curstack = PL_curstackinfo->si_stack;
463 PL_mainstack = PL_curstack; /* remember in case we switch stacks */ 466 PL_mainstack = PL_curstack; /* remember in case we switch stacks */
464 467
465 PL_stack_base = AvARRAY(PL_curstack); 468 PL_stack_base = AvARRAY(PL_curstack);
466 PL_stack_sp = PL_stack_base; 469 PL_stack_sp = PL_stack_base;
467 PL_stack_max = PL_stack_base + AvMAX(PL_curstack); 470 PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
468 471
469 New(50,PL_tmps_stack,128,SV*); 472 New(50,PL_tmps_stack,64,SV*);
470 PL_tmps_floor = -1; 473 PL_tmps_floor = -1;
471 PL_tmps_ix = -1; 474 PL_tmps_ix = -1;
472 PL_tmps_max = 128; 475 PL_tmps_max = 64;
473 476
474 New(54,PL_markstack,32,I32); 477 New(54,PL_markstack,16,I32);
475 PL_markstack_ptr = PL_markstack; 478 PL_markstack_ptr = PL_markstack;
476 PL_markstack_max = PL_markstack + 32; 479 PL_markstack_max = PL_markstack + 16;
477 480
478#ifdef SET_MARK_OFFSET 481#ifdef SET_MARK_OFFSET
479 SET_MARK_OFFSET; 482 SET_MARK_OFFSET;
480#endif 483#endif
481 484
482 New(54,PL_scopestack,32,I32); 485 New(54,PL_scopestack,16,I32);
483 PL_scopestack_ix = 0; 486 PL_scopestack_ix = 0;
484 PL_scopestack_max = 32; 487 PL_scopestack_max = 16;
485 488
486 New(54,PL_savestack,64,ANY); 489 New(54,PL_savestack,64,ANY);
487 PL_savestack_ix = 0; 490 PL_savestack_ix = 0;
488 PL_savestack_max = 64; 491 PL_savestack_max = 64;
489 492
490#if !PERL_VERSION_ATLEAST (5,9,0) 493#if !PERL_VERSION_ATLEAST (5,9,0)
491 New(54,PL_retstack,16,OP*); 494 New(54,PL_retstack,4,OP*);
492 PL_retstack_ix = 0; 495 PL_retstack_ix = 0;
493 PL_retstack_max = 16; 496 PL_retstack_max = 4;
494#endif 497#endif
495} 498}
496#endif 499#endif
497 500
498/* 501/*
538 Safefree (PL_scopestack); 541 Safefree (PL_scopestack);
539 Safefree (PL_savestack); 542 Safefree (PL_savestack);
540#if !PERL_VERSION_ATLEAST (5,9,0) 543#if !PERL_VERSION_ATLEAST (5,9,0)
541 Safefree (PL_retstack); 544 Safefree (PL_retstack);
542#endif 545#endif
546}
547
548static size_t
549coro_rss (struct coro *coro)
550{
551 size_t rss = sizeof (coro);
552
553 if (coro->mainstack)
554 {
555 if (coro->flags & CF_RUNNING)
556 {
557 #define VAR(name,type)coro->name = PL_ ## name;
558 # include "state.h"
559 #undef VAR
560 }
561
562 rss += sizeof (coro->curstackinfo);
563 rss += sizeof (struct xpvav) + (1 + AvFILL (coro->curstackinfo->si_stack)) * sizeof (SV *);
564 rss += (coro->curstackinfo->si_cxmax + 1) * sizeof (PERL_CONTEXT);
565 rss += sizeof (struct xpvav) + (1 + AvFILL (coro->curstack)) * sizeof (SV *);
566 rss += coro->tmps_max * sizeof (SV *);
567 rss += (coro->markstack_max - coro->markstack_ptr) * sizeof (I32);
568 rss += coro->scopestack_max * sizeof (I32);
569 rss += coro->savestack_max * sizeof (ANY);
570
571#if !PERL_VERSION_ATLEAST (5,9,0)
572 rss += coro->retstack_max * sizeof (OP *);
573#endif
574 }
575
576 return rss;
543} 577}
544 578
545/** coroutine stack handling ************************************************/ 579/** coroutine stack handling ************************************************/
546 580
547static void 581static void
900 cctx_destroy (coro->cctx); 934 cctx_destroy (coro->cctx);
901 SvREFCNT_dec (coro->args); 935 SvREFCNT_dec (coro->args);
902 936
903 if (coro->next) coro->next->prev = coro->prev; 937 if (coro->next) coro->next->prev = coro->prev;
904 if (coro->prev) coro->prev->next = coro->next; 938 if (coro->prev) coro->prev->next = coro->next;
905 if (coro == first) first = coro->next; 939 if (coro == coro_first) coro_first = coro->next;
906 940
907 return 1; 941 return 1;
908} 942}
909 943
910static int 944static int
1218 Newz (0, coro, 1, struct coro); 1252 Newz (0, coro, 1, struct coro);
1219 coro->args = newAV (); 1253 coro->args = newAV ();
1220 coro->save = CORO_SAVE_DEF; 1254 coro->save = CORO_SAVE_DEF;
1221 coro->flags = CF_NEW; 1255 coro->flags = CF_NEW;
1222 1256
1223 if (first) first->prev = coro; 1257 if (coro_first) coro_first->prev = coro;
1224 coro->next = first; 1258 coro->next = coro_first;
1225 first = coro; 1259 coro_first = coro;
1226 1260
1227 coro->hv = hv = newHV (); 1261 coro->hv = hv = newHV ();
1228 sv_magicext ((SV *)hv, 0, PERL_MAGIC_ext, &coro_state_vtbl, (char *)coro, 0)->mg_flags |= MGf_DUP; 1262 sv_magicext ((SV *)hv, 0, PERL_MAGIC_ext, &coro_state_vtbl, (char *)coro, 0)->mg_flags |= MGf_DUP;
1229 RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); 1263 RETVAL = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
1230 1264
1339void 1373void
1340list () 1374list ()
1341 PPCODE: 1375 PPCODE:
1342{ 1376{
1343 struct coro *coro; 1377 struct coro *coro;
1344 for (coro = first; coro; coro = coro->next) 1378 for (coro = coro_first; coro; coro = coro->next)
1345 if (coro->hv) 1379 if (coro->hv)
1346 XPUSHs (sv_2mortal (newRV_inc ((SV *)coro->hv))); 1380 XPUSHs (sv_2mortal (newRV_inc ((SV *)coro->hv)));
1347} 1381}
1348 1382
1349void 1383void
1350_eval (SV *coro_sv, SV *coderef) 1384_eval (Coro::State coro, SV *coderef)
1351 CODE: 1385 CODE:
1352{ 1386{
1353 struct coro *coro = SvSTATE (coro_sv);
1354 if (coro->mainstack) 1387 if (coro->mainstack)
1355 { 1388 {
1356 struct coro temp; 1389 struct coro temp;
1357 Zero (&temp, 1, struct coro); 1390 Zero (&temp, 1, struct coro);
1358 temp.save = CORO_SAVE_ALL; 1391 temp.save = CORO_SAVE_ALL;
1383 } 1416 }
1384 } 1417 }
1385} 1418}
1386 1419
1387SV * 1420SV *
1388is_ready (SV *coro_sv) 1421is_ready (Coro::State coro)
1389 PROTOTYPE: $ 1422 PROTOTYPE: $
1390 ALIAS: 1423 ALIAS:
1391 is_ready = CF_READY 1424 is_ready = CF_READY
1392 is_running = CF_RUNNING 1425 is_running = CF_RUNNING
1393 is_new = CF_NEW 1426 is_new = CF_NEW
1394 is_destroyed = CF_DESTROYED 1427 is_destroyed = CF_DESTROYED
1395 CODE: 1428 CODE:
1396 struct coro *coro = SvSTATE (coro_sv);
1397 RETVAL = boolSV (coro->flags & ix); 1429 RETVAL = boolSV (coro->flags & ix);
1398 OUTPUT: 1430 OUTPUT:
1399 RETVAL 1431 RETVAL
1400 1432
1433SV *
1434has_stack (Coro::State coro)
1435 PROTOTYPE: $
1436 CODE:
1437 RETVAL = boolSV (!!coro->cctx);
1438 OUTPUT:
1439 RETVAL
1440
1441IV
1442rss (Coro::State coro)
1443 PROTOTYPE: $
1444 CODE:
1445 RETVAL = coro_rss (coro);
1446 OUTPUT:
1447 RETVAL
1448
1401 1449
1402MODULE = Coro::State PACKAGE = Coro 1450MODULE = Coro::State PACKAGE = Coro
1403 1451
1404BOOT: 1452BOOT:
1405{ 1453{
1406 int i; 1454 int i;
1455
1456 sv_pool_rss = get_sv ("Coro::POOL_RSS" , TRUE);
1457 sv_pool_size = get_sv ("Coro::POOL_SIZE" , TRUE);
1458 av_async_pool = get_av ("Coro::async_pool", TRUE);
1459
1460 coro_current = get_sv ("Coro::current", FALSE);
1461 SvREADONLY_on (coro_current);
1407 1462
1408 coro_stash = gv_stashpv ("Coro", TRUE); 1463 coro_stash = gv_stashpv ("Coro", TRUE);
1409 1464
1410 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX)); 1465 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
1411 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH)); 1466 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
1412 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL)); 1467 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
1413 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW)); 1468 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW));
1414 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE)); 1469 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
1415 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN)); 1470 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN));
1416
1417 coro_current = get_sv ("Coro::current", FALSE);
1418 SvREADONLY_on (coro_current);
1419 1471
1420 for (i = PRIO_MAX - PRIO_MIN + 1; i--; ) 1472 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
1421 coro_ready[i] = newAV (); 1473 coro_ready[i] = newAV ();
1422 1474
1423 { 1475 {
1481 CODE: 1533 CODE:
1482 RETVAL = coro_nready; 1534 RETVAL = coro_nready;
1483 OUTPUT: 1535 OUTPUT:
1484 RETVAL 1536 RETVAL
1485 1537
1538# for async_pool speedup
1539void
1540_pool_1 (SV *cb)
1541 CODE:
1542{
1543 int i, len;
1544 HV *hv = (HV *)SvRV (coro_current);
1545 AV *defav = GvAV (PL_defgv);
1546 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
1547 AV *invoke_av;
1548
1549 if (!invoke)
1550 croak ("\3terminate\2\n");
1551
1552 hv_store (hv, "desc", sizeof ("desc") - 1,
1553 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
1554
1555 invoke_av = (AV *)SvRV (invoke);
1556 len = av_len (invoke_av);
1557
1558 sv_setsv (cb, AvARRAY (invoke_av)[0]);
1559
1560 if (len > 0)
1561 {
1562 av_fill (defav, len - 1);
1563 for (i = 0; i < len; ++i)
1564 av_store (defav, i, SvREFCNT_inc (AvARRAY (invoke_av)[i + 1]));
1565 }
1566
1567 SvREFCNT_dec (invoke);
1568}
1569
1570void
1571_pool_2 (SV *cb)
1572 CODE:
1573{
1574 struct coro *coro = SvSTATE (coro_current);
1575
1576 sv_setsv (cb, &PL_sv_undef);
1577
1578 if (coro_rss (coro) > SvIV (sv_pool_rss)
1579 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
1580 croak ("\3terminate\2\n");
1581
1582 av_clear (GvAV (PL_defgv));
1583 hv_store (SvRV (coro_current), "desc", sizeof ("desc") - 1,
1584 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
1585 coro->save = CORO_SAVE_DEF;
1586 coro->prio = 0;
1587 av_push (av_async_pool, newSVsv (coro_current));
1588}
1589
1590
1486MODULE = Coro::State PACKAGE = Coro::AIO 1591MODULE = Coro::State PACKAGE = Coro::AIO
1487 1592
1488SV * 1593SV *
1489_get_state () 1594_get_state ()
1490 CODE: 1595 CODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines