ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev.c
(Generate patch)

Comparing libev/ev.c (file contents):
Revision 1.380 by root, Mon Jun 27 19:20:01 2011 UTC vs.
Revision 1.389 by root, Wed Aug 3 15:31:23 2011 UTC

492 #define ecb_inline static inline 492 #define ecb_inline static inline
493#else 493#else
494 #define ecb_inline static 494 #define ecb_inline static
495#endif 495#endif
496 496
497#ifndef ECB_MEMORY_FENCE
498 #if ECB_GCC_VERSION(2,5)
499 #if __x86
500 #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
501 #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
502 #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE /* better be safe than sorry */
503 #elif __amd64
504 #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
505 #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("lfence" : : : "memory")
506 #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("sfence")
507 #endif
508 #endif
509#endif
510
511#ifndef ECB_MEMORY_FENCE
512 #if ECB_GCC_VERSION(4,4)
513 #define ECB_MEMORY_FENCE __sync_synchronize ()
514 #define ECB_MEMORY_FENCE_ACQUIRE ({ char dummy = 0; __sync_lock_test_and_set (&dummy, 1); })
515 #define ECB_MEMORY_FENCE_RELEASE ({ char dummy = 1; __sync_lock_release (&dummy ); })
516 #elif _MSC_VER >= 1400 /* VC++ 2005 */
517 #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
518 #define ECB_MEMORY_FENCE _ReadWriteBarrier ()
519 #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
520 #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
521 #elif defined(_WIN32)
522 #include <WinNT.h>
523 #define ECB_MEMORY_FENCE MemoryBarrier ()
524 #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
525 #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
526 #endif
527#endif
528
529#ifndef ECB_MEMORY_FENCE
530 #include <pthread.h>
531
532 static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
533 #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
534 #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
535 #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
536#endif
537
497#if ECB_GCC_VERSION(3,1) 538#if ECB_GCC_VERSION(3,1)
498 #define ecb_attribute(attrlist) __attribute__(attrlist) 539 #define ecb_attribute(attrlist) __attribute__(attrlist)
499 #define ecb_is_constant(expr) __builtin_constant_p (expr) 540 #define ecb_is_constant(expr) __builtin_constant_p (expr)
500 #define ecb_expect(expr,value) __builtin_expect ((expr),(value)) 541 #define ecb_expect(expr,value) __builtin_expect ((expr),(value))
501 #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality) 542 #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
964 memset ((void *)(base), 0, sizeof (*(base)) * (count)) 1005 memset ((void *)(base), 0, sizeof (*(base)) * (count))
965 1006
966#define array_needsize(type,base,cur,cnt,init) \ 1007#define array_needsize(type,base,cur,cnt,init) \
967 if (expect_false ((cnt) > (cur))) \ 1008 if (expect_false ((cnt) > (cur))) \
968 { \ 1009 { \
969 int ocur_ = (cur); \ 1010 int ecb_unused ocur_ = (cur); \
970 (base) = (type *)array_realloc \ 1011 (base) = (type *)array_realloc \
971 (sizeof (type), (base), &(cur), (cnt)); \ 1012 (sizeof (type), (base), &(cur), (cnt)); \
972 init ((base) + (ocur_), (cur) - ocur_); \ 1013 init ((base) + (ocur_), (cur) - ocur_); \
973 } 1014 }
974 1015
1420} 1461}
1421 1462
1422inline_speed void 1463inline_speed void
1423evpipe_write (EV_P_ EV_ATOMIC_T *flag) 1464evpipe_write (EV_P_ EV_ATOMIC_T *flag)
1424{ 1465{
1425 if (!*flag) 1466 if (expect_true (*flag))
1426 { 1467 return;
1468
1427 *flag = 1; 1469 *flag = 1;
1428 1470
1471 ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */
1472
1429 pipe_write_skipped = 1; 1473 pipe_write_skipped = 1;
1430 1474
1475 ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */
1476
1431 if (pipe_write_wanted) 1477 if (pipe_write_wanted)
1478 {
1479 int old_errno;
1480
1481 pipe_write_skipped = 0; /* just an optimsiation, no fence needed */
1482
1483 old_errno = errno; /* save errno because write will clobber it */
1484
1485#if EV_USE_EVENTFD
1486 if (evfd >= 0)
1432 { 1487 {
1433 int old_errno;
1434
1435 pipe_write_skipped = 0;
1436
1437 old_errno = errno; /* save errno because write will clobber it */
1438
1439#if EV_USE_EVENTFD
1440 if (evfd >= 0)
1441 {
1442 uint64_t counter = 1; 1488 uint64_t counter = 1;
1443 write (evfd, &counter, sizeof (uint64_t)); 1489 write (evfd, &counter, sizeof (uint64_t));
1444 }
1445 else
1446#endif
1447 {
1448 /* win32 people keep sending patches that change this write() to send() */
1449 /* and then run away. but send() is wrong, it wants a socket handle on win32 */
1450 /* so when you think this write should be a send instead, please find out */
1451 /* where your send() is from - it's definitely not the microsoft send, and */
1452 /* tell me. thank you. */
1453 write (evpipe [1], &(evpipe [1]), 1);
1454 }
1455
1456 errno = old_errno;
1457 } 1490 }
1491 else
1492#endif
1493 {
1494 /* win32 people keep sending patches that change this write() to send() */
1495 /* and then run away. but send() is wrong, it wants a socket handle on win32 */
1496 /* so when you think this write should be a send instead, please find out */
1497 /* where your send() is from - it's definitely not the microsoft send, and */
1498 /* tell me. thank you. */
1499 write (evpipe [1], &(evpipe [1]), 1);
1500 }
1501
1502 errno = old_errno;
1458 } 1503 }
1459} 1504}
1460 1505
1461/* called whenever the libev signal pipe */ 1506/* called whenever the libev signal pipe */
1462/* got some events (signal, async) */ 1507/* got some events (signal, async) */
1520 1565
1521 if (!EV_A) 1566 if (!EV_A)
1522 return; 1567 return;
1523#endif 1568#endif
1524 1569
1525 evpipe_init (EV_A); 1570 if (!ev_active (&pipe_w))
1571 return;
1526 1572
1527 signals [signum - 1].pending = 1; 1573 signals [signum - 1].pending = 1;
1528 evpipe_write (EV_A_ &sig_pending); 1574 evpipe_write (EV_A_ &sig_pending);
1529} 1575}
1530 1576
2572 time_update (EV_A_ 1e100); 2618 time_update (EV_A_ 1e100);
2573 2619
2574 /* from now on, we want a pipe-wake-up */ 2620 /* from now on, we want a pipe-wake-up */
2575 pipe_write_wanted = 1; 2621 pipe_write_wanted = 1;
2576 2622
2623 ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */
2624
2577 if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) 2625 if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))
2578 { 2626 {
2579 waittime = MAX_BLOCKTIME; 2627 waittime = MAX_BLOCKTIME;
2580 2628
2581 if (timercnt) 2629 if (timercnt)
2622#endif 2670#endif
2623 assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */ 2671 assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
2624 backend_poll (EV_A_ waittime); 2672 backend_poll (EV_A_ waittime);
2625 assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */ 2673 assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
2626 2674
2627 pipe_write_wanted = 0; 2675 pipe_write_wanted = 0; /* just an optimsiation, no fence needed */
2628 2676
2629 if (pipe_write_skipped) 2677 if (pipe_write_skipped)
2630 { 2678 {
2631 assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w))); 2679 assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));
2632 ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); 2680 ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines