00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef __LP64__
00028 # ifndef SYS_futex
00029 # define SYS_futex 202
00030 # endif
00031
00032 static inline void
00033 futex_wait (int *addr, int val)
00034 {
00035 register long r10 __asm__("%r10");
00036 long res;
00037
00038 r10 = 0;
00039 __asm volatile ("syscall"
00040 : "=a" (res)
00041 : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wait),
00042 "d" (val), "r" (r10)
00043 : "r11", "rcx", "memory");
00044 if (__builtin_expect (res == -ENOSYS, 0))
00045 {
00046 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00047 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00048 r10 = 0;
00049 __asm volatile ("syscall"
00050 : "=a" (res)
00051 : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wait),
00052 "d" (val), "r" (r10)
00053 : "r11", "rcx", "memory");
00054 }
00055 }
00056
00057 static inline void
00058 futex_wake (int *addr, int count)
00059 {
00060 long res;
00061
00062 __asm volatile ("syscall"
00063 : "=a" (res)
00064 : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wake),
00065 "d" (count)
00066 : "r11", "rcx", "memory");
00067 if (__builtin_expect (res == -ENOSYS, 0))
00068 {
00069 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00070 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00071 __asm volatile ("syscall"
00072 : "=a" (res)
00073 : "0" (SYS_futex), "D" (addr), "S" (gomp_futex_wake),
00074 "d" (count)
00075 : "r11", "rcx", "memory");
00076 }
00077 }
00078 #else
00079 # ifndef SYS_futex
00080 # define SYS_futex 240
00081 # endif
00082
00083 # ifdef __PIC__
00084
00085 static inline long
00086 sys_futex0 (int *addr, int op, int val)
00087 {
00088 long res;
00089
00090 __asm volatile ("xchgl\t%%ebx, %2\n\t"
00091 "int\t$0x80\n\t"
00092 "xchgl\t%%ebx, %2"
00093 : "=a" (res)
00094 : "0"(SYS_futex), "r" (addr), "c"(op),
00095 "d"(val), "S"(0)
00096 : "memory");
00097 return res;
00098 }
00099
00100 # else
00101
00102 static inline long
00103 sys_futex0 (int *addr, int op, int val)
00104 {
00105 long res;
00106
00107 __asm volatile ("int $0x80"
00108 : "=a" (res)
00109 : "0"(SYS_futex), "b" (addr), "c"(op),
00110 "d"(val), "S"(0)
00111 : "memory");
00112 return res;
00113 }
00114
00115 # endif
00116
00117 static inline void
00118 futex_wait (int *addr, int val)
00119 {
00120 long res = sys_futex0 (addr, gomp_futex_wait, val);
00121 if (__builtin_expect (res == -ENOSYS, 0))
00122 {
00123 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00124 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00125 sys_futex0 (addr, gomp_futex_wait, val);
00126 }
00127 }
00128
00129 static inline void
00130 futex_wake (int *addr, int count)
00131 {
00132 long res = sys_futex0 (addr, gomp_futex_wake, count);
00133 if (__builtin_expect (res == -ENOSYS, 0))
00134 {
00135 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00136 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00137 sys_futex0 (addr, gomp_futex_wake, count);
00138 }
00139 }
00140
00141 #endif
00142
00143 static inline void
00144 cpu_relax (void)
00145 {
00146 __asm volatile ("rep; nop" : : : "memory");
00147 }
00148
00149 static inline void
00150 atomic_write_barrier (void)
00151 {
00152 __sync_synchronize ();
00153 }