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 r0 __asm__ ("r0");
00033 register long int r3 __asm__ ("r3");
00034 register long int r4 __asm__ ("r4");
00035 register long int r5 __asm__ ("r5");
00036 register long int r6 __asm__ ("r6");
00037
00038 r0 = SYS_futex;
00039 r3 = (long) addr;
00040 r4 = op;
00041 r5 = val;
00042 r6 = 0;
00043
00044
00045
00046
00047
00048 __asm volatile ("sc; mfcr %0"
00049 : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6)
00050 : "r"(r0), "r"(r3), "r"(r4), "r"(r5), "r"(r6)
00051 : "r7", "r8", "r9", "r10", "r11", "r12",
00052 "cr0", "ctr", "memory");
00053 if (__builtin_expect (r0 & (1 << 28), 0))
00054 return r3;
00055 return 0;
00056 }
00057
00058 static inline void
00059 futex_wait (int *addr, int val)
00060 {
00061 long err = sys_futex0 (addr, gomp_futex_wait, val);
00062 if (__builtin_expect (err == ENOSYS, 0))
00063 {
00064 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00065 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00066 sys_futex0 (addr, gomp_futex_wait, val);
00067 }
00068 }
00069
00070 static inline void
00071 futex_wake (int *addr, int count)
00072 {
00073 long err = sys_futex0 (addr, gomp_futex_wake, count);
00074 if (__builtin_expect (err == ENOSYS, 0))
00075 {
00076 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
00077 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
00078 sys_futex0 (addr, gomp_futex_wake, count);
00079 }
00080 }
00081
00082 static inline void
00083 cpu_relax (void)
00084 {
00085 __asm volatile ("" : : : "memory");
00086 }
00087
00088 static inline void
00089 atomic_write_barrier (void)
00090 {
00091 __asm volatile ("eieio" : : : "memory");
00092 }