diff options
Diffstat (limited to 'libgomp/config')
24 files changed, 1702 insertions, 0 deletions
diff --git a/libgomp/config/linux/alpha/futex.h b/libgomp/config/linux/alpha/futex.h new file mode 100644 index 00000000000..98681a8526e --- /dev/null +++ b/libgomp/config/linux/alpha/futex.h @@ -0,0 +1,76 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* Provide target-specific access to the futex system call. */ + +#ifndef SYS_futex +#define SYS_futex 394 +#endif +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + + +static inline void +futex_wait (int *addr, int val) +{ + register long sc_0 __asm__("$0"); + register long sc_16 __asm__("$16"); + register long sc_17 __asm__("$17"); + register long sc_18 __asm__("$18"); + register long sc_19 __asm__("$19"); + + sc_0 = SYS_futex; + sc_16 = (long) addr; + sc_17 = FUTEX_WAIT; + sc_18 = val; + sc_19 = 0; + __asm volatile ("callsys" + : "=r" (sc_0), "=r"(sc_19) + : "0"(sc_0), "r" (sc_16), "r"(sc_17), "r"(sc_18), "1"(sc_19) + : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$22", "$23", "$24", "$25", "$27", "$28", "memory"); +} + +static inline void +futex_wake (int *addr, int count) +{ + register long sc_0 __asm__("$0"); + register long sc_16 __asm__("$16"); + register long sc_17 __asm__("$17"); + register long sc_18 __asm__("$18"); + register long sc_19 __asm__("$19"); + + sc_0 = SYS_futex; + sc_16 = (long) addr; + sc_17 = FUTEX_WAKE; + sc_18 = count; + __asm volatile ("callsys" + : "=r" (sc_0), "=r"(sc_19) + : "0"(sc_0), "r" (sc_16), "r"(sc_17), "r"(sc_18) + : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$22", "$23", "$24", "$25", "$27", "$28", "memory"); +} diff --git a/libgomp/config/linux/bar.c b/libgomp/config/linux/bar.c new file mode 100644 index 00000000000..5c4f32e6f8b --- /dev/null +++ b/libgomp/config/linux/bar.c @@ -0,0 +1,64 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is a Linux specific implementation of a barrier synchronization + mechanism for libgomp. This type is private to the library. This + implementation uses atomic instructions and the futex syscall. */ + +#include "libgomp.h" +#include "futex.h" +#include <limits.h> + + +void +gomp_barrier_wait_end (gomp_barrier_t *bar, bool last) +{ + if (last) + { + bar->generation++; + futex_wake (&bar->generation, INT_MAX); + } + else + { + unsigned int generation = bar->generation; + + gomp_mutex_unlock (&bar->mutex); + + do + futex_wait (&bar->generation, generation); + while (bar->generation == generation); + } + + if (__sync_add_and_fetch (&bar->arrived, -1) == 0) + gomp_mutex_unlock (&bar->mutex); +} + +void +gomp_barrier_wait (gomp_barrier_t *barrier) +{ + gomp_barrier_wait_end (barrier, gomp_barrier_wait_start (barrier)); +} diff --git a/libgomp/config/linux/bar.h b/libgomp/config/linux/bar.h new file mode 100644 index 00000000000..57268585d8b --- /dev/null +++ b/libgomp/config/linux/bar.h @@ -0,0 +1,75 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is a Linux specific implementation of a barrier synchronization + mechanism for libgomp. This type is private to the library. This + implementation uses atomic instructions and the futex syscall. */ + +#ifndef GOMP_BARRIER_H +#define GOMP_BARRIER_H 1 + +#include "mutex.h" + +typedef struct +{ + gomp_mutex_t mutex; + unsigned total; + unsigned arrived; + int generation; +} gomp_barrier_t; + +static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count) +{ + gomp_mutex_init (&bar->mutex); + bar->total = count; + bar->arrived = 0; + bar->generation = 0; +} + +static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count) +{ + gomp_mutex_lock (&bar->mutex); + bar->total = count; + gomp_mutex_unlock (&bar->mutex); +} + +static inline void gomp_barrier_destroy (gomp_barrier_t *bar) +{ + /* Before destroying, make sure all threads have left the barrier. */ + gomp_mutex_lock (&bar->mutex); +} + +extern void gomp_barrier_wait (gomp_barrier_t *); +extern void gomp_barrier_wait_end (gomp_barrier_t *, bool); + +static inline bool gomp_barrier_wait_start (gomp_barrier_t *bar) +{ + gomp_mutex_lock (&bar->mutex); + return ++bar->arrived == bar->total; +} + +#endif /* GOMP_BARRIER_H */ diff --git a/libgomp/config/linux/ia64/futex.h b/libgomp/config/linux/ia64/futex.h new file mode 100644 index 00000000000..5e54982d6f7 --- /dev/null +++ b/libgomp/config/linux/ia64/futex.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* Provide target-specific access to the futex system call. */ + +#include <sys/syscall.h> + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + + +static inline void +sys_futex0(int *addr, int op, int val) +{ + register long out0 asm ("out0") = (long) addr; + register long out1 asm ("out1") = op; + register long out2 asm ("out2") = val; + register long out3 asm ("out3") = 0; + register long r15 asm ("r15") = SYS_futex; + + __asm __volatile ("break 0x100000" + : "=r"(r15), "=r"(out0), "=r"(out1), "=r"(out2), "=r"(out3) + : "r"(r15), "r"(out0), "r"(out1), "r"(out2), "r"(out3) + : "memory", "r8", "r10", "out4", "out5", "out6", "out7", + /* Non-stacked integer registers, minus r8, r10, r15. */ + "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", + "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", + "r28", "r29", "r30", "r31", + /* Predicate registers. */ + "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", + /* Non-rotating fp registers. */ + "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + /* Branch registers. */ + "b6"); +} + +static inline void +futex_wait (int *addr, int val) +{ + sys_futex0 (addr, FUTEX_WAIT, val); +} + +static inline void +futex_wake (int *addr, int count) +{ + sys_futex0 (addr, FUTEX_WAKE, count); +} diff --git a/libgomp/config/linux/lock.c b/libgomp/config/linux/lock.c new file mode 100644 index 00000000000..211f6007b43 --- /dev/null +++ b/libgomp/config/linux/lock.c @@ -0,0 +1,182 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is a Linux specific implementation of the public OpenMP locking + primitives. This implementation uses atomic instructions and the futex + syscall. */ + +#include "libgomp.h" +#include <string.h> +#include <unistd.h> +#include <sys/syscall.h> +#include "futex.h" + + +/* The internal gomp_mutex_t and the external non-recursive omp_lock_t + have the same form. Re-use it. */ + +void +omp_init_lock (omp_lock_t *lock) +{ + gomp_mutex_init (lock); +} + +void +omp_destroy_lock (omp_lock_t *lock) +{ + gomp_mutex_destroy (lock); +} + +void +omp_set_lock (omp_lock_t *lock) +{ + gomp_mutex_lock (lock); +} + +void +omp_unset_lock (omp_lock_t *lock) +{ + gomp_mutex_unlock (lock); +} + +int +omp_test_lock (omp_lock_t *lock) +{ + return __sync_bool_compare_and_swap (lock, 0, 1); +} + +/* The external recursive omp_nest_lock_t form requires additional work. */ + +/* We need an integer to uniquely identify this thread. Most generally + this is the thread's TID, which ideally we'd get this straight from + the TLS block where glibc keeps it. Unfortunately, we can't get at + that directly. + + If we don't support (or have disabled) TLS, one function call is as + good (or bad) as any other. Use the syscall all the time. + + On an ILP32 system (defined here as not LP64), we can make do with + any thread-local pointer. Ideally we'd use the TLS base address, + since that requires the least amount of arithmetic, but that's not + always available directly. Make do with the gomp_thread pointer + since it's handy. */ + +#if !defined (HAVE_TLS) +static inline int gomp_tid (void) +{ + return syscall (SYS_gettid); +} +#elif !defined(__LP64__) +static inline int gomp_tid (void) +{ + return (int) gomp_thread (); +} +#else +static __thread int tid_cache; +static inline int gomp_tid (void) +{ + int tid = tid_cache; + if (__builtin_expect (tid == 0, 0)) + tid_cache = tid = syscall (SYS_gettid); + return tid; +} +#endif + + +void +omp_init_nest_lock (omp_nest_lock_t *lock) +{ + memset (lock, 0, sizeof (lock)); +} + +void +omp_destroy_nest_lock (omp_nest_lock_t *lock) +{ +} + +void +omp_set_nest_lock (omp_nest_lock_t *lock) +{ + int otid, tid = gomp_tid (); + + while (1) + { + otid = __sync_val_compare_and_swap (&lock->owner, 0, tid); + if (otid == 0) + { + lock->count = 1; + return; + } + if (otid == tid) + { + lock->count++; + return; + } + + futex_wait (&lock->owner, otid); + } +} + +void +omp_unset_nest_lock (omp_nest_lock_t *lock) +{ + /* ??? Validate that we own the lock here. */ + + if (--lock->count == 0) + { + __sync_lock_release (&lock->owner); + futex_wake (&lock->owner, 1); + } +} + +int +omp_test_nest_lock (omp_nest_lock_t *lock) +{ + int otid, tid = gomp_tid (); + + otid = __sync_val_compare_and_swap (&lock->owner, 0, tid); + if (otid == 0) + { + lock->count = 1; + return 1; + } + if (otid == tid) + return ++lock->count; + + return 0; +} + +ialias (omp_init_lock) +ialias (omp_init_nest_lock) +ialias (omp_destroy_lock) +ialias (omp_destroy_nest_lock) +ialias (omp_set_lock) +ialias (omp_set_nest_lock) +ialias (omp_unset_lock) +ialias (omp_unset_nest_lock) +ialias (omp_test_lock) +ialias (omp_test_nest_lock) diff --git a/libgomp/config/linux/mutex.c b/libgomp/config/linux/mutex.c new file mode 100644 index 00000000000..fa3dfd1cb03 --- /dev/null +++ b/libgomp/config/linux/mutex.c @@ -0,0 +1,52 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is a Linux specific implementation of a mutex synchronization + mechanism for libgomp. This type is private to the library. This + implementation uses atomic instructions and the futex syscall. */ + +#include "libgomp.h" +#include "futex.h" + + +void +gomp_mutex_lock_slow (gomp_mutex_t *mutex) +{ + do + { + int oldval = __sync_val_compare_and_swap (mutex, 1, 2); + if (oldval != 0) + futex_wait (mutex, 2); + } + while (!__sync_bool_compare_and_swap (mutex, 0, 2)); +} + +void +gomp_mutex_unlock_slow (gomp_mutex_t *mutex) +{ + futex_wake (mutex, 1); +} diff --git a/libgomp/config/linux/mutex.h b/libgomp/config/linux/mutex.h new file mode 100644 index 00000000000..323814aa8e7 --- /dev/null +++ b/libgomp/config/linux/mutex.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is a Linux specific implementation of a mutex synchronization + mechanism for libgomp. This type is private to the library. This + implementation uses atomic instructions and the futex syscall. */ + +#ifndef GOMP_MUTEX_H +#define GOMP_MUTEX_H 1 + +typedef int gomp_mutex_t; + +#define GOMP_MUTEX_INIT_0 1 + +static inline void gomp_mutex_init (gomp_mutex_t *mutex) +{ + *mutex = 0; +} + +extern void gomp_mutex_lock_slow (gomp_mutex_t *mutex); +static inline void gomp_mutex_lock (gomp_mutex_t *mutex) +{ + if (!__sync_bool_compare_and_swap (mutex, 0, 1)) + gomp_mutex_lock_slow (mutex); +} + +extern void gomp_mutex_unlock_slow (gomp_mutex_t *mutex); +static inline void gomp_mutex_unlock (gomp_mutex_t *mutex) +{ + int val = __sync_lock_test_and_set (mutex, 0); + if (__builtin_expect (val > 1, 0)) + gomp_mutex_unlock_slow (mutex); +} + +static inline void gomp_mutex_destroy (gomp_mutex_t *mutex) +{ +} + +#endif /* GOMP_MUTEX_H */ diff --git a/libgomp/config/linux/omp-lock.h b/libgomp/config/linux/omp-lock.h new file mode 100644 index 00000000000..350cba16056 --- /dev/null +++ b/libgomp/config/linux/omp-lock.h @@ -0,0 +1,10 @@ +/* This header is used during the build process to find the size and + alignment of the public OpenMP locks, so that we can export data + structures without polluting the namespace. + + When using the Linux futex primitive, non-recursive locks require + only one int. Recursive locks require we identify the owning thread + and so require two ints. */ + +typedef int omp_lock_t; +typedef struct { int owner, count; } omp_nest_lock_t; diff --git a/libgomp/config/linux/powerpc/futex.h b/libgomp/config/linux/powerpc/futex.h new file mode 100644 index 00000000000..20e03573783 --- /dev/null +++ b/libgomp/config/linux/powerpc/futex.h @@ -0,0 +1,70 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* Provide target-specific access to the futex system call. */ + +#include <sys/syscall.h> +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +static inline void +sys_futex0 (int *addr, int op, int val) +{ + register long int r0 __asm__ ("r0"); + register long int r3 __asm__ ("r3"); + register long int r4 __asm__ ("r4"); + register long int r5 __asm__ ("r5"); + register long int r6 __asm__ ("r6"); + + r0 = SYS_futex; + r3 = (long) addr; + r4 = op; + r5 = val; + r6 = 0; + + /* ??? The powerpc64 sysdep.h file clobbers ctr; the powerpc32 sysdep.h + doesn't. It doesn't much matter for us. In the interest of unity, + go ahead and clobber it always. */ + + __asm volatile ("sc" + : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6) + : "r"(r0), "r"(r3), "r"(r4), "r"(r5), "r"(r6) + : "r7", "r8", "r9", "r10", "r11", "r12", + "cr0", "ctr", "memory"); +} + +static inline void +futex_wait (int *addr, int val) +{ + sys_futex0 (addr, FUTEX_WAIT, val); +} + +static inline void +futex_wake (int *addr, int count) +{ + sys_futex0 (addr, FUTEX_WAKE, count); +} diff --git a/libgomp/config/linux/s390/futex.h b/libgomp/config/linux/s390/futex.h new file mode 100644 index 00000000000..9b3820c0d97 --- /dev/null +++ b/libgomp/config/linux/s390/futex.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Jakub Jelinek <jakub@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* Provide target-specific access to the futex system call. */ + +#include <sys/syscall.h> +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +static inline void +sys_futex0 (int *addr, int op, int val) +{ + register long int gpr2 __asm__ ("2"); + register long int gpr3 __asm__ ("3"); + register long int gpr4 __asm__ ("4"); + register long int gpr5 __asm__ ("5"); + + gpr2 = (long) addr; + gpr3 = op; + gpr4 = val; + gpr5 = 0; + + __asm volatile ("svc %b1" + : "=d" (gpr2) + : "i" (SYS_futex), + "0" (gpr2), "d" (gpr3), "d" (gpr4), "d" (gpr5) + : "memory"); +} + +static inline void +futex_wait (int *addr, int val) +{ + sys_futex0 (addr, FUTEX_WAIT, val); +} + +static inline void +futex_wake (int *addr, int count) +{ + sys_futex0 (addr, FUTEX_WAKE, count); +} diff --git a/libgomp/config/linux/sem.c b/libgomp/config/linux/sem.c new file mode 100644 index 00000000000..798e3f1f2c0 --- /dev/null +++ b/libgomp/config/linux/sem.c @@ -0,0 +1,65 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is a Linux specific implementation of a semaphore synchronization + mechanism for libgomp. This type is private to the library. This + implementation uses atomic instructions and the futex syscall. */ + +#include "libgomp.h" +#include "futex.h" + + +void +gomp_sem_wait_slow (gomp_sem_t *sem) +{ + while (1) + { + int val = __sync_val_compare_and_swap (sem, 0, -1); + if (val > 0) + { + if (__sync_bool_compare_and_swap (sem, val, val - 1)) + return; + } + futex_wait (sem, -1); + } +} + +void +gomp_sem_post_slow (gomp_sem_t *sem) +{ + int old, tmp = *sem, wake; + + do + { + old = tmp; + wake = old > 0 ? old + 1 : 1; + tmp = __sync_val_compare_and_swap (sem, old, wake); + } + while (old != tmp); + + futex_wake (sem, wake); +} diff --git a/libgomp/config/linux/sem.h b/libgomp/config/linux/sem.h new file mode 100644 index 00000000000..fff0bbdedcb --- /dev/null +++ b/libgomp/config/linux/sem.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is a Linux specific implementation of a semaphore synchronization + mechanism for libgomp. This type is private to the library. This + implementation uses atomic instructions and the futex syscall. */ + +#ifndef GOMP_SEM_H +#define GOMP_SEM_H 1 + +typedef int gomp_sem_t; + +static inline void gomp_sem_init (gomp_sem_t *sem, int value) +{ + *sem = value; +} + +extern void gomp_sem_wait_slow (gomp_sem_t *); +static inline void gomp_sem_wait (gomp_sem_t *sem) +{ + if (!__sync_bool_compare_and_swap (sem, 1, 0)) + gomp_sem_wait_slow (sem); +} + +extern void gomp_sem_post_slow (gomp_sem_t *); +static inline void gomp_sem_post (gomp_sem_t *sem) +{ + if (!__sync_bool_compare_and_swap (sem, 0, 1)) + gomp_sem_post_slow (sem); +} + +static inline void gomp_sem_destroy (gomp_sem_t *sem) +{ +} + +#endif /* GOMP_SEM_H */ diff --git a/libgomp/config/linux/sparc/futex.h b/libgomp/config/linux/sparc/futex.h new file mode 100644 index 00000000000..7b1cc837956 --- /dev/null +++ b/libgomp/config/linux/sparc/futex.h @@ -0,0 +1,80 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Jakub Jelinek <jakub@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* Provide target-specific access to the futex system call. */ + +#include <sys/syscall.h> +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +static inline void +sys_futex0 (int *addr, int op, int val) +{ + register long int g1 __asm__ ("g1"); + register long int o0 __asm__ ("o0"); + register long int o1 __asm__ ("o1"); + register long int o2 __asm__ ("o2"); + register long int o3 __asm__ ("o3"); + + g1 = SYS_futex; + o0 = (long) addr; + o1 = op; + o2 = val; + o3 = 0; + +#ifdef __arch64__ +# define SYSCALL_STRING "ta\t0x6d" +#else +# define SYSCALL_STRING "ta\t0x10" +#endif + + __asm volatile (SYSCALL_STRING + : "=r" (g1), "=r" (o0) + : "0" (g1), "1" (o0), "r" (o1), "r" (o2), "r" (o3) + : "g2", "g3", "g4", "g5", "g6", + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", +#ifdef __arch64__ + "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", + "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62", +#endif + "cc", "memory"); +} + +static inline void +futex_wait (int *addr, int val) +{ + sys_futex0 (addr, FUTEX_WAIT, val); +} + +static inline void +futex_wake (int *addr, int count) +{ + sys_futex0 (addr, FUTEX_WAKE, count); +} diff --git a/libgomp/config/linux/x86/futex.h b/libgomp/config/linux/x86/futex.h new file mode 100644 index 00000000000..4f9aac2ddbb --- /dev/null +++ b/libgomp/config/linux/x86/futex.h @@ -0,0 +1,110 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* Provide target-specific access to the futex system call. */ + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 + +#ifdef __LP64__ +# ifndef SYS_futex +# define SYS_futex 202 +# endif + +static inline void +futex_wait (int *addr, int val) +{ + register long r10 __asm__("%r10") = 0; + long res; + + __asm volatile ("syscall" + : "=a" (res) + : "0"(SYS_futex), "D" (addr), "S"(FUTEX_WAIT), + "d"(val), "r"(r10) + : "r11", "rcx", "memory"); +} + +static inline void +futex_wake (int *addr, int count) +{ + long res; + + __asm volatile ("syscall" + : "=a" (res) + : "0"(SYS_futex), "D" (addr), "S"(FUTEX_WAKE), "d"(count) + : "r11", "rcx", "memory"); +} +#else +# ifndef SYS_futex +# define SYS_futex 240 +# endif + +# ifdef __PIC__ + +static inline void +sys_futex0 (int *addr, int op, int val) +{ + long res; + + __asm volatile ("xchgl\t%%ebx, %2\n\t" + "int\t$0x80\n\t" + "xchgl\t%%ebx, %2" + : "=a" (res) + : "0"(SYS_futex), "r" (addr), "c"(op), + "d"(val), "S"(0) + : "memory"); +} + +# else + +static inline void +sys_futex0 (int *addr, int op, int val) +{ + long res; + + __asm volatile ("int $0x80" + : "=a" (res) + : "0"(SYS_futex), "b" (addr), "c"(op), + "d"(val), "S"(0) + : "memory"); +} + +# endif /* __PIC__ */ + +static inline void +futex_wait (int *addr, int val) +{ + sys_futex0 (addr, FUTEX_WAIT, val); +} + +static inline void +futex_wake (int *addr, int count) +{ + sys_futex0 (addr, FUTEX_WAKE, count); +} + +#endif /* __LP64__ */ diff --git a/libgomp/config/posix/bar.c b/libgomp/config/posix/bar.c new file mode 100644 index 00000000000..79721610ca7 --- /dev/null +++ b/libgomp/config/posix/bar.c @@ -0,0 +1,111 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is the default implementation of a barrier synchronization mechanism + for libgomp. This type is private to the library. Note that we rely on + being able to adjust the barrier count while threads are blocked, so the + POSIX pthread_barrier_t won't work. */ + +#include "libgomp.h" + + +void +gomp_barrier_init (gomp_barrier_t *bar, unsigned count) +{ + gomp_mutex_init (&bar->mutex1); +#ifndef HAVE_SYNC_BUILTINS + gomp_mutex_init (&bar->mutex2); +#endif + gomp_sem_init (&bar->sem1, 0); + gomp_sem_init (&bar->sem2, 0); + bar->total = count; + bar->arrived = 0; +} + +void +gomp_barrier_destroy (gomp_barrier_t *bar) +{ + /* Before destroying, make sure all threads have left the barrier. */ + gomp_mutex_lock (&bar->mutex1); + gomp_mutex_unlock (&bar->mutex1); + + gomp_mutex_destroy (&bar->mutex1); +#ifndef HAVE_SYNC_BUILTINS + gomp_mutex_destroy (&bar->mutex2); +#endif + gomp_sem_destroy (&bar->sem1); + gomp_sem_destroy (&bar->sem2); +} + +void +gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count) +{ + gomp_mutex_lock (&bar->mutex1); + bar->total = count; + gomp_mutex_unlock (&bar->mutex1); +} + +void +gomp_barrier_wait_end (gomp_barrier_t *bar, bool last) +{ + unsigned int n; + + if (last) + { + n = --bar->arrived; + if (n > 0) + { + do + gomp_sem_post (&bar->sem1); + while (--n != 0); + gomp_sem_wait (&bar->sem2); + } + gomp_mutex_unlock (&bar->mutex1); + } + else + { + gomp_mutex_unlock (&bar->mutex1); + gomp_sem_wait (&bar->sem1); + +#ifdef HAVE_SYNC_BUILTINS + n = __sync_add_and_fetch (&bar->arrived, -1); +#else + gomp_mutex_lock (&bar->mutex2); + n = --bar->arrived; + gomp_mutex_unlock (&bar->mutex2); +#endif + + if (n == 0) + gomp_sem_post (&bar->sem2); + } +} + +void +gomp_barrier_wait (gomp_barrier_t *barrier) +{ + gomp_barrier_wait_end (barrier, gomp_barrier_wait_start (barrier)); +} diff --git a/libgomp/config/posix/bar.h b/libgomp/config/posix/bar.h new file mode 100644 index 00000000000..5275efa96a7 --- /dev/null +++ b/libgomp/config/posix/bar.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is the default implementation of a barrier synchronization mechanism + for libgomp. This type is private to the library. Note that we rely on + being able to adjust the barrier count while threads are blocked, so the + POSIX pthread_barrier_t won't work. */ + +#ifndef GOMP_BARRIER_H +#define GOMP_BARRIER_H 1 + +#include <pthread.h> + +typedef struct +{ + gomp_mutex_t mutex1; +#ifndef HAVE_SYNC_BUILTINS + gomp_mutex_t mutex2; +#endif + gomp_sem_t sem1; + gomp_sem_t sem2; + unsigned total; + unsigned arrived; +} gomp_barrier_t; + +extern void gomp_barrier_init (gomp_barrier_t *, unsigned); +extern void gomp_barrier_reinit (gomp_barrier_t *, unsigned); +extern void gomp_barrier_destroy (gomp_barrier_t *); + +extern void gomp_barrier_wait (gomp_barrier_t *); +extern void gomp_barrier_wait_end (gomp_barrier_t *, bool); + +static inline bool gomp_barrier_wait_start (gomp_barrier_t *bar) +{ + gomp_mutex_lock (&bar->mutex1); + return ++bar->arrived == bar->total; +} + +#endif /* GOMP_BARRIER_H */ diff --git a/libgomp/config/posix/lock.c b/libgomp/config/posix/lock.c new file mode 100644 index 00000000000..062174d32d5 --- /dev/null +++ b/libgomp/config/posix/lock.c @@ -0,0 +1,121 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is the default PTHREADS implementation of the public OpenMP + locking primitives. + + Because OpenMP uses different entry points for normal and recursive + locks, and pthreads uses only one entry point, a system may be able + to do better and streamline the locking as well as reduce the size + of the types exported. */ + +/* We need Unix98 extensions to get recursive locks. */ +#define _XOPEN_SOURCE 500 + +#include "libgomp.h" + + +void +omp_init_lock (omp_lock_t *lock) +{ + pthread_mutex_init (lock, NULL); +} + +void +omp_destroy_lock (omp_lock_t *lock) +{ + pthread_mutex_destroy (lock); +} + +void +omp_set_lock (omp_lock_t *lock) +{ + pthread_mutex_lock (lock); +} + +void +omp_unset_lock (omp_lock_t *lock) +{ + pthread_mutex_unlock (lock); +} + +int +omp_test_lock (omp_lock_t *lock) +{ + return pthread_mutex_trylock (lock) == 0; +} + +void +omp_init_nest_lock (omp_nest_lock_t *lock) +{ + pthread_mutexattr_t attr; + + pthread_mutexattr_init (&attr); + pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init (&lock->lock, &attr); + lock->count = 0; + pthread_mutexattr_destroy (&attr); +} + +void +omp_destroy_nest_lock (omp_nest_lock_t *lock) +{ + pthread_mutex_destroy (&lock->lock); +} + +void +omp_set_nest_lock (omp_nest_lock_t *lock) +{ + pthread_mutex_lock (&lock->lock); + lock->count++; +} + +void +omp_unset_nest_lock (omp_nest_lock_t *lock) +{ + lock->count--; + pthread_mutex_unlock (&lock->lock); +} + +int +omp_test_nest_lock (omp_nest_lock_t *lock) +{ + if (pthread_mutex_trylock (&lock->lock) == 0) + return ++lock->count; + return 0; +} + +ialias (omp_init_lock) +ialias (omp_init_nest_lock) +ialias (omp_destroy_lock) +ialias (omp_destroy_nest_lock) +ialias (omp_set_lock) +ialias (omp_set_nest_lock) +ialias (omp_unset_lock) +ialias (omp_unset_nest_lock) +ialias (omp_test_lock) +ialias (omp_test_nest_lock) diff --git a/libgomp/config/posix/mutex.c b/libgomp/config/posix/mutex.c new file mode 100644 index 00000000000..39bb64da0f9 --- /dev/null +++ b/libgomp/config/posix/mutex.c @@ -0,0 +1 @@ +/* Everything is in the header. */ diff --git a/libgomp/config/posix/mutex.h b/libgomp/config/posix/mutex.h new file mode 100644 index 00000000000..c798e78aec8 --- /dev/null +++ b/libgomp/config/posix/mutex.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is the default PTHREADS implementation of a mutex synchronization + mechanism for libgomp. This type is private to the library. */ + +#ifndef GOMP_MUTEX_H +#define GOMP_MUTEX_H 1 + +#include <pthread.h> + +typedef pthread_mutex_t gomp_mutex_t; + +#define GOMP_MUTEX_INIT_0 0 + +static inline void gomp_mutex_init (gomp_mutex_t *mutex) +{ + pthread_mutex_init (mutex, NULL); +} + +static inline void gomp_mutex_lock (gomp_mutex_t *mutex) +{ + pthread_mutex_lock (mutex); +} + +static inline void gomp_mutex_unlock (gomp_mutex_t *mutex) +{ + pthread_mutex_unlock (mutex); +} + +static inline void gomp_mutex_destroy (gomp_mutex_t *mutex) +{ + pthread_mutex_destroy (mutex); +} + +#endif /* GOMP_MUTEX_H */ diff --git a/libgomp/config/posix/omp-lock.h b/libgomp/config/posix/omp-lock.h new file mode 100644 index 00000000000..ed70618d87d --- /dev/null +++ b/libgomp/config/posix/omp-lock.h @@ -0,0 +1,11 @@ +/* This header is used during the build process to find the size and + alignment of the public OpenMP locks, so that we can export data + structures without polluting the namespace. + + In this default POSIX implementation, we map the two locks to the + same PTHREADS primitive. */ + +#include <pthread.h> + +typedef pthread_mutex_t omp_lock_t; +typedef struct { pthread_mutex_t lock; int count; } omp_nest_lock_t; diff --git a/libgomp/config/posix/proc.c b/libgomp/config/posix/proc.c new file mode 100644 index 00000000000..3f5eb7ddc11 --- /dev/null +++ b/libgomp/config/posix/proc.c @@ -0,0 +1,98 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This file contains system specific routines related to counting + online processors and dynamic load balancing. It is expected that + a system may well want to write special versions of each of these. + + The following implementation uses a mix of POSIX and BSD routines. */ + +#include "libgomp.h" +#include <unistd.h> +#include <stdlib.h> + + +/* At startup, determine the default number of threads. It would seem + this should be related to the number of cpus online. */ + +void +gomp_init_num_threads (void) +{ +#ifdef _SC_NPROCESSORS_ONLN + gomp_nthreads_var = sysconf (_SC_NPROCESSORS_ONLN); +#endif +} + +/* When OMP_DYNAMIC is set, at thread launch determine the number of + threads we should spawn for this team. */ +/* ??? I have no idea what best practice for this is. Surely some + function of the number of processors that are *still* online and + the load average. Here I use the number of processors online + minus the 15 minute load average. */ + +unsigned +gomp_dynamic_max_threads (void) +{ + unsigned n_onln, loadavg; + +#ifdef _SC_NPROCESSORS_ONLN + n_onln = sysconf (_SC_NPROCESSORS_ONLN); + if (n_onln > gomp_nthreads_var) + n_onln = gomp_nthreads_var; +#else + n_onln = gomp_nthreads_var; +#endif + + loadavg = 0; +#ifdef HAVE_GETLOADAVG + { + double dloadavg[3]; + if (getloadavg (dloadavg, 3) == 3) + { + /* Add 0.1 to get a kind of biased rounding. */ + loadavg = dloadavg[2] + 0.1; + } + } +#endif + + if (loadavg >= n_onln) + return 1; + else + return n_onln - loadavg; +} + +int +omp_get_num_procs (void) +{ +#ifdef _SC_NPROCESSORS_ONLN + return sysconf (_SC_NPROCESSORS_ONLN); +#else + return gomp_nthreads_var; +#endif +} + +ialias (omp_get_num_procs) diff --git a/libgomp/config/posix/sem.c b/libgomp/config/posix/sem.c new file mode 100644 index 00000000000..e8374bda50d --- /dev/null +++ b/libgomp/config/posix/sem.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is the default POSIX 1003.1b implementation of a semaphore + synchronization mechanism for libgomp. This type is private to + the library. + + This is a bit heavy weight for what we need, in that we're not + interested in sem_wait as a cancelation point, but it's not too + bad for a default. */ + +#include "libgomp.h" + + +void +gomp_sem_wait (gomp_sem_t *sem) +{ + /* With POSIX, the wait can be canceled by signals. We don't want that. + It is expected that the return value here is -1 and errno is EINTR. */ + while (sem_wait (sem) != 0) + continue; +} diff --git a/libgomp/config/posix/sem.h b/libgomp/config/posix/sem.h new file mode 100644 index 00000000000..776a60d1c16 --- /dev/null +++ b/libgomp/config/posix/sem.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This is the default POSIX 1003.1b implementation of a semaphore + synchronization mechanism for libgomp. This type is private to + the library. + + This is a bit heavy weight for what we need, in that we're not + interested in sem_wait as a cancelation point, but it's not too + bad for a default. */ + +#ifndef GOMP_SEM_H +#define GOMP_SEM_H 1 + +#ifdef HAVE_ATTRIBUTE_VISIBILITY +# pragma GCC visibility push(default) +#endif + +#include <semaphore.h> + +#ifdef HAVE_ATTRIBUTE_VISIBILITY +# pragma GCC visibility pop +#endif + +typedef sem_t gomp_sem_t; + +static inline void gomp_sem_init (gomp_sem_t *sem, int value) +{ + sem_init (sem, 0, value); +} + +extern void gomp_sem_wait (gomp_sem_t *sem); + +static inline void gomp_sem_post (gomp_sem_t *sem) +{ + sem_post (sem); +} + +static inline void gomp_sem_destroy (gomp_sem_t *sem) +{ + sem_destroy (sem); +} + +#endif /* GOMP_SEM_H */ diff --git a/libgomp/config/posix/time.c b/libgomp/config/posix/time.c new file mode 100644 index 00000000000..ef267a31228 --- /dev/null +++ b/libgomp/config/posix/time.c @@ -0,0 +1,81 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + Contributed by Richard Henderson <rth@redhat.com>. + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with libgomp; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* As a special exception, if you link this library with other files, some + of which are compiled with GCC, to produce an executable, this library + does not by itself cause the resulting executable to be covered by the + GNU General Public License. This exception does not however invalidate + any other reasons why the executable file might be covered by the GNU + General Public License. */ + +/* This file contains system specific timer routines. It is expected that + a system may well want to write special versions of each of these. + + The following implementation uses the most simple POSIX routines. + If present, POSIX 4 clocks should be used instead. */ + +#include "libgomp.h" +#include <unistd.h> +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + + +double +omp_get_wtime (void) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; +# ifdef CLOCK_MONOTONIC + if (clock_gettime (CLOCK_MONOTONIC, &ts) < 0) +# endif + clock_gettime (CLOCK_REALTIME, &ts); + return ts.tv_sec + ts.tv_nsec / 1e9; +#else + struct timeval tv; + gettimeofday (&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1e6; +#endif +} + +double +omp_get_wtick (void) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; +# ifdef CLOCK_MONOTONIC + if (clock_getres (CLOCK_MONOTONIC, &ts) < 0) +# endif + clock_getres (CLOCK_REALTIME, &ts); + return ts.tv_sec + ts.tv_nsec / 1e9; +#else + return 1.0 / sysconf(_SC_CLK_TCK); +#endif +} + +ialias (omp_get_wtime) +ialias (omp_get_wtick) |