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.412 by root, Mon Jun 13 09:00:15 2011 UTC vs.
Revision 1.413 by root, Fri Jun 17 18:55:08 2011 UTC

335 335
336/** time stuff **************************************************************/ 336/** time stuff **************************************************************/
337 337
338#ifdef HAS_GETTIMEOFDAY 338#ifdef HAS_GETTIMEOFDAY
339 339
340ECB_INLINE void 340ecb_inline void
341coro_u2time (pTHX_ UV ret[2]) 341coro_u2time (pTHX_ UV ret[2])
342{ 342{
343 struct timeval tv; 343 struct timeval tv;
344 gettimeofday (&tv, 0); 344 gettimeofday (&tv, 0);
345 345
346 ret [0] = tv.tv_sec; 346 ret [0] = tv.tv_sec;
347 ret [1] = tv.tv_usec; 347 ret [1] = tv.tv_usec;
348} 348}
349 349
350ECB_INLINE double 350ecb_inline double
351coro_nvtime (void) 351coro_nvtime (void)
352{ 352{
353 struct timeval tv; 353 struct timeval tv;
354 gettimeofday (&tv, 0); 354 gettimeofday (&tv, 0);
355 355
356 return tv.tv_sec + tv.tv_usec * 1e-6; 356 return tv.tv_sec + tv.tv_usec * 1e-6;
357} 357}
358 358
359ECB_INLINE void 359ecb_inline void
360time_init (pTHX) 360time_init (pTHX)
361{ 361{
362 nvtime = coro_nvtime; 362 nvtime = coro_nvtime;
363 u2time = coro_u2time; 363 u2time = coro_u2time;
364} 364}
365 365
366#else 366#else
367 367
368ECB_INLINE void 368ecb_inline void
369time_init (pTHX) 369time_init (pTHX)
370{ 370{
371 SV **svp; 371 SV **svp;
372 372
373 require_pv ("Time/HiRes.pm"); 373 require_pv ("Time/HiRes.pm");
415 get_hv (name, create); 415 get_hv (name, create);
416#endif 416#endif
417 return get_hv (name, create); 417 return get_hv (name, create);
418} 418}
419 419
420ECB_INLINE void 420ecb_inline void
421coro_times_update (void) 421coro_times_update (void)
422{ 422{
423#ifdef coro_clock_gettime 423#ifdef coro_clock_gettime
424 struct timespec ts; 424 struct timespec ts;
425 425
438 time_real [0] = tv [0]; 438 time_real [0] = tv [0];
439 time_real [1] = tv [1] * 1000; 439 time_real [1] = tv [1] * 1000;
440#endif 440#endif
441} 441}
442 442
443ECB_INLINE void 443ecb_inline void
444coro_times_add (struct coro *c) 444coro_times_add (struct coro *c)
445{ 445{
446 c->t_real [1] += time_real [1]; 446 c->t_real [1] += time_real [1];
447 if (c->t_real [1] > 1000000000) { c->t_real [1] -= 1000000000; ++c->t_real [0]; } 447 if (c->t_real [1] > 1000000000) { c->t_real [1] -= 1000000000; ++c->t_real [0]; }
448 c->t_real [0] += time_real [0]; 448 c->t_real [0] += time_real [0];
450 c->t_cpu [1] += time_cpu [1]; 450 c->t_cpu [1] += time_cpu [1];
451 if (c->t_cpu [1] > 1000000000) { c->t_cpu [1] -= 1000000000; ++c->t_cpu [0]; } 451 if (c->t_cpu [1] > 1000000000) { c->t_cpu [1] -= 1000000000; ++c->t_cpu [0]; }
452 c->t_cpu [0] += time_cpu [0]; 452 c->t_cpu [0] += time_cpu [0];
453} 453}
454 454
455ECB_INLINE void 455ecb_inline void
456coro_times_sub (struct coro *c) 456coro_times_sub (struct coro *c)
457{ 457{
458 if (c->t_real [1] < time_real [1]) { c->t_real [1] += 1000000000; --c->t_real [0]; } 458 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]; 459 c->t_real [1] -= time_real [1];
460 c->t_real [0] -= time_real [0]; 460 c->t_real [0] -= time_real [0];
481 : 0) 481 : 0)
482 482
483#define CORO_MAGIC_cv(cv) CORO_MAGIC (((SV *)(cv)), CORO_MAGIC_type_cv) 483#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) 484#define CORO_MAGIC_state(sv) CORO_MAGIC_NN (((SV *)(sv)), CORO_MAGIC_type_state)
485 485
486ECB_INLINE MAGIC * 486ecb_inline MAGIC *
487SvSTATEhv_p (pTHX_ SV *coro) 487SvSTATEhv_p (pTHX_ SV *coro)
488{ 488{
489 MAGIC *mg; 489 MAGIC *mg;
490 490
491 if (ecb_expect_true ( 491 if (ecb_expect_true (
496 return mg; 496 return mg;
497 497
498 return 0; 498 return 0;
499} 499}
500 500
501ECB_INLINE struct coro * 501ecb_inline struct coro *
502SvSTATE_ (pTHX_ SV *coro) 502SvSTATE_ (pTHX_ SV *coro)
503{ 503{
504 MAGIC *mg; 504 MAGIC *mg;
505 505
506 if (SvROK (coro)) 506 if (SvROK (coro))
520#define SvSTATE_current SvSTATE_hv (SvRV (coro_current)) 520#define SvSTATE_current SvSTATE_hv (SvRV (coro_current))
521 521
522/*****************************************************************************/ 522/*****************************************************************************/
523/* padlist management and caching */ 523/* padlist management and caching */
524 524
525ECB_INLINE AV * 525ecb_inline AV *
526coro_derive_padlist (pTHX_ CV *cv) 526coro_derive_padlist (pTHX_ CV *cv)
527{ 527{
528 AV *padlist = CvPADLIST (cv); 528 AV *padlist = CvPADLIST (cv);
529 AV *newpadlist, *newpad; 529 AV *newpadlist, *newpad;
530 530
542 av_store (newpadlist, 1, (SV *)newpad); 542 av_store (newpadlist, 1, (SV *)newpad);
543 543
544 return newpadlist; 544 return newpadlist;
545} 545}
546 546
547ECB_INLINE void 547ecb_inline void
548free_padlist (pTHX_ AV *padlist) 548free_padlist (pTHX_ AV *padlist)
549{ 549{
550 /* may be during global destruction */ 550 /* may be during global destruction */
551 if (!IN_DESTRUCT) 551 if (!IN_DESTRUCT)
552 { 552 {
595 0, 0, 0, 0, 595 0, 0, 0, 0,
596 coro_cv_free 596 coro_cv_free
597}; 597};
598 598
599/* the next two functions merely cache the padlists */ 599/* the next two functions merely cache the padlists */
600ECB_INLINE void 600ecb_inline void
601get_padlist (pTHX_ CV *cv) 601get_padlist (pTHX_ CV *cv)
602{ 602{
603 MAGIC *mg = CORO_MAGIC_cv (cv); 603 MAGIC *mg = CORO_MAGIC_cv (cv);
604 AV *av; 604 AV *av;
605 605
618 CvPADLIST (cv) = coro_derive_padlist (aTHX_ cv); 618 CvPADLIST (cv) = coro_derive_padlist (aTHX_ cv);
619#endif 619#endif
620 } 620 }
621} 621}
622 622
623ECB_INLINE void 623ecb_inline void
624put_padlist (pTHX_ CV *cv) 624put_padlist (pTHX_ CV *cv)
625{ 625{
626 MAGIC *mg = CORO_MAGIC_cv (cv); 626 MAGIC *mg = CORO_MAGIC_cv (cv);
627 AV *av; 627 AV *av;
628 628
1220 SvREFCNT_dec (coro->invoke_cb); 1220 SvREFCNT_dec (coro->invoke_cb);
1221 SvREFCNT_dec (coro->invoke_av); 1221 SvREFCNT_dec (coro->invoke_av);
1222 } 1222 }
1223} 1223}
1224 1224
1225ECB_INLINE void 1225ecb_inline void
1226free_coro_mortal (pTHX) 1226free_coro_mortal (pTHX)
1227{ 1227{
1228 if (ecb_expect_true (coro_mortal)) 1228 if (ecb_expect_true (coro_mortal))
1229 { 1229 {
1230 SvREFCNT_dec ((SV *)coro_mortal); 1230 SvREFCNT_dec ((SV *)coro_mortal);
1389 slf_frame.prepare = slf_prepare_set_stacklevel; 1389 slf_frame.prepare = slf_prepare_set_stacklevel;
1390 slf_frame.check = slf_check_set_stacklevel; 1390 slf_frame.check = slf_check_set_stacklevel;
1391} 1391}
1392 1392
1393/* the tail of transfer: execute stuff we can only do after a transfer */ 1393/* the tail of transfer: execute stuff we can only do after a transfer */
1394ECB_INLINE void 1394ecb_inline void
1395transfer_tail (pTHX) 1395transfer_tail (pTHX)
1396{ 1396{
1397 free_coro_mortal (aTHX); 1397 free_coro_mortal (aTHX);
1398} 1398}
1399 1399
1792 TRANSFER (ta, 1); 1792 TRANSFER (ta, 1);
1793} 1793}
1794 1794
1795/** Coro ********************************************************************/ 1795/** Coro ********************************************************************/
1796 1796
1797ECB_INLINE void 1797ecb_inline void
1798coro_enq (pTHX_ struct coro *coro) 1798coro_enq (pTHX_ struct coro *coro)
1799{ 1799{
1800 struct coro **ready = coro_ready [coro->prio - CORO_PRIO_MIN]; 1800 struct coro **ready = coro_ready [coro->prio - CORO_PRIO_MIN];
1801 1801
1802 SvREFCNT_inc_NN (coro->hv); 1802 SvREFCNT_inc_NN (coro->hv);
1804 coro->next_ready = 0; 1804 coro->next_ready = 0;
1805 *(ready [0] ? &ready [1]->next_ready : &ready [0]) = coro; 1805 *(ready [0] ? &ready [1]->next_ready : &ready [0]) = coro;
1806 ready [1] = coro; 1806 ready [1] = coro;
1807} 1807}
1808 1808
1809ECB_INLINE struct coro * 1809ecb_inline struct coro *
1810coro_deq (pTHX) 1810coro_deq (pTHX)
1811{ 1811{
1812 int prio; 1812 int prio;
1813 1813
1814 for (prio = CORO_PRIO_MAX - CORO_PRIO_MIN + 1; --prio >= 0; ) 1814 for (prio = CORO_PRIO_MAX - CORO_PRIO_MIN + 1; --prio >= 0; )
1867{ 1867{
1868 return !!(SvSTATE (coro_sv)->flags & CF_READY); 1868 return !!(SvSTATE (coro_sv)->flags & CF_READY);
1869} 1869}
1870 1870
1871/* expects to own a reference to next->hv */ 1871/* expects to own a reference to next->hv */
1872ECB_INLINE void 1872ecb_inline void
1873prepare_schedule_to (pTHX_ struct coro_transfer_args *ta, struct coro *next) 1873prepare_schedule_to (pTHX_ struct coro_transfer_args *ta, struct coro *next)
1874{ 1874{
1875 SV *prev_sv = SvRV (coro_current); 1875 SV *prev_sv = SvRV (coro_current);
1876 1876
1877 ta->prev = SvSTATE_hv (prev_sv); 1877 ta->prev = SvSTATE_hv (prev_sv);
1936 } 1936 }
1937 } 1937 }
1938 } 1938 }
1939} 1939}
1940 1940
1941ECB_INLINE void 1941ecb_inline void
1942prepare_cede (pTHX_ struct coro_transfer_args *ta) 1942prepare_cede (pTHX_ struct coro_transfer_args *ta)
1943{ 1943{
1944 api_ready (aTHX_ coro_current); 1944 api_ready (aTHX_ coro_current);
1945 prepare_schedule (aTHX_ ta); 1945 prepare_schedule (aTHX_ ta);
1946} 1946}
1947 1947
1948ECB_INLINE void 1948ecb_inline void
1949prepare_cede_notself (pTHX_ struct coro_transfer_args *ta) 1949prepare_cede_notself (pTHX_ struct coro_transfer_args *ta)
1950{ 1950{
1951 SV *prev = SvRV (coro_current); 1951 SV *prev = SvRV (coro_current);
1952 1952
1953 if (coro_nready) 1953 if (coro_nready)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines