ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libecb/ecb.h
(Generate patch)

Comparing libecb/ecb.h (file contents):
Revision 1.94 by root, Tue May 29 21:03:20 2012 UTC vs.
Revision 1.98 by root, Thu Jun 7 21:25:13 2012 UTC

83 83
84#define ECB_C (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */ 84#define ECB_C (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */
85#define ECB_C99 (__STDC_VERSION__ >= 199901L) 85#define ECB_C99 (__STDC_VERSION__ >= 199901L)
86#define ECB_C11 (__STDC_VERSION__ >= 201112L) 86#define ECB_C11 (__STDC_VERSION__ >= 201112L)
87#define ECB_CPP (__cplusplus+0) 87#define ECB_CPP (__cplusplus+0)
88#define ECB_CPP98 (__cplusplus >= 199711L)
89#define ECB_CPP11 (__cplusplus >= 201103L) 88#define ECB_CPP11 (__cplusplus >= 201103L)
90 89
91/*****************************************************************************/ 90/*****************************************************************************/
92 91
93/* ECB_NO_THREADS - ecb is not used by multiple threads, ever */ 92/* ECB_NO_THREADS - ecb is not used by multiple threads, ever */
94/* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */ 93/* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */
95 94
96#if ECB_NO_THREADS 95#if ECB_NO_THREADS
97# define ECB_NO_SMP 1 96 #define ECB_NO_SMP 1
98#endif 97#endif
99 98
100#if ECB_NO_SMP 99#if ECB_NO_SMP
101 #define ECB_MEMORY_FENCE do { } while (0) 100 #define ECB_MEMORY_FENCE do { } while (0)
102#endif 101#endif
138 #endif 137 #endif
139#endif 138#endif
140 139
141#ifndef ECB_MEMORY_FENCE 140#ifndef ECB_MEMORY_FENCE
142 #if ECB_GCC_VERSION(4,7) 141 #if ECB_GCC_VERSION(4,7)
143 /* see comment below about the C11 memory model. in short - avoid */ 142 /* see comment below (stdatomic.h) about the C11 memory model. */
144 #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) 143 #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
145 #elif defined __clang && __has_feature (cxx_atomic) 144 #elif defined __clang && __has_feature (cxx_atomic)
146 /* see above */ 145 /* see comment below (stdatomic.h) about the C11 memory model. */
147 #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) 146 #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
148 #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ 147 #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
149 #define ECB_MEMORY_FENCE __sync_synchronize () 148 #define ECB_MEMORY_FENCE __sync_synchronize ()
150 /*#define ECB_MEMORY_FENCE_ACQUIRE ({ char dummy = 0; __sync_lock_test_and_set (&dummy, 1); }) */
151 /*#define ECB_MEMORY_FENCE_RELEASE ({ char dummy = 1; __sync_lock_release (&dummy ); }) */
152 #elif _MSC_VER >= 1400 /* VC++ 2005 */ 149 #elif _MSC_VER >= 1400 /* VC++ 2005 */
153 #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) 150 #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
154 #define ECB_MEMORY_FENCE _ReadWriteBarrier () 151 #define ECB_MEMORY_FENCE _ReadWriteBarrier ()
155 #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */ 152 #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
156 #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier () 153 #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
170#ifndef ECB_MEMORY_FENCE 167#ifndef ECB_MEMORY_FENCE
171 #if ECB_C11 && !defined __STDC_NO_ATOMICS__ 168 #if ECB_C11 && !defined __STDC_NO_ATOMICS__
172 /* we assume that these memory fences work on all variables/all memory accesses, */ 169 /* we assume that these memory fences work on all variables/all memory accesses, */
173 /* not just C11 atomics and atomic accesses */ 170 /* not just C11 atomics and atomic accesses */
174 #include <stdatomic.h> 171 #include <stdatomic.h>
175 /* unfortunately, the C11 memory model seems to be very limited, and unable to express */ 172 /* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
176 /* simple barrier semantics. That means we need to take out thor's hammer. */ 173 /* any fence other than seq_cst, which isn't very efficient for us. */
174 /* Why that is, we don't know - either the C11 memory model is quite useless */
175 /* for most usages, or gcc and clang have a bug */
176 /* I *currently* lean towards the latter, and inefficiently implement */
177 /* all three of ecb's fences as a seq_cst fence */
177 #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) 178 #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
178 #endif
179 #endif 179 #endif
180#endif 180#endif
181 181
182#ifndef ECB_MEMORY_FENCE 182#ifndef ECB_MEMORY_FENCE
183 #if !ECB_AVOID_PTHREADS 183 #if !ECB_AVOID_PTHREADS
465 465
466ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const; 466ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const;
467ecb_inline unsigned char 467ecb_inline unsigned char
468ecb_byteorder_helper (void) 468ecb_byteorder_helper (void)
469{ 469{
470 const uint32_t u = 0x11223344; 470 /* the union code still generates code under pressure in gcc, */
471 return *(unsigned char *)&u; 471 /* but less than using pointers, and always seem to */
472 /* successfully return a constant. */
473 /* the reason why we have this horrible preprocessor mess */
474 /* is to avoid it in all cases, at leats on common architectures */
475#if __i386 || __i386__ || _M_X86 || __amd64 || __amd64__ || _M_X64
476 return 0x44;
477#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
478 return 0x44;
479#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
480 retrurn 0x11;
481#else
482 union
483 {
484 uint32_t i;
485 uint8_t c;
486 } u = { 0x11223344 };
487 return u.c;
488#endif
472} 489}
473 490
474ecb_inline ecb_bool ecb_big_endian (void) ecb_const; 491ecb_inline ecb_bool ecb_big_endian (void) ecb_const;
475ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; } 492ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
476ecb_inline ecb_bool ecb_little_endian (void) ecb_const; 493ecb_inline ecb_bool ecb_little_endian (void) ecb_const;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines