00001 /* Copyright (C) 2010, 2011 Free Software Foundation, Inc. 00002 Contributed by ARM Ltd. 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 /* The include file hierachy above us (wait.h) has pushed visibility 00028 hidden, this will be applied to prototypes with headers we include 00029 with the effect that we cannot link against an external function 00030 (syscall). The solution here is to push default visibility, include 00031 our required headers then reinstante the original visibility. */ 00032 00033 #pragma GCC visibility push(default) 00034 00035 #define _GNU_SOURCE 00036 #include <unistd.h> 00037 #include <sys/syscall.h> 00038 00039 #pragma GCC visibility pop 00040 00041 static inline void 00042 futex_wait (int *addr, int val) 00043 { 00044 long err = syscall (SYS_futex, addr, gomp_futex_wait, val, NULL); 00045 if (__builtin_expect (err == -ENOSYS, 0)) 00046 { 00047 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; 00048 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; 00049 syscall (SYS_futex, addr, gomp_futex_wait, val, NULL); 00050 } 00051 } 00052 00053 static inline void 00054 futex_wake (int *addr, int count) 00055 { 00056 long err = syscall (SYS_futex, addr, gomp_futex_wake, count); 00057 if (__builtin_expect (err == -ENOSYS, 0)) 00058 { 00059 gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG; 00060 gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG; 00061 syscall (SYS_futex, addr, gomp_futex_wake, count); 00062 } 00063 } 00064 00065 static inline void 00066 cpu_relax (void) 00067 { 00068 __asm volatile ("" : : : "memory"); 00069 } 00070 00071 static inline void 00072 atomic_write_barrier (void) 00073 { 00074 __sync_synchronize (); 00075 }