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
00030
00031 static inline long
00032 sys_futex0(int *addr, long op, int val)
00033 {
00034 register long out0 asm ("out0") = (long) addr;
00035 register long out1 asm ("out1") = op;
00036 register long out2 asm ("out2") = val;
00037 register long out3 asm ("out3") = 0;
00038 register long r8 asm ("r8");
00039 register long r10 asm ("r10");
00040 register long r15 asm ("r15") = SYS_futex;
00041
00042 __asm __volatile ("break 0x100000"
00043 : "=r"(r15), "=r"(out0), "=r"(out1), "=r"(out2), "=r"(out3),
00044 "=r"(r8), "=r"(r10)
00045 : "r"(r15), "r"(out0), "r"(out1), "r"(out2), "r"(out3)
00046 : "memory", "out4", "out5", "out6", "out7",
00047
00048 "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18",
00049 "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27",
00050 "r28", "r29", "r30", "r31",
00051
00052 "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
00053
00054 "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
00055
00056 "b6");
00057 return r8 & r10;
00058 }
00059
00060 static inline void
00061 futex_wait (int *addr, int val)
00062 {
00063 long err = sys_futex0 (addr, gomp_futex_wait, val);
00064 if (__builtin_expect (err == ENOSYS, 0))
00065 {
00066 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00067 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00068 sys_futex0 (addr, gomp_futex_wait, val);
00069 }
00070 }
00071
00072 static inline void
00073 futex_wake (int *addr, int count)
00074 {
00075 long err = sys_futex0 (addr, gomp_futex_wake, count);
00076 if (__builtin_expect (err == ENOSYS, 0))
00077 {
00078 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00079 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00080 sys_futex0 (addr, gomp_futex_wake, count);
00081 }
00082 }
00083
00084 static inline void
00085 cpu_relax (void)
00086 {
00087 __asm volatile ("hint @pause" : : : "memory");
00088 }
00089
00090 static inline void
00091 atomic_write_barrier (void)
00092 {
00093 __sync_synchronize ();
00094 }