… | |
… | |
48 | #include <inttypes.h> |
48 | #include <inttypes.h> |
49 | #endif |
49 | #endif |
50 | |
50 | |
51 | /* many compilers define _GNUC_ to some versions but then only implement |
51 | /* many compilers define _GNUC_ to some versions but then only implement |
52 | * what their idiot authors think are the "more important" extensions, |
52 | * what their idiot authors think are the "more important" extensions, |
53 | * causing enourmous grief in return for some better fake benchmark numbers. |
53 | * causing enormous grief in return for some better fake benchmark numbers. |
54 | * or so. |
54 | * or so. |
55 | * we try to detect these and simply assume they are not gcc - if they have |
55 | * we try to detect these and simply assume they are not gcc - if they have |
56 | * an issue with that they should have done it right in the first place. |
56 | * an issue with that they should have done it right in the first place. |
57 | */ |
57 | */ |
58 | #ifndef ECB_GCC_VERSION |
58 | #ifndef ECB_GCC_VERSION |
… | |
… | |
62 | #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) |
62 | #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) |
63 | #endif |
63 | #endif |
64 | #endif |
64 | #endif |
65 | |
65 | |
66 | /*****************************************************************************/ |
66 | /*****************************************************************************/ |
|
|
67 | |
|
|
68 | /* ECB_NO_THREADS - ecb is not used by multiple threads, ever */ |
|
|
69 | /* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */ |
|
|
70 | |
|
|
71 | #if ECB_NO_THREADS || ECB_NO_SMP |
|
|
72 | #define ECB_MEMORY_FENCE do { } while (0) |
|
|
73 | #define ECB_MEMORY_FENCE_ACQUIRE do { } while (0) |
|
|
74 | #define ECB_MEMORY_FENCE_RELEASE do { } while (0) |
|
|
75 | #endif |
67 | |
76 | |
68 | #ifndef ECB_MEMORY_FENCE |
77 | #ifndef ECB_MEMORY_FENCE |
69 | #if ECB_GCC_VERSION(2,5) |
78 | #if ECB_GCC_VERSION(2,5) |
70 | #if __x86 |
79 | #if __x86 |
71 | #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") |
80 | #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") |
… | |
… | |
100 | #ifndef ECB_MEMORY_FENCE |
109 | #ifndef ECB_MEMORY_FENCE |
101 | /* |
110 | /* |
102 | * if you get undefined symbol references to pthread_mutex_lock, |
111 | * if you get undefined symbol references to pthread_mutex_lock, |
103 | * or failure to find pthread.h, then you should implement |
112 | * or failure to find pthread.h, then you should implement |
104 | * the ECB_MEMORY_FENCE operations for your cpu/compiler |
113 | * the ECB_MEMORY_FENCE operations for your cpu/compiler |
105 | * OR proide pthread.h and link against the posix thread library |
114 | * OR provide pthread.h and link against the posix thread library |
106 | * of your system. |
115 | * of your system. |
107 | */ |
116 | */ |
108 | #include <pthread.h> |
117 | #include <pthread.h> |
|
|
118 | #define ECB_NEEDS_PTHREADS 1 |
|
|
119 | #define ECB_MEMORY_FENCE_NEEDS_PTHREADS 1 |
109 | |
120 | |
110 | static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER; |
121 | static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER; |
111 | #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0) |
122 | #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0) |
112 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
123 | #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE |
113 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |
124 | #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE |