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.154 by root, Fri Sep 21 01:08:06 2007 UTC vs.
Revision 1.161 by root, Sat Sep 22 22:59:31 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 */
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(64, 4); 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);
481 484
482 New(54,PL_scopestack,16,I32); 485 New(54,PL_scopestack,16,I32);
483 PL_scopestack_ix = 0; 486 PL_scopestack_ix = 0;
484 PL_scopestack_max = 16; 487 PL_scopestack_max = 16;
485 488
486 New(54,PL_savestack,32,ANY); 489 New(54,PL_savestack,64,ANY);
487 PL_savestack_ix = 0; 490 PL_savestack_ix = 0;
488 PL_savestack_max = 32; 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,8,OP*); 494 New(54,PL_retstack,4,OP*);
492 PL_retstack_ix = 0; 495 PL_retstack_ix = 0;
493 PL_retstack_max = 8; 496 PL_retstack_max = 4;
494#endif 497#endif
495} 498}
496#endif 499#endif
497 500
498/* 501/*
1440 1443
1441BOOT: 1444BOOT:
1442{ 1445{
1443 int i; 1446 int i;
1444 1447
1448 sv_pool_rss = get_sv ("Coro::POOL_RSS" , TRUE);
1449 sv_pool_size = get_sv ("Coro::POOL_SIZE" , TRUE);
1450 av_async_pool = get_av ("Coro::async_pool", TRUE);
1451
1452 coro_current = get_sv ("Coro::current", FALSE);
1453 SvREADONLY_on (coro_current);
1454
1445 coro_stash = gv_stashpv ("Coro", TRUE); 1455 coro_stash = gv_stashpv ("Coro", TRUE);
1446 1456
1447 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX)); 1457 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
1448 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH)); 1458 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
1449 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL)); 1459 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
1450 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW)); 1460 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW));
1451 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE)); 1461 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
1452 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN)); 1462 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN));
1453
1454 coro_current = get_sv ("Coro::current", FALSE);
1455 SvREADONLY_on (coro_current);
1456 1463
1457 for (i = PRIO_MAX - PRIO_MIN + 1; i--; ) 1464 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
1458 coro_ready[i] = newAV (); 1465 coro_ready[i] = newAV ();
1459 1466
1460 { 1467 {
1518 CODE: 1525 CODE:
1519 RETVAL = coro_nready; 1526 RETVAL = coro_nready;
1520 OUTPUT: 1527 OUTPUT:
1521 RETVAL 1528 RETVAL
1522 1529
1530# for async_pool speedup
1531void
1532_pool_1 (SV *cb)
1533 CODE:
1534{
1535 int i, len;
1536 HV *hv = (HV *)SvRV (coro_current);
1537 AV *defav = GvAV (PL_defgv);
1538 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
1539 AV *invoke_av;
1540
1541 if (!invoke)
1542 croak ("\3terminate\2\n");
1543
1544 hv_store (hv, "desc", sizeof ("desc") - 1,
1545 newSVpvn ("[async_pool]", sizeof ("[async_pool]") - 1), 0);
1546
1547 invoke_av = (AV *)SvRV (invoke);
1548 len = av_len (invoke_av);
1549
1550 sv_setsv (cb, AvARRAY (invoke_av)[0]);
1551
1552 if (len > 0)
1553 {
1554 av_fill (defav, len - 1);
1555 for (i = 0; i < len; ++i)
1556 av_store (defav, i, SvREFCNT_inc (AvARRAY (invoke_av)[i + 1]));
1557 }
1558
1559 SvREFCNT_dec (invoke);
1560}
1561
1562void
1563_pool_2 (SV *cb)
1564 CODE:
1565{
1566 struct coro *coro = SvSTATE (coro_current);
1567
1568 sv_setsv (cb, &PL_sv_undef);
1569
1570 if (coro_rss (coro) > SvIV (sv_pool_rss)
1571 || av_len (av_async_pool) + 1 >= SvIV (sv_pool_size))
1572 croak ("\3terminate\2\n");
1573
1574 av_clear (GvAV (PL_defgv));
1575 hv_store (SvRV (coro_current), "desc", sizeof ("desc") - 1,
1576 newSVpvn ("[async_pool idle]", sizeof ("[async_pool idle]") - 1), 0);
1577 coro->save = CORO_SAVE_DEF;
1578 coro->prio = 0;
1579 av_push (av_async_pool, newSVsv (coro_current));
1580}
1581
1582
1523MODULE = Coro::State PACKAGE = Coro::AIO 1583MODULE = Coro::State PACKAGE = Coro::AIO
1524 1584
1525SV * 1585SV *
1526_get_state () 1586_get_state ()
1527 CODE: 1587 CODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines