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.280 by root, Sun Nov 16 09:43:18 2008 UTC vs.
Revision 1.281 by root, Sun Nov 16 10:12:38 2008 UTC

389static MGVTBL coro_cv_vtbl = { 389static MGVTBL coro_cv_vtbl = {
390 0, 0, 0, 0, 390 0, 0, 0, 0,
391 coro_cv_free 391 coro_cv_free
392}; 392};
393 393
394#define CORO_MAGIC(sv, type) \ 394#define CORO_MAGIC(sv, type) \
395 SvMAGIC (sv) \ 395 expect_true (SvMAGIC (sv)) \
396 ? SvMAGIC (sv)->mg_type == type \ 396 ? expect_true (SvMAGIC (sv)->mg_type == type) \
397 ? SvMAGIC (sv) \ 397 ? SvMAGIC (sv) \
398 : mg_find (sv, type) \ 398 : mg_find (sv, type) \
399 : 0 399 : 0
400 400
401#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv) 401#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv)
402#define CORO_MAGIC_state(sv) CORO_MAGIC (((SV *)(sv)), CORO_MAGIC_type_state) 402#define CORO_MAGIC_state(sv) CORO_MAGIC (((SV *)(sv)), CORO_MAGIC_type_state)
403 403
424 mg = CORO_MAGIC_state (coro); 424 mg = CORO_MAGIC_state (coro);
425 return (struct coro *)mg->mg_ptr; 425 return (struct coro *)mg->mg_ptr;
426} 426}
427 427
428#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv)) 428#define SvSTATE(sv) SvSTATE_ (aTHX_ (sv))
429
430/* fastert than SvSTATE, but expects a coroutine hv */
431INLINE struct coro *
432SvSTATE_hv (SV *sv)
433{
434 MAGIC *mg = expect_true (SvMAGIC (sv)->mg_type == CORO_MAGIC_type_state)
435 ? SvMAGIC (sv)
436 : mg_find (sv, CORO_MAGIC_type_state);
437
438 return (struct coro *)mg->mg_ptr;
439}
440
441#define SvSTATE_current SvSTATE_hv (SvRV (coro_current))
429 442
430/* the next two functions merely cache the padlists */ 443/* the next two functions merely cache the padlists */
431static void 444static void
432get_padlist (pTHX_ CV *cv) 445get_padlist (pTHX_ CV *cv)
433{ 446{
915static int 928static int
916runops_trace (pTHX) 929runops_trace (pTHX)
917{ 930{
918 COP *oldcop = 0; 931 COP *oldcop = 0;
919 int oldcxix = -2; 932 int oldcxix = -2;
920 struct coro *coro = SvSTATE (coro_current); /* trace cctx is tied to specific coro */ 933 struct coro *coro = SvSTATE_current; /* trace cctx is tied to specific coro */
921 coro_cctx *cctx = coro->cctx; 934 coro_cctx *cctx = coro->cctx;
922 935
923 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX))) 936 while ((PL_op = CALL_FPTR (PL_op->op_ppaddr) (aTHX)))
924 { 937 {
925 PERL_ASYNC_CHECK (); 938 PERL_ASYNC_CHECK ();
1486 TRANSFER (ta, 1); 1499 TRANSFER (ta, 1);
1487} 1500}
1488 1501
1489/** Coro ********************************************************************/ 1502/** Coro ********************************************************************/
1490 1503
1491static void 1504INLINE void
1492coro_enq (pTHX_ SV *coro_sv) 1505coro_enq (pTHX_ struct coro *coro)
1493{ 1506{
1494 av_push (coro_ready [SvSTATE (coro_sv)->prio - PRIO_MIN], coro_sv); 1507 av_push (coro_ready [coro->prio - PRIO_MIN], SvREFCNT_inc_NN (coro->hv));
1495} 1508}
1496 1509
1497static SV * 1510INLINE SV *
1498coro_deq (pTHX) 1511coro_deq (pTHX)
1499{ 1512{
1500 int prio; 1513 int prio;
1501 1514
1502 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; ) 1515 for (prio = PRIO_MAX - PRIO_MIN + 1; --prio >= 0; )
1524 coro->flags |= CF_READY; 1537 coro->flags |= CF_READY;
1525 1538
1526 sv_hook = coro_nready ? 0 : coro_readyhook; 1539 sv_hook = coro_nready ? 0 : coro_readyhook;
1527 xs_hook = coro_nready ? 0 : coroapi.readyhook; 1540 xs_hook = coro_nready ? 0 : coroapi.readyhook;
1528 1541
1529 coro_enq (aTHX_ SvREFCNT_inc_NN (coro_sv)); 1542 coro_enq (aTHX_ coro);
1530 ++coro_nready; 1543 ++coro_nready;
1531 1544
1532 if (sv_hook) 1545 if (sv_hook)
1533 { 1546 {
1534 dSP; 1547 dSP;
1582 FREETMPS; 1595 FREETMPS;
1583 LEAVE; 1596 LEAVE;
1584 continue; 1597 continue;
1585 } 1598 }
1586 1599
1587 ta->next = SvSTATE (next_sv); 1600 ta->next = SvSTATE_hv (next_sv);
1588 1601
1589 /* cannot transfer to destroyed coros, skip and look for next */ 1602 /* cannot transfer to destroyed coros, skip and look for next */
1590 if (expect_false (ta->next->flags & CF_DESTROYED)) 1603 if (expect_false (ta->next->flags & CF_DESTROYED))
1591 { 1604 {
1592 SvREFCNT_dec (next_sv); 1605 SvREFCNT_dec (next_sv);
1598 break; 1611 break;
1599 } 1612 }
1600 1613
1601 /* free this only after the transfer */ 1614 /* free this only after the transfer */
1602 prev_sv = SvRV (coro_current); 1615 prev_sv = SvRV (coro_current);
1603 ta->prev = SvSTATE (prev_sv); 1616 ta->prev = SvSTATE_hv (prev_sv);
1604 TRANSFER_CHECK (*ta); 1617 TRANSFER_CHECK (*ta);
1605 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY)); 1618 assert (("FATAL: next coroutine isn't marked as ready in Coro (please report)", ta->next->flags & CF_READY));
1606 ta->next->flags &= ~CF_READY; 1619 ta->next->flags &= ~CF_READY;
1607 SvRV_set (coro_current, next_sv); 1620 SvRV_set (coro_current, next_sv);
1608 1621
1974} 1987}
1975 1988
1976/*****************************************************************************/ 1989/*****************************************************************************/
1977 1990
1978static void 1991static void
1979coro_semaphore_adjust (AV *av, int adjust) 1992coro_semaphore_adjust (pTHX_ AV *av, int adjust)
1980{ 1993{
1981 SV *count_sv = AvARRAY (av)[0]; 1994 SV *count_sv = AvARRAY (av)[0];
1982 IV count = SvIVX (count_sv); 1995 IV count = SvIVX (count_sv);
1983 1996
1984 count += adjust; 1997 count += adjust;
2007 2020
2008static void 2021static void
2009coro_semaphore_on_destroy (pTHX_ struct coro *coro) 2022coro_semaphore_on_destroy (pTHX_ struct coro *coro)
2010{ 2023{
2011 /* call $sem->adjust (0) to possibly wake up some waiters */ 2024 /* call $sem->adjust (0) to possibly wake up some waiters */
2012 coro_semaphore_adjust ((AV *)coro->slf_frame.data, 0); 2025 coro_semaphore_adjust (aTHX_ (AV *)coro->slf_frame.data, 0);
2013} 2026}
2014 2027
2015static int 2028static int
2016slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) 2029slf_check_semaphore_down (pTHX_ struct CoroSLF *frame)
2017{ 2030{
2018 AV *av = (AV *)frame->data; 2031 AV *av = (AV *)frame->data;
2019 SV *count_sv = AvARRAY (av)[0]; 2032 SV *count_sv = AvARRAY (av)[0];
2020 2033
2021 if (SvIVX (count_sv) > 0) 2034 if (SvIVX (count_sv) > 0)
2022 { 2035 {
2023 SvSTATE (coro_current)->on_destroy = 0; 2036 SvSTATE_current->on_destroy = 0;
2024 SvIVX (count_sv) = SvIVX (count_sv) - 1; 2037 SvIVX (count_sv) = SvIVX (count_sv) - 1;
2025 return 0; 2038 return 0;
2026 } 2039 }
2027 else 2040 else
2028 { 2041 {
2057 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av)); 2070 frame->data = (void *)sv_2mortal (SvREFCNT_inc ((SV *)av));
2058 frame->prepare = prepare_schedule; 2071 frame->prepare = prepare_schedule;
2059 2072
2060 /* to avoid race conditions when a woken-up coro gets terminated */ 2073 /* to avoid race conditions when a woken-up coro gets terminated */
2061 /* we arrange for a temporary on_destroy that calls adjust (0) */ 2074 /* we arrange for a temporary on_destroy that calls adjust (0) */
2062 SvSTATE (coro_current)->on_destroy = coro_semaphore_on_destroy; 2075 SvSTATE_current->on_destroy = coro_semaphore_on_destroy;
2063 } 2076 }
2064 2077
2065 frame->check = slf_check_semaphore_down; 2078 frame->check = slf_check_semaphore_down;
2066 2079
2067} 2080}
2095PROTOTYPES: DISABLE 2108PROTOTYPES: DISABLE
2096 2109
2097BOOT: 2110BOOT:
2098{ 2111{
2099#ifdef USE_ITHREADS 2112#ifdef USE_ITHREADS
2100 MUTEX_INIT (&coro_lock);
2101# if CORO_PTHREAD 2113# if CORO_PTHREAD
2102 coro_thx = PERL_GET_CONTEXT; 2114 coro_thx = PERL_GET_CONTEXT;
2103# endif 2115# endif
2104#endif 2116#endif
2105 BOOT_PAGESIZE; 2117 BOOT_PAGESIZE;
2370 2382
2371void 2383void
2372force_cctx () 2384force_cctx ()
2373 PROTOTYPE: 2385 PROTOTYPE:
2374 CODE: 2386 CODE:
2375 struct coro *coro = SvSTATE (coro_current);
2376 coro->cctx->idle_sp = 0; 2387 SvSTATE_current->cctx->idle_sp = 0;
2377 2388
2378void 2389void
2379swap_defsv (Coro::State self) 2390swap_defsv (Coro::State self)
2380 PROTOTYPE: $ 2391 PROTOTYPE: $
2381 ALIAS: 2392 ALIAS:
2504# for async_pool speedup 2515# for async_pool speedup
2505void 2516void
2506_pool_1 (SV *cb) 2517_pool_1 (SV *cb)
2507 CODE: 2518 CODE:
2508{ 2519{
2509 struct coro *coro = SvSTATE (coro_current);
2510 HV *hv = (HV *)SvRV (coro_current); 2520 HV *hv = (HV *)SvRV (coro_current);
2521 struct coro *coro = SvSTATE_hv ((SV *)hv);
2511 AV *defav = GvAV (PL_defgv); 2522 AV *defav = GvAV (PL_defgv);
2512 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0); 2523 SV *invoke = hv_delete (hv, "_invoke", sizeof ("_invoke") - 1, 0);
2513 AV *invoke_av; 2524 AV *invoke_av;
2514 int i, len; 2525 int i, len;
2515 2526
2542 2553
2543void 2554void
2544_pool_2 (SV *cb) 2555_pool_2 (SV *cb)
2545 CODE: 2556 CODE:
2546{ 2557{
2547 struct coro *coro = SvSTATE (coro_current); 2558 struct coro *coro = SvSTATE_current;
2548 2559
2549 sv_setsv (cb, &PL_sv_undef); 2560 sv_setsv (cb, &PL_sv_undef);
2550 2561
2551 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh; 2562 SvREFCNT_dec ((SV *)PL_defoutgv); PL_defoutgv = (GV *)coro->saved_deffh;
2552 coro->saved_deffh = 0; 2563 coro->saved_deffh = 0;
2684void 2695void
2685up (SV *self, int adjust = 1) 2696up (SV *self, int adjust = 1)
2686 ALIAS: 2697 ALIAS:
2687 adjust = 1 2698 adjust = 1
2688 CODE: 2699 CODE:
2689 coro_semaphore_adjust ((AV *)SvRV (self), ix ? adjust : 1); 2700 coro_semaphore_adjust (aTHX_ (AV *)SvRV (self), ix ? adjust : 1);
2690 2701
2691void 2702void
2692down (SV *self) 2703down (SV *self)
2693 CODE: 2704 CODE:
2694 api_execute_slf (aTHX_ cv, slf_init_semaphore_down, &ST (0), 1); 2705 api_execute_slf (aTHX_ cv, slf_init_semaphore_down, &ST (0), 1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines