… | |
… | |
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)) \ |
… | |
… | |
2807 | #ifdef __FreeBSD__ |
2809 | #ifdef __FreeBSD__ |
2808 | flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */ |
2810 | flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */ |
2809 | #endif |
2811 | #endif |
2810 | |
2812 | |
2811 | /* TODO: linuxaio is very experimental */ |
2813 | /* TODO: linuxaio is very experimental */ |
|
|
2814 | #if !EV_RECOMMEND_LINUXAIO |
2812 | flags &= ~EVBACKEND_LINUXAIO; |
2815 | flags &= ~EVBACKEND_LINUXAIO; |
|
|
2816 | #endif |
2813 | |
2817 | |
2814 | return flags; |
2818 | return flags; |
2815 | } |
2819 | } |
2816 | |
2820 | |
2817 | ecb_cold |
2821 | ecb_cold |