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 #include <sys/syscall.h>
00028
00029 static inline long
00030 sys_futex0 (int *addr, int op, int val)
00031 {
00032 register long int g1 __asm__ ("g1");
00033 register long int o0 __asm__ ("o0");
00034 register long int o1 __asm__ ("o1");
00035 register long int o2 __asm__ ("o2");
00036 register long int o3 __asm__ ("o3");
00037
00038 g1 = SYS_futex;
00039 o0 = (long) addr;
00040 o1 = op;
00041 o2 = val;
00042 o3 = 0;
00043
00044 #ifdef __arch64__
00045 # define SYSCALL_STRING "ta\t0x6d; bcs,a,pt %%xcc, 1f; sub %%g0, %%o0, %%o0; 1:"
00046 #else
00047 # define SYSCALL_STRING "ta\t0x10; bcs,a 1f; sub %%g0, %%o0, %%o0; 1:"
00048 #endif
00049
00050 __asm volatile (SYSCALL_STRING
00051 : "=r" (g1), "=r" (o0)
00052 : "0" (g1), "1" (o0), "r" (o1), "r" (o2), "r" (o3)
00053 : "g2", "g3", "g4", "g5", "g6",
00054 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
00055 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
00056 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
00057 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
00058 #ifdef __arch64__
00059 "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
00060 "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
00061 #endif
00062 "cc", "memory");
00063 return o0;
00064 }
00065
00066 static inline void
00067 futex_wait (int *addr, int val)
00068 {
00069 long err = sys_futex0 (addr, gomp_futex_wait, val);
00070 if (__builtin_expect (err == ENOSYS, 0))
00071 {
00072 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00073 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00074 sys_futex0 (addr, gomp_futex_wait, val);
00075 }
00076 }
00077
00078 static inline void
00079 futex_wake (int *addr, int count)
00080 {
00081 long err = sys_futex0 (addr, gomp_futex_wake, count);
00082 if (__builtin_expect (err == ENOSYS, 0))
00083 {
00084 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00085 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00086 sys_futex0 (addr, gomp_futex_wake, count);
00087 }
00088 }
00089
00090 static inline void
00091 cpu_relax (void)
00092 {
00093 #if defined __arch64__ || defined __sparc_v9__
00094 __asm volatile ("membar #LoadLoad" : : : "memory");
00095 #else
00096 __asm volatile ("" : : : "memory");
00097 #endif
00098 }
00099
00100 static inline void
00101 atomic_write_barrier (void)
00102 {
00103 #if defined __arch64__ || defined __sparc_v9__
00104 __asm volatile ("membar #StoreStore" : : : "memory");
00105 #else
00106 __sync_synchronize ();
00107 #endif
00108 }