config/linux/x86/futex.h

Go to the documentation of this file.
00001 /* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
00002    Contributed by Richard Henderson <rth@redhat.com>.
00003 
00004    This file is part of the GNU OpenMP Library (libgomp).
00005 
00006    Libgomp is free software; you can redistribute it and/or modify it
00007    under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3, or (at your option)
00009    any later version.
00010 
00011    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
00012    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00014    more details.
00015 
00016    Under Section 7 of GPL version 3, you are granted additional
00017    permissions described in the GCC Runtime Library Exception, version
00018    3.1, as published by the Free Software Foundation.
00019 
00020    You should have received a copy of the GNU General Public License and
00021    a copy of the GCC Runtime Library Exception along with this program;
00022    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023    <http://www.gnu.org/licenses/>.  */
00024 
00025 /* Provide target-specific access to the futex system call.  */
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 /* __PIC__ */
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 /* __LP64__ */
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 }

Generated on Fri Apr 5 05:38:09 2013 for Libgomp by  doxygen 1.4.7