1 /******************************************************************************/ 2 #ifdef JEMALLOC_H_TYPES 3 4 #endif /* JEMALLOC_H_TYPES */ 5 /******************************************************************************/ 6 #ifdef JEMALLOC_H_STRUCTS 7 8 #endif /* JEMALLOC_H_STRUCTS */ 9 /******************************************************************************/ 10 #ifdef JEMALLOC_H_EXTERNS 11 12 #endif /* JEMALLOC_H_EXTERNS */ 13 /******************************************************************************/ 14 #ifdef JEMALLOC_H_INLINES 15 16 #ifndef JEMALLOC_ENABLE_INLINE 17 void mb_write(void); 18 #endif 19 20 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MB_C_)) 21 #ifdef __i386__ 22 /* 23 * According to the Intel Architecture Software Developer's Manual, current 24 * processors execute instructions in order from the perspective of other 25 * processors in a multiprocessor system, but 1) Intel reserves the right to 26 * change that, and 2) the compiler's optimizer could re-order instructions if 27 * there weren't some form of barrier. Therefore, even if running on an 28 * architecture that does not need memory barriers (everything through at least 29 * i686), an "optimizer barrier" is necessary. 30 */ 31 JEMALLOC_INLINE void mb_write(void)32mb_write(void) 33 { 34 35 # if 0 36 /* This is a true memory barrier. */ 37 asm volatile ("pusha;" 38 "xor %%eax,%%eax;" 39 "cpuid;" 40 "popa;" 41 : /* Outputs. */ 42 : /* Inputs. */ 43 : "memory" /* Clobbers. */ 44 ); 45 #else 46 /* 47 * This is hopefully enough to keep the compiler from reordering 48 * instructions around this one. 49 */ 50 asm volatile ("nop;" 51 : /* Outputs. */ 52 : /* Inputs. */ 53 : "memory" /* Clobbers. */ 54 ); 55 #endif 56 } 57 #elif (defined(__amd64__) || defined(__x86_64__)) 58 JEMALLOC_INLINE void mb_write(void)59mb_write(void) 60 { 61 62 asm volatile ("sfence" 63 : /* Outputs. */ 64 : /* Inputs. */ 65 : "memory" /* Clobbers. */ 66 ); 67 } 68 #elif defined(__powerpc__) 69 JEMALLOC_INLINE void mb_write(void)70mb_write(void) 71 { 72 73 asm volatile ("eieio" 74 : /* Outputs. */ 75 : /* Inputs. */ 76 : "memory" /* Clobbers. */ 77 ); 78 } 79 #elif defined(__sparc64__) 80 JEMALLOC_INLINE void mb_write(void)81mb_write(void) 82 { 83 84 asm volatile ("membar #StoreStore" 85 : /* Outputs. */ 86 : /* Inputs. */ 87 : "memory" /* Clobbers. */ 88 ); 89 } 90 #elif defined(__tile__) 91 JEMALLOC_INLINE void mb_write(void)92mb_write(void) 93 { 94 95 __sync_synchronize(); 96 } 97 #else 98 /* 99 * This is much slower than a simple memory barrier, but the semantics of mutex 100 * unlock make this work. 101 */ 102 JEMALLOC_INLINE void mb_write(void)103mb_write(void) 104 { 105 malloc_mutex_t mtx; 106 107 malloc_mutex_init(&mtx); 108 malloc_mutex_lock(&mtx); 109 malloc_mutex_unlock(&mtx); 110 } 111 #endif 112 #endif 113 114 #endif /* JEMALLOC_H_INLINES */ 115 /******************************************************************************/ 116