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.411 by root, Mon Jun 13 08:38:15 2011 UTC vs.
Revision 1.414 by root, Wed Jun 29 16:08:31 2011 UTC

63#endif 63#endif
64 64
65/* the maximum number of idle cctx that will be pooled */ 65/* the maximum number of idle cctx that will be pooled */
66static int cctx_max_idle = 4; 66static int cctx_max_idle = 4;
67 67
68#if defined(DEBUGGING) && PERL_VERSION_ATLEAST(5,12,0)
69# define HAS_SCOPESTACK_NAME 1
70#endif
71
68#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64 72#if !__i386 && !__x86_64 && !__powerpc && !__m68k && !__alpha && !__mips && !__sparc64
69# undef CORO_STACKGUARD 73# undef CORO_STACKGUARD
70#endif 74#endif
71 75
72#ifndef CORO_STACKGUARD 76#ifndef CORO_STACKGUARD
335 339
336/** time stuff **************************************************************/ 340/** time stuff **************************************************************/
337 341
338#ifdef HAS_GETTIMEOFDAY 342#ifdef HAS_GETTIMEOFDAY
339 343
340ECB_INLINE void 344ecb_inline void
341coro_u2time (pTHX_ UV ret[2]) 345coro_u2time (pTHX_ UV ret[2])
342{ 346{
343 struct timeval tv; 347 struct timeval tv;
344 gettimeofday (&tv, 0); 348 gettimeofday (&tv, 0);
345 349
346 ret [0] = tv.tv_sec; 350 ret [0] = tv.tv_sec;
347 ret [1] = tv.tv_usec; 351 ret [1] = tv.tv_usec;
348} 352}
349 353
350ECB_INLINE double 354ecb_inline double
351coro_nvtime (void) 355coro_nvtime (void)
352{ 356{
353 struct timeval tv; 357 struct timeval tv;
354 gettimeofday (&tv, 0); 358 gettimeofday (&tv, 0);
355 359
356 return tv.tv_sec + tv.tv_usec * 1e-6; 360 return tv.tv_sec + tv.tv_usec * 1e-6;
357} 361}
358 362
359ECB_INLINE void 363ecb_inline void
360time_init (pTHX) 364time_init (pTHX)
361{ 365{
362 nvtime = coro_nvtime; 366 nvtime = coro_nvtime;
363 u2time = coro_u2time; 367 u2time = coro_u2time;
364} 368}
365 369
366#else 370#else
367 371
368ECB_INLINE void 372ecb_inline void
369time_init (pTHX) 373time_init (pTHX)
370{ 374{
371 SV **svp; 375 SV **svp;
372 376
373 require_pv ("Time/HiRes.pm"); 377 require_pv ("Time/HiRes.pm");
415 get_hv (name, create); 419 get_hv (name, create);
416#endif 420#endif
417 return get_hv (name, create); 421 return get_hv (name, create);
418} 422}
419 423
420ECB_INLINE void 424ecb_inline void
421coro_times_update (void) 425coro_times_update (void)
422{ 426{
423#ifdef coro_clock_gettime 427#ifdef coro_clock_gettime
424 struct timespec ts; 428 struct timespec ts;
425 429
438 time_real [0] = tv [0]; 442 time_real [0] = tv [0];
439 time_real [1] = tv [1] * 1000; 443 time_real [1] = tv [1] * 1000;
440#endif 444#endif
441} 445}
442 446
443ECB_INLINE void 447ecb_inline void
444coro_times_add (struct coro *c) 448coro_times_add (struct coro *c)
445{ 449{
446 c->t_real [1] += time_real [1]; 450 c->t_real [1] += time_real [1];
447 if (c->t_real [1] > 1000000000) { c->t_real [1] -= 1000000000; ++c->t_real [0]; } 451 if (c->t_real [1] > 1000000000) { c->t_real [1] -= 1000000000; ++c->t_real [0]; }
448 c->t_real [0] += time_real [0]; 452 c->t_real [0] += time_real [0];
450 c->t_cpu [1] += time_cpu [1]; 454 c->t_cpu [1] += time_cpu [1];
451 if (c->t_cpu [1] > 1000000000) { c->t_cpu [1] -= 1000000000; ++c->t_cpu [0]; } 455 if (c->t_cpu [1] > 1000000000) { c->t_cpu [1] -= 1000000000; ++c->t_cpu [0]; }
452 c->t_cpu [0] += time_cpu [0]; 456 c->t_cpu [0] += time_cpu [0];
453} 457}
454 458
455ECB_INLINE void 459ecb_inline void
456coro_times_sub (struct coro *c) 460coro_times_sub (struct coro *c)
457{ 461{
458 if (c->t_real [1] < time_real [1]) { c->t_real [1] += 1000000000; --c->t_real [0]; } 462 if (c->t_real [1] < time_real [1]) { c->t_real [1] += 1000000000; --c->t_real [0]; }
459 c->t_real [1] -= time_real [1]; 463 c->t_real [1] -= time_real [1];
460 c->t_real [0] -= time_real [0]; 464 c->t_real [0] -= time_real [0];
481 : 0) 485 : 0)
482 486
483#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv) 487#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv)
484#define CORO_MAGIC_state(sv) CORO_MAGIC_NN (((SV *)(sv)), CORO_MAGIC_type_state) 488#define CORO_MAGIC_state(sv) CORO_MAGIC_NN (((SV *)(sv)), CORO_MAGIC_type_state)
485 489
486ECB_INLINE MAGIC * 490ecb_inline MAGIC *
487SvSTATEhv_p (pTHX_ SV *coro) 491SvSTATEhv_p (pTHX_ SV *coro)
488{ 492{
489 MAGIC *mg; 493 MAGIC *mg;
490 494
491 if (ecb_expect_true ( 495 if (ecb_expect_true (
496 return mg; 500 return mg;
497 501
498 return 0; 502 return 0;
499} 503}
500 504
501ECB_INLINE struct coro * 505ecb_inline struct coro *
502SvSTATE_ (pTHX_ SV *coro) 506SvSTATE_ (pTHX_ SV *coro)
503{ 507{
504 MAGIC *mg; 508 MAGIC *mg;
505 509
506 if (SvROK (coro)) 510 if (SvROK (coro))
520#define SvSTATE_current SvSTATE_hv (SvRV (coro_current)) 524#define SvSTATE_current SvSTATE_hv (SvRV (coro_current))
521 525
522/*****************************************************************************/ 526/*****************************************************************************/
523/* padlist management and caching */ 527/* padlist management and caching */
524 528
525ECB_INLINE AV * 529ecb_inline AV *
526coro_derive_padlist (pTHX_ CV *cv) 530coro_derive_padlist (pTHX_ CV *cv)
527{ 531{
528 AV *padlist = CvPADLIST (cv); 532 AV *padlist = CvPADLIST (cv);
529 AV *newpadlist, *newpad; 533 AV *newpadlist, *newpad;
530 534
542 av_store (newpadlist, 1, (SV *)newpad); 546 av_store (newpadlist, 1, (SV *)newpad);
543 547
544 return newpadlist; 548 return newpadlist;
545} 549}
546 550
547ECB_INLINE void 551ecb_inline void
548free_padlist (pTHX_ AV *padlist) 552free_padlist (pTHX_ AV *padlist)
549{ 553{
550 /* may be during global destruction */ 554 /* may be during global destruction */
551 if (!IN_DESTRUCT) 555 if (!IN_DESTRUCT)
552 { 556 {
595 0, 0, 0, 0, 599 0, 0, 0, 0,
596 coro_cv_free 600 coro_cv_free
597}; 601};
598 602
599/* the next two functions merely cache the padlists */ 603/* the next two functions merely cache the padlists */
600ECB_INLINE void 604ecb_inline void
601get_padlist (pTHX_ CV *cv) 605get_padlist (pTHX_ CV *cv)
602{ 606{
603 MAGIC *mg = CORO_MAGIC_cv (cv); 607 MAGIC *mg = CORO_MAGIC_cv (cv);
604 AV *av; 608 AV *av;
605 609
618 CvPADLIST (cv) = coro_derive_padlist (aTHX_ cv); 622 CvPADLIST (cv) = coro_derive_padlist (aTHX_ cv);
619#endif 623#endif
620 } 624 }
621} 625}
622 626
623ECB_INLINE void 627ecb_inline void
624put_padlist (pTHX_ CV *cv) 628put_padlist (pTHX_ CV *cv)
625{ 629{
626 MAGIC *mg = CORO_MAGIC_cv (cv); 630 MAGIC *mg = CORO_MAGIC_cv (cv);
627 AV *av; 631 AV *av;
628 632
879#endif 883#endif
880 884
881 New(54,PL_scopestack,8,I32); 885 New(54,PL_scopestack,8,I32);
882 PL_scopestack_ix = 0; 886 PL_scopestack_ix = 0;
883 PL_scopestack_max = 8; 887 PL_scopestack_max = 8;
888#if HAS_SCOPESTACK_NAME
889 New(54,PL_scopestack_name,8,const char*);
890#endif
884 891
885 New(54,PL_savestack,24,ANY); 892 New(54,PL_savestack,24,ANY);
886 PL_savestack_ix = 0; 893 PL_savestack_ix = 0;
887 PL_savestack_max = 24; 894 PL_savestack_max = 24;
888 895
916 } 923 }
917 924
918 Safefree (PL_tmps_stack); 925 Safefree (PL_tmps_stack);
919 Safefree (PL_markstack); 926 Safefree (PL_markstack);
920 Safefree (PL_scopestack); 927 Safefree (PL_scopestack);
928#if HAS_SCOPESTACK_NAME
929 Safefree (PL_scopestack_name);
930#endif
921 Safefree (PL_savestack); 931 Safefree (PL_savestack);
922#if !PERL_VERSION_ATLEAST (5,10,0) 932#if !PERL_VERSION_ATLEAST (5,10,0)
923 Safefree (PL_retstack); 933 Safefree (PL_retstack);
924#endif 934#endif
925} 935}
1220 SvREFCNT_dec (coro->invoke_cb); 1230 SvREFCNT_dec (coro->invoke_cb);
1221 SvREFCNT_dec (coro->invoke_av); 1231 SvREFCNT_dec (coro->invoke_av);
1222 } 1232 }
1223} 1233}
1224 1234
1225ECB_INLINE void 1235ecb_inline void
1226free_coro_mortal (pTHX) 1236free_coro_mortal (pTHX)
1227{ 1237{
1228 if (ecb_expect_true (coro_mortal)) 1238 if (ecb_expect_true (coro_mortal))
1229 { 1239 {
1230 SvREFCNT_dec ((SV *)coro_mortal); 1240 SvREFCNT_dec ((SV *)coro_mortal);
1389 slf_frame.prepare = slf_prepare_set_stacklevel; 1399 slf_frame.prepare = slf_prepare_set_stacklevel;
1390 slf_frame.check = slf_check_set_stacklevel; 1400 slf_frame.check = slf_check_set_stacklevel;
1391} 1401}
1392 1402
1393/* the tail of transfer: execute stuff we can only do after a transfer */ 1403/* the tail of transfer: execute stuff we can only do after a transfer */
1394ECB_INLINE void 1404ecb_inline void
1395transfer_tail (pTHX) 1405transfer_tail (pTHX)
1396{ 1406{
1397 free_coro_mortal (aTHX); 1407 free_coro_mortal (aTHX);
1398} 1408}
1399 1409
1792 TRANSFER (ta, 1); 1802 TRANSFER (ta, 1);
1793} 1803}
1794 1804
1795/** Coro ********************************************************************/ 1805/** Coro ********************************************************************/
1796 1806
1797ECB_INLINE void 1807ecb_inline void
1798coro_enq (pTHX_ struct coro *coro) 1808coro_enq (pTHX_ struct coro *coro)
1799{ 1809{
1800 struct coro **ready = coro_ready [coro->prio - CORO_PRIO_MIN]; 1810 struct coro **ready = coro_ready [coro->prio - CORO_PRIO_MIN];
1801 1811
1802 SvREFCNT_inc_NN (coro->hv); 1812 SvREFCNT_inc_NN (coro->hv);
1804 coro->next_ready = 0; 1814 coro->next_ready = 0;
1805 *(ready [0] ? &ready [1]->next_ready : &ready [0]) = coro; 1815 *(ready [0] ? &ready [1]->next_ready : &ready [0]) = coro;
1806 ready [1] = coro; 1816 ready [1] = coro;
1807} 1817}
1808 1818
1809ECB_INLINE struct coro * 1819ecb_inline struct coro *
1810coro_deq (pTHX) 1820coro_deq (pTHX)
1811{ 1821{
1812 int prio; 1822 int prio;
1813 1823
1814 for (prio = CORO_PRIO_MAX - CORO_PRIO_MIN + 1; --prio >= 0; ) 1824 for (prio = CORO_PRIO_MAX - CORO_PRIO_MIN + 1; --prio >= 0; )
1867{ 1877{
1868 return !!(SvSTATE (coro_sv)->flags & CF_READY); 1878 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1869} 1879}
1870 1880
1871/* expects to own a reference to next->hv */ 1881/* expects to own a reference to next->hv */
1872ECB_INLINE void 1882ecb_inline void
1873prepare_schedule_to (pTHX_ struct coro_transfer_args *ta, struct coro *next) 1883prepare_schedule_to (pTHX_ struct coro_transfer_args *ta, struct coro *next)
1874{ 1884{
1875 SV *prev_sv = SvRV (coro_current); 1885 SV *prev_sv = SvRV (coro_current);
1876 1886
1877 ta->prev = SvSTATE_hv (prev_sv); 1887 ta->prev = SvSTATE_hv (prev_sv);
1936 } 1946 }
1937 } 1947 }
1938 } 1948 }
1939} 1949}
1940 1950
1941ECB_INLINE void 1951ecb_inline void
1942prepare_cede (pTHX_ struct coro_transfer_args *ta) 1952prepare_cede (pTHX_ struct coro_transfer_args *ta)
1943{ 1953{
1944 api_ready (aTHX_ coro_current); 1954 api_ready (aTHX_ coro_current);
1945 prepare_schedule (aTHX_ ta); 1955 prepare_schedule (aTHX_ ta);
1946} 1956}
1947 1957
1948ECB_INLINE void 1958ecb_inline void
1949prepare_cede_notself (pTHX_ struct coro_transfer_args *ta) 1959prepare_cede_notself (pTHX_ struct coro_transfer_args *ta)
1950{ 1960{
1951 SV *prev = SvRV (coro_current); 1961 SV *prev = SvRV (coro_current);
1952 1962
1953 if (coro_nready) 1963 if (coro_nready)
4139} 4149}
4140 4150
4141MODULE = Coro::State PACKAGE = Coro::SemaphoreSet 4151MODULE = Coro::State PACKAGE = Coro::SemaphoreSet
4142 4152
4143void 4153void
4144_may_delete (SV *sem, int count, int extra_refs) 4154_may_delete (SV *sem, int count, unsigned int extra_refs)
4145 PPCODE: 4155 PPCODE:
4146{ 4156{
4147 AV *av = (AV *)SvRV (sem); 4157 AV *av = (AV *)SvRV (sem);
4148 4158
4149 if (SvREFCNT ((SV *)av) == 1 + extra_refs 4159 if (SvREFCNT ((SV *)av) == 1 + extra_refs

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines