… | |
… | |
438 | # endif |
438 | # endif |
439 | #endif |
439 | #endif |
440 | |
440 | |
441 | #if EV_USE_LINUXAIO |
441 | #if EV_USE_LINUXAIO |
442 | # include <sys/syscall.h> |
442 | # include <sys/syscall.h> |
443 | # if !SYS_io_getevents || !EV_USE_EPOLL |
443 | # if !SYS_io_getevents || !EV_USE_EPOLL /* ev_linxaio uses ev_poll.c:ev_epoll_create */ |
444 | # undef EV_USE_LINUXAIO |
444 | # undef EV_USE_LINUXAIO |
445 | # define EV_USE_LINUXAIO 0 |
445 | # define EV_USE_LINUXAIO 0 |
446 | # endif |
446 | # endif |
447 | #endif |
447 | #endif |
448 | |
448 | |
… | |
… | |
559 | |
559 | |
560 | #ifndef ECB_H |
560 | #ifndef ECB_H |
561 | #define ECB_H |
561 | #define ECB_H |
562 | |
562 | |
563 | /* 16 bits major, 16 bits minor */ |
563 | /* 16 bits major, 16 bits minor */ |
564 | #define ECB_VERSION 0x00010005 |
564 | #define ECB_VERSION 0x00010006 |
565 | |
565 | |
566 | #ifdef _WIN32 |
566 | #ifdef _WIN32 |
567 | typedef signed char int8_t; |
567 | typedef signed char int8_t; |
568 | typedef unsigned char uint8_t; |
568 | typedef unsigned char uint8_t; |
569 | typedef signed short int16_t; |
569 | typedef signed short int16_t; |
… | |
… | |
683 | #include <intrin.h> /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */ |
683 | #include <intrin.h> /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */ |
684 | #endif |
684 | #endif |
685 | |
685 | |
686 | #ifndef ECB_MEMORY_FENCE |
686 | #ifndef ECB_MEMORY_FENCE |
687 | #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 |
687 | #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 |
|
|
688 | #define ECB_MEMORY_FENCE_RELAXED __asm__ __volatile__ ("" : : : "memory") |
688 | #if __i386 || __i386__ |
689 | #if __i386 || __i386__ |
689 | #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") |
690 | #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") |
690 | #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") |
691 | #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") |
691 | #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory") |
692 | #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory") |
692 | #elif ECB_GCC_AMD64 |
693 | #elif ECB_GCC_AMD64 |
… | |
… | |
742 | #if ECB_GCC_VERSION(4,7) |
743 | #if ECB_GCC_VERSION(4,7) |
743 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
744 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
744 | #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) |
745 | #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) |
745 | #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE) |
746 | #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE) |
746 | #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE) |
747 | #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE) |
|
|
748 | #define ECB_MEMORY_FENCE_RELAXED __atomic_thread_fence (__ATOMIC_RELAXED) |
747 | |
749 | |
748 | #elif ECB_CLANG_EXTENSION(c_atomic) |
750 | #elif ECB_CLANG_EXTENSION(c_atomic) |
749 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
751 | /* see comment below (stdatomic.h) about the C11 memory model. */ |
750 | #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) |
752 | #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) |
751 | #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE) |
753 | #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE) |
752 | #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE) |
754 | #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE) |
|
|
755 | #define ECB_MEMORY_FENCE_RELAXED __c11_atomic_thread_fence (__ATOMIC_RELAXED) |
753 | |
756 | |
754 | #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ |
757 | #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ |
755 | #define ECB_MEMORY_FENCE __sync_synchronize () |
758 | #define ECB_MEMORY_FENCE __sync_synchronize () |
756 | #elif _MSC_VER >= 1500 /* VC++ 2008 */ |
759 | #elif _MSC_VER >= 1500 /* VC++ 2008 */ |
757 | /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */ |
760 | /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */ |
… | |
… | |
767 | #elif defined _WIN32 |
770 | #elif defined _WIN32 |
768 | #include <WinNT.h> |
771 | #include <WinNT.h> |
769 | #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */ |
772 | #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */ |
770 | #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 |
773 | #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 |
771 | #include <mbarrier.h> |
774 | #include <mbarrier.h> |
772 | #define ECB_MEMORY_FENCE __machine_rw_barrier () |
775 | #define ECB_MEMORY_FENCE __machine_rw_barrier () |
773 | #define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier () |
776 | #define ECB_MEMORY_FENCE_ACQUIRE __machine_acq_barrier () |
774 | #define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier () |
777 | #define ECB_MEMORY_FENCE_RELEASE __machine_rel_barrier () |
|
|
778 | #define ECB_MEMORY_FENCE_RELAXED __compiler_barrier () |
775 | #elif __xlC__ |
779 | #elif __xlC__ |
776 | #define ECB_MEMORY_FENCE __sync () |
780 | #define ECB_MEMORY_FENCE __sync () |
777 | #endif |
781 | #endif |
778 | #endif |
782 | #endif |
779 | |
783 | |
780 | #ifndef ECB_MEMORY_FENCE |
784 | #ifndef ECB_MEMORY_FENCE |
781 | #if ECB_C11 && !defined __STDC_NO_ATOMICS__ |
785 | #if ECB_C11 && !defined __STDC_NO_ATOMICS__ |
782 | /* we assume that these memory fences work on all variables/all memory accesses, */ |
786 | /* we assume that these memory fences work on all variables/all memory accesses, */ |
783 | /* not just C11 atomics and atomic accesses */ |
787 | /* not just C11 atomics and atomic accesses */ |
784 | #include <stdatomic.h> |
788 | #include <stdatomic.h> |
785 | /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */ |
|
|
786 | /* any fence other than seq_cst, which isn't very efficient for us. */ |
|
|
787 | /* Why that is, we don't know - either the C11 memory model is quite useless */ |
|
|
788 | /* for most usages, or gcc and clang have a bug */ |
|
|
789 | /* I *currently* lean towards the latter, and inefficiently implement */ |
|
|
790 | /* all three of ecb's fences as a seq_cst fence */ |
|
|
791 | /* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */ |
|
|
792 | /* for all __atomic_thread_fence's except seq_cst */ |
|
|
793 | #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) |
789 | #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) |
|
|
790 | #define ECB_MEMORY_FENCE_ACQUIRE atomic_thread_fence (memory_order_acquire) |
|
|
791 | #define ECB_MEMORY_FENCE_RELEASE atomic_thread_fence (memory_order_release) |
794 | #endif |
792 | #endif |
795 | #endif |
793 | #endif |
796 | |
794 | |
797 | #ifndef ECB_MEMORY_FENCE |
795 | #ifndef ECB_MEMORY_FENCE |
798 | #if !ECB_AVOID_PTHREADS |
796 | #if !ECB_AVOID_PTHREADS |
… | |
… | |
816 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
814 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
817 | #endif |
815 | #endif |
818 | |
816 | |
819 | #if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE |
817 | #if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE |
820 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |
818 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |
|
|
819 | #endif |
|
|
820 | |
|
|
821 | #if !defined ECB_MEMORY_FENCE_RELAXED && defined ECB_MEMORY_FENCE |
|
|
822 | #define ECB_MEMORY_FENCE_RELAXED ECB_MEMORY_FENCE /* very heavy-handed */ |
821 | #endif |
823 | #endif |
822 | |
824 | |
823 | /*****************************************************************************/ |
825 | /*****************************************************************************/ |
824 | |
826 | |
825 | #if ECB_CPP |
827 | #if ECB_CPP |
… | |
… | |
1989 | { |
1991 | { |
1990 | *cur = array_nextsize (elem, *cur, cnt); |
1992 | *cur = array_nextsize (elem, *cur, cnt); |
1991 | return ev_realloc (base, elem * *cur); |
1993 | return ev_realloc (base, elem * *cur); |
1992 | } |
1994 | } |
1993 | |
1995 | |
1994 | #define array_needsize_noinit(base,count) |
1996 | #define array_needsize_noinit(base,offset,count) |
1995 | |
1997 | |
1996 | #define array_needsize_zerofill(base,count) \ |
1998 | #define array_needsize_zerofill(base,offset,count) \ |
1997 | memset ((void *)(base), 0, sizeof (*(base)) * (count)) |
1999 | memset ((void *)(base + offset), 0, sizeof (*(base)) * (count)) |
1998 | |
2000 | |
1999 | #define array_needsize(type,base,cur,cnt,init) \ |
2001 | #define array_needsize(type,base,cur,cnt,init) \ |
2000 | if (expect_false ((cnt) > (cur))) \ |
2002 | if (expect_false ((cnt) > (cur))) \ |
2001 | { \ |
2003 | { \ |
2002 | ecb_unused int ocur_ = (cur); \ |
2004 | ecb_unused int ocur_ = (cur); \ |
2003 | (base) = (type *)array_realloc \ |
2005 | (base) = (type *)array_realloc \ |
2004 | (sizeof (type), (base), &(cur), (cnt)); \ |
2006 | (sizeof (type), (base), &(cur), (cnt)); \ |
2005 | init ((base) + (ocur_), (cur) - ocur_); \ |
2007 | init ((base), ocur_, ((cur) - ocur_)); \ |
2006 | } |
2008 | } |
2007 | |
2009 | |
2008 | #if 0 |
2010 | #if 0 |
2009 | #define array_slim(type,stem) \ |
2011 | #define array_slim(type,stem) \ |
2010 | if (stem ## max < array_roundsize (stem ## cnt >> 2)) \ |
2012 | if (stem ## max < array_roundsize (stem ## cnt >> 2)) \ |
… | |
… | |
2145 | ev_io *w; |
2147 | ev_io *w; |
2146 | |
2148 | |
2147 | unsigned char o_events = anfd->events; |
2149 | unsigned char o_events = anfd->events; |
2148 | unsigned char o_reify = anfd->reify; |
2150 | unsigned char o_reify = anfd->reify; |
2149 | |
2151 | |
2150 | anfd->reify = 0; |
2152 | anfd->reify = 0; |
2151 | |
2153 | |
2152 | /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */ |
2154 | /*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */ |
2153 | { |
2155 | { |
2154 | anfd->events = 0; |
2156 | anfd->events = 0; |
2155 | |
2157 | |
… | |
… | |
3921 | return; |
3923 | return; |
3922 | |
3924 | |
3923 | assert (("libev: ev_io_start called with negative fd", fd >= 0)); |
3925 | assert (("libev: ev_io_start called with negative fd", fd >= 0)); |
3924 | assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE)))); |
3926 | assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE)))); |
3925 | |
3927 | |
|
|
3928 | #if EV_VERIFY >= 2 |
|
|
3929 | assert (("libev: ev_io_start called on watcher with invalid fd", fd_valid (fd))); |
|
|
3930 | #endif |
3926 | EV_FREQUENT_CHECK; |
3931 | EV_FREQUENT_CHECK; |
3927 | |
3932 | |
3928 | ev_start (EV_A_ (W)w, 1); |
3933 | ev_start (EV_A_ (W)w, 1); |
3929 | array_needsize (ANFD, anfds, anfdmax, fd + 1, array_needsize_zerofill); |
3934 | array_needsize (ANFD, anfds, anfdmax, fd + 1, array_needsize_zerofill); |
3930 | wlist_add (&anfds[fd].head, (WL)w); |
3935 | wlist_add (&anfds[fd].head, (WL)w); |
… | |
… | |
3946 | if (expect_false (!ev_is_active (w))) |
3951 | if (expect_false (!ev_is_active (w))) |
3947 | return; |
3952 | return; |
3948 | |
3953 | |
3949 | assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax)); |
3954 | assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax)); |
3950 | |
3955 | |
|
|
3956 | #if EV_VERIFY >= 2 |
|
|
3957 | assert (("libev: ev_io_stop called on watcher with invalid fd", fd_valid (w->fd))); |
|
|
3958 | #endif |
3951 | EV_FREQUENT_CHECK; |
3959 | EV_FREQUENT_CHECK; |
3952 | |
3960 | |
3953 | wlist_del (&anfds[w->fd].head, (WL)w); |
3961 | wlist_del (&anfds[w->fd].head, (WL)w); |
3954 | ev_stop (EV_A_ (W)w); |
3962 | ev_stop (EV_A_ (W)w); |
3955 | |
3963 | |