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

Comparing libev/ev.c (file contents):
Revision 1.379 by root, Sun Jun 19 17:55:13 2011 UTC vs.
Revision 1.383 by root, Wed Jul 20 00:40:14 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
517 #define ECB_MEMORY_FENCE do { } while (0)
518 #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
519 #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
520 #elif defined(_WIN32) && defined(MemoryBarrier)
521 #define ECB_MEMORY_FENCE MemoryBarrier ()
522 #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
523 #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
524 #endif
525#endif
526
527#ifndef ECB_MEMORY_FENCE
528 #include <pthread.h>
529
530 static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
531 #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
532 #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
533 #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
534#endif
535
497#if ECB_GCC_VERSION(3,1) 536#if ECB_GCC_VERSION(3,1)
498 #define ecb_attribute(attrlist) __attribute__(attrlist) 537 #define ecb_attribute(attrlist) __attribute__(attrlist)
499 #define ecb_is_constant(expr) __builtin_constant_p (expr) 538 #define ecb_is_constant(expr) __builtin_constant_p (expr)
500 #define ecb_expect(expr,value) __builtin_expect ((expr),(value)) 539 #define ecb_expect(expr,value) __builtin_expect ((expr),(value))
501 #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality) 540 #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
964 memset ((void *)(base), 0, sizeof (*(base)) * (count)) 1003 memset ((void *)(base), 0, sizeof (*(base)) * (count))
965 1004
966#define array_needsize(type,base,cur,cnt,init) \ 1005#define array_needsize(type,base,cur,cnt,init) \
967 if (expect_false ((cnt) > (cur))) \ 1006 if (expect_false ((cnt) > (cur))) \
968 { \ 1007 { \
969 int ocur_ = (cur); \ 1008 int ecb_unused ocur_ = (cur); \
970 (base) = (type *)array_realloc \ 1009 (base) = (type *)array_realloc \
971 (sizeof (type), (base), &(cur), (cnt)); \ 1010 (sizeof (type), (base), &(cur), (cnt)); \
972 init ((base) + (ocur_), (cur) - ocur_); \ 1011 init ((base) + (ocur_), (cur) - ocur_); \
973 } 1012 }
974 1013
1417 ev_io_start (EV_A_ &pipe_w); 1456 ev_io_start (EV_A_ &pipe_w);
1418 ev_unref (EV_A); /* watcher should not keep loop alive */ 1457 ev_unref (EV_A); /* watcher should not keep loop alive */
1419 } 1458 }
1420} 1459}
1421 1460
1422inline_size void 1461inline_speed void
1423evpipe_write (EV_P_ EV_ATOMIC_T *flag) 1462evpipe_write (EV_P_ EV_ATOMIC_T *flag)
1424{ 1463{
1425 if (!*flag) 1464 if (expect_true (*flag))
1426 { 1465 return;
1466
1427 *flag = 1; 1467 *flag = 1;
1428 1468
1469 ECB_MEMORY_FENCE_RELEASE;
1470
1429 pipe_write_skipped = 1; 1471 pipe_write_skipped = 1;
1430 1472
1473 ECB_MEMORY_FENCE;
1474
1431 if (pipe_write_wanted) 1475 if (pipe_write_wanted)
1476 {
1477 int old_errno;
1478
1479 pipe_write_skipped = 0; /* optimisation only */
1480
1481 old_errno = errno; /* save errno because write will clobber it */
1482
1483#if EV_USE_EVENTFD
1484 if (evfd >= 0)
1432 { 1485 {
1433 int old_errno = errno; /* save errno because write will clobber it */
1434 char dummy;
1435
1436 pipe_write_skipped = 0;
1437
1438#if EV_USE_EVENTFD
1439 if (evfd >= 0)
1440 {
1441 uint64_t counter = 1; 1486 uint64_t counter = 1;
1442 write (evfd, &counter, sizeof (uint64_t)); 1487 write (evfd, &counter, sizeof (uint64_t));
1443 }
1444 else
1445#endif
1446 {
1447 /* win32 people keep sending patches that change this write() to send() */
1448 /* and then run away. but send() is wrong, it wants a socket handle on win32 */
1449 /* so when you think this write should be a send instead, please find out */
1450 /* where your send() is from - it's definitely not the microsoft send, and */
1451 /* tell me. thank you. */
1452 write (evpipe [1], &dummy, 1);
1453 }
1454
1455 errno = old_errno;
1456 } 1488 }
1489 else
1490#endif
1491 {
1492 /* win32 people keep sending patches that change this write() to send() */
1493 /* and then run away. but send() is wrong, it wants a socket handle on win32 */
1494 /* so when you think this write should be a send instead, please find out */
1495 /* where your send() is from - it's definitely not the microsoft send, and */
1496 /* tell me. thank you. */
1497 write (evpipe [1], &(evpipe [1]), 1);
1498 }
1499
1500 errno = old_errno;
1457 } 1501 }
1458} 1502}
1459 1503
1460/* called whenever the libev signal pipe */ 1504/* called whenever the libev signal pipe */
1461/* got some events (signal, async) */ 1505/* got some events (signal, async) */
1519 1563
1520 if (!EV_A) 1564 if (!EV_A)
1521 return; 1565 return;
1522#endif 1566#endif
1523 1567
1524 evpipe_init (EV_A); 1568 if (!ev_active (&pipe_w))
1569 return;
1525 1570
1526 signals [signum - 1].pending = 1; 1571 signals [signum - 1].pending = 1;
1527 evpipe_write (EV_A_ &sig_pending); 1572 evpipe_write (EV_A_ &sig_pending);
1528} 1573}
1529 1574
2570 /* update time to cancel out callback processing overhead */ 2615 /* update time to cancel out callback processing overhead */
2571 time_update (EV_A_ 1e100); 2616 time_update (EV_A_ 1e100);
2572 2617
2573 /* from now on, we want a pipe-wake-up */ 2618 /* from now on, we want a pipe-wake-up */
2574 pipe_write_wanted = 1; 2619 pipe_write_wanted = 1;
2620
2621 ECB_MEMORY_FENCE;
2575 2622
2576 if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) 2623 if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))
2577 { 2624 {
2578 waittime = MAX_BLOCKTIME; 2625 waittime = MAX_BLOCKTIME;
2579 2626

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines