… | |
… | |
389 | static MGVTBL coro_cv_vtbl = { |
389 | static 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 */ |
|
|
431 | INLINE struct coro * |
|
|
432 | SvSTATE_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 */ |
431 | static void |
444 | static void |
432 | get_padlist (pTHX_ CV *cv) |
445 | get_padlist (pTHX_ CV *cv) |
433 | { |
446 | { |
… | |
… | |
915 | static int |
928 | static int |
916 | runops_trace (pTHX) |
929 | runops_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 | |
1491 | static void |
1504 | INLINE void |
1492 | coro_enq (pTHX_ SV *coro_sv) |
1505 | coro_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 | |
1497 | static SV * |
1510 | INLINE SV * |
1498 | coro_deq (pTHX) |
1511 | coro_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 | |
1978 | static void |
1991 | static void |
1979 | coro_semaphore_adjust (AV *av, int adjust) |
1992 | coro_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 | |
2008 | static void |
2021 | static void |
2009 | coro_semaphore_on_destroy (pTHX_ struct coro *coro) |
2022 | coro_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 | |
2015 | static int |
2028 | static int |
2016 | slf_check_semaphore_down (pTHX_ struct CoroSLF *frame) |
2029 | slf_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 | } |
… | |
… | |
2095 | PROTOTYPES: DISABLE |
2108 | PROTOTYPES: DISABLE |
2096 | |
2109 | |
2097 | BOOT: |
2110 | BOOT: |
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 | |
2371 | void |
2383 | void |
2372 | force_cctx () |
2384 | force_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 | |
2378 | void |
2389 | void |
2379 | swap_defsv (Coro::State self) |
2390 | swap_defsv (Coro::State self) |
2380 | PROTOTYPE: $ |
2391 | PROTOTYPE: $ |
2381 | ALIAS: |
2392 | ALIAS: |
… | |
… | |
2504 | # for async_pool speedup |
2515 | # for async_pool speedup |
2505 | void |
2516 | void |
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 | |
2543 | void |
2554 | void |
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; |
… | |
… | |
2684 | void |
2695 | void |
2685 | up (SV *self, int adjust = 1) |
2696 | up (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 | |
2691 | void |
2702 | void |
2692 | down (SV *self) |
2703 | down (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); |