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.155 by root, Fri Sep 21 01:09:36 2007 UTC vs.
Revision 1.163 by root, Mon Sep 24 18:30: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 */
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);
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,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/*
1425 CODE: 1428 CODE:
1426 RETVAL = boolSV (coro->flags & ix); 1429 RETVAL = boolSV (coro->flags & ix);
1427 OUTPUT: 1430 OUTPUT:
1428 RETVAL 1431 RETVAL
1429 1432
1433SV *
1434has_stack (Coro::State coro)
1435 PROTOTYPE: $
1436 CODE:
1437 RETVAL = boolSV (!!coro->cctx);
1438 OUTPUT:
1439 RETVAL
1440
1430IV 1441IV
1431rss (Coro::State coro) 1442rss (Coro::State coro)
1432 PROTOTYPE: $ 1443 PROTOTYPE: $
1433 CODE: 1444 CODE:
1434 RETVAL = coro_rss (coro); 1445 RETVAL = coro_rss (coro);
1440 1451
1441BOOT: 1452BOOT:
1442{ 1453{
1443 int i; 1454 int i;
1444 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);
1462
1445 coro_stash = gv_stashpv ("Coro", TRUE); 1463 coro_stash = gv_stashpv ("Coro", TRUE);
1446 1464
1447 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX)); 1465 newCONSTSUB (coro_stash, "PRIO_MAX", newSViv (PRIO_MAX));
1448 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH)); 1466 newCONSTSUB (coro_stash, "PRIO_HIGH", newSViv (PRIO_HIGH));
1449 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL)); 1467 newCONSTSUB (coro_stash, "PRIO_NORMAL", newSViv (PRIO_NORMAL));
1450 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW)); 1468 newCONSTSUB (coro_stash, "PRIO_LOW", newSViv (PRIO_LOW));
1451 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE)); 1469 newCONSTSUB (coro_stash, "PRIO_IDLE", newSViv (PRIO_IDLE));
1452 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN)); 1470 newCONSTSUB (coro_stash, "PRIO_MIN", newSViv (PRIO_MIN));
1453
1454 coro_current = get_sv ("Coro::current", FALSE);
1455 SvREADONLY_on (coro_current);
1456 1471
1457 for (i = PRIO_MAX - PRIO_MIN + 1; i--; ) 1472 for (i = PRIO_MAX - PRIO_MIN + 1; i--; )
1458 coro_ready[i] = newAV (); 1473 coro_ready[i] = newAV ();
1459 1474
1460 { 1475 {
1518 CODE: 1533 CODE:
1519 RETVAL = coro_nready; 1534 RETVAL = coro_nready;
1520 OUTPUT: 1535 OUTPUT:
1521 RETVAL 1536 RETVAL
1522 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 ((HV *)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
1523MODULE = Coro::State PACKAGE = Coro::AIO 1591MODULE = Coro::State PACKAGE = Coro::AIO
1524 1592
1525SV * 1593SV *
1526_get_state () 1594_get_state ()
1527 CODE: 1595 CODE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines