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.202 by root, Mon Oct 8 02:50:23 2007 UTC vs.
Revision 1.211 by root, Wed Oct 10 03:37:58 2007 UTC

10#include "patchlevel.h" 10#include "patchlevel.h"
11 11
12#include <stdio.h> 12#include <stdio.h>
13#include <errno.h> 13#include <errno.h>
14#include <assert.h> 14#include <assert.h>
15#include <inttypes.h> /* portable stdint.h */
15 16
16#ifdef HAVE_MMAP 17#ifdef HAVE_MMAP
17# include <unistd.h> 18# include <unistd.h>
18# include <sys/mman.h> 19# include <sys/mman.h>
19# ifndef MAP_ANONYMOUS 20# ifndef MAP_ANONYMOUS
221 222
222 /* process data */ 223 /* process data */
223 AV *mainstack; 224 AV *mainstack;
224 perl_slots *slot; /* basically the saved sp */ 225 perl_slots *slot; /* basically the saved sp */
225 226
226 /* data associated with this coroutine (initial args) */ 227 AV *args; /* data associated with this coroutine (initial args) */
227 AV *args; 228 int refcnt; /* coroutines are refcounted, yes */
228 int refcnt;
229 int flags; /* CF_ flags */ 229 int flags; /* CF_ flags */
230 HV *hv; /* the perl hash associated with this coro, if any */
230 231
231 /* statistics */ 232 /* statistics */
232 int usecount; /* number of transfers to this coro */ 233 int usecount; /* number of transfers to this coro */
233 234
234 /* coro process data */ 235 /* coro process data */
235 int prio; 236 int prio;
236 SV *throw; 237 SV *throw; /* exception to be thrown */
237 238
238 /* async_pool */ 239 /* async_pool */
239 SV *saved_deffh; 240 SV *saved_deffh;
240 241
241 /* linked list */ 242 /* linked list */
242 struct coro *next, *prev; 243 struct coro *next, *prev;
243 HV *hv; /* the perl hash associated with this coro, if any */
244}; 244};
245 245
246typedef struct coro *Coro__State; 246typedef struct coro *Coro__State;
247typedef struct coro *Coro__State_or_hashref; 247typedef struct coro *Coro__State_or_hashref;
248 248
557 * allocate various perl stacks. This is an exact copy 557 * allocate various perl stacks. This is an exact copy
558 * of perl.c:init_stacks, except that it uses less memory 558 * of perl.c:init_stacks, except that it uses less memory
559 * on the (sometimes correct) assumption that coroutines do 559 * on the (sometimes correct) assumption that coroutines do
560 * not usually need a lot of stackspace. 560 * not usually need a lot of stackspace.
561 */ 561 */
562#if 1 562#if CORO_PREFER_PERL_FUNCTIONS
563# define coro_init_stacks init_stacks 563# define coro_init_stacks init_stacks
564#else 564#else
565static void 565static void
566coro_init_stacks (pTHX) 566coro_init_stacks (pTHX)
567{ 567{
713 PL_op = (OP *)&myop; 713 PL_op = (OP *)&myop;
714 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); 714 PL_op = PL_ppaddr[OP_ENTERSUB](aTHX);
715 SPAGAIN; 715 SPAGAIN;
716 } 716 }
717 717
718 ENTER; /* necessary e.g. for dounwind and to balance the xsub-entersub */ 718 /* this newly created coroutine might be run on an existing cctx which most
719 * likely was suspended in set_stacklevel, called from entersub.
720 * set_stacklevl doesn't do anything on return, but entersub does LEAVE,
721 * so we ENTER here for symmetry
722 */
723 ENTER;
719} 724}
720 725
721static void 726static void
722coro_destroy (pTHX_ struct coro *coro) 727coro_destroy (pTHX_ struct coro *coro)
723{ 728{
1524 1529
1525 while (main_top_env->je_prev) 1530 while (main_top_env->je_prev)
1526 main_top_env = main_top_env->je_prev; 1531 main_top_env = main_top_env->je_prev;
1527 1532
1528 coroapi.ver = CORO_API_VERSION; 1533 coroapi.ver = CORO_API_VERSION;
1534 coroapi.rev = CORO_API_REVISION;
1529 coroapi.transfer = api_transfer; 1535 coroapi.transfer = api_transfer;
1530 1536
1531 assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); 1537 assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL));
1532} 1538}
1533 1539
1600 1606
1601 break; 1607 break;
1602 } 1608 }
1603 1609
1604 BARRIER; 1610 BARRIER;
1611 PUTBACK;
1605 TRANSFER (ta); 1612 TRANSFER (ta);
1606 1613 SPAGAIN; /* might be the sp of a different coroutine now */
1607 if (expect_false (GIMME_V != G_VOID && ta.next != ta.prev)) 1614 /* be extra careful not to ever do anything after TRANSFER */
1608 XSRETURN_YES;
1609} 1615}
1610 1616
1611bool 1617bool
1612_destroy (SV *coro_sv) 1618_destroy (SV *coro_sv)
1613 CODE: 1619 CODE:
1673 1679
1674 { 1680 {
1675 dSP; 1681 dSP;
1676 ENTER; 1682 ENTER;
1677 SAVETMPS; 1683 SAVETMPS;
1684 PUTBACK;
1685 PUSHSTACK;
1678 PUSHMARK (SP); 1686 PUSHMARK (SP);
1679 PUTBACK;
1680 1687
1681 if (ix) 1688 if (ix)
1682 eval_sv (coderef, 0); 1689 eval_sv (coderef, 0);
1683 else 1690 else
1684 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); 1691 call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD);
1685 1692
1693 POPSTACK;
1686 SPAGAIN; 1694 SPAGAIN;
1687 FREETMPS; 1695 FREETMPS;
1688 LEAVE; 1696 LEAVE;
1689 PUTBACK; 1697 PUTBACK;
1690 } 1698 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines