… | |
… | |
511 | #ifndef ECB_MEMORY_FENCE |
511 | #ifndef ECB_MEMORY_FENCE |
512 | #if ECB_GCC_VERSION(4,4) |
512 | #if ECB_GCC_VERSION(4,4) |
513 | #define ECB_MEMORY_FENCE __sync_synchronize () |
513 | #define ECB_MEMORY_FENCE __sync_synchronize () |
514 | #define ECB_MEMORY_FENCE_ACQUIRE ({ char dummy = 0; __sync_lock_test_and_set (&dummy, 1); }) |
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 ); }) |
515 | #define ECB_MEMORY_FENCE_RELEASE ({ char dummy = 1; __sync_lock_release (&dummy ); }) |
516 | #elif _MSC_VER >= 1400 |
516 | #elif _MSC_VER >= 1400 && 0 /* TODO: only true when using volatiles */ |
517 | #define ECB_MEMORY_FENCE do { } while (0) |
517 | #define ECB_MEMORY_FENCE do { } while (0) |
518 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
518 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
519 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |
519 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |
520 | #elif defined(_WIN32) && defined(MemoryBarrier) |
520 | #elif defined(_WIN32) |
|
|
521 | #include <WinNT.h> |
521 | #define ECB_MEMORY_FENCE MemoryBarrier () |
522 | #define ECB_MEMORY_FENCE MemoryBarrier () |
522 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
523 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
523 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |
524 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |
524 | #endif |
525 | #endif |
525 | #endif |
526 | #endif |
… | |
… | |
1464 | if (expect_true (*flag)) |
1465 | if (expect_true (*flag)) |
1465 | return; |
1466 | return; |
1466 | |
1467 | |
1467 | *flag = 1; |
1468 | *flag = 1; |
1468 | |
1469 | |
1469 | ECB_MEMORY_FENCE_RELEASE; |
1470 | ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */ |
1470 | |
1471 | |
1471 | pipe_write_skipped = 1; |
1472 | pipe_write_skipped = 1; |
1472 | |
1473 | |
1473 | ECB_MEMORY_FENCE; |
1474 | ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */ |
1474 | |
1475 | |
1475 | if (pipe_write_wanted) |
1476 | if (pipe_write_wanted) |
1476 | { |
1477 | { |
1477 | int old_errno; |
1478 | int old_errno; |
1478 | |
1479 | |
1479 | pipe_write_skipped = 0; /* optimisation only */ |
1480 | pipe_write_skipped = 0; /* just an optimsiation, no fence needed */ |
1480 | |
1481 | |
1481 | old_errno = errno; /* save errno because write will clobber it */ |
1482 | old_errno = errno; /* save errno because write will clobber it */ |
1482 | |
1483 | |
1483 | #if EV_USE_EVENTFD |
1484 | #if EV_USE_EVENTFD |
1484 | if (evfd >= 0) |
1485 | if (evfd >= 0) |
… | |
… | |
2616 | time_update (EV_A_ 1e100); |
2617 | time_update (EV_A_ 1e100); |
2617 | |
2618 | |
2618 | /* from now on, we want a pipe-wake-up */ |
2619 | /* from now on, we want a pipe-wake-up */ |
2619 | pipe_write_wanted = 1; |
2620 | pipe_write_wanted = 1; |
2620 | |
2621 | |
2621 | ECB_MEMORY_FENCE; |
2622 | ECB_MEMORY_FENCE; /* amke sure pipe_write_wanted is visible before we check for potential skips */ |
2622 | |
2623 | |
2623 | if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) |
2624 | if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) |
2624 | { |
2625 | { |
2625 | waittime = MAX_BLOCKTIME; |
2626 | waittime = MAX_BLOCKTIME; |
2626 | |
2627 | |
… | |
… | |
2668 | #endif |
2669 | #endif |
2669 | assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */ |
2670 | assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */ |
2670 | backend_poll (EV_A_ waittime); |
2671 | backend_poll (EV_A_ waittime); |
2671 | assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */ |
2672 | assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */ |
2672 | |
2673 | |
2673 | pipe_write_wanted = 0; |
2674 | pipe_write_wanted = 0; /* just an optimsiation, no fence needed */ |
2674 | |
2675 | |
2675 | if (pipe_write_skipped) |
2676 | if (pipe_write_skipped) |
2676 | { |
2677 | { |
2677 | assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w))); |
2678 | assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w))); |
2678 | ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); |
2679 | ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); |