diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libgomp/config/posix | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libgomp/config/posix')
-rw-r--r-- | libgomp/config/posix/affinity.c | 38 | ||||
-rw-r--r-- | libgomp/config/posix/bar.c | 178 | ||||
-rw-r--r-- | libgomp/config/posix/bar.h | 115 | ||||
-rw-r--r-- | libgomp/config/posix/lock.c | 307 | ||||
-rw-r--r-- | libgomp/config/posix/mutex.c | 1 | ||||
-rw-r--r-- | libgomp/config/posix/mutex.h | 57 | ||||
-rw-r--r-- | libgomp/config/posix/omp-lock.h | 23 | ||||
-rw-r--r-- | libgomp/config/posix/proc.c | 101 | ||||
-rw-r--r-- | libgomp/config/posix/ptrlock.c | 1 | ||||
-rw-r--r-- | libgomp/config/posix/ptrlock.h | 66 | ||||
-rw-r--r-- | libgomp/config/posix/sem.c | 123 | ||||
-rw-r--r-- | libgomp/config/posix/sem.h | 87 | ||||
-rw-r--r-- | libgomp/config/posix/time.c | 78 |
13 files changed, 1175 insertions, 0 deletions
diff --git a/libgomp/config/posix/affinity.c b/libgomp/config/posix/affinity.c new file mode 100644 index 000000000..25865fcb5 --- /dev/null +++ b/libgomp/config/posix/affinity.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2006, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* This is a generic stub implementation of a CPU affinity setting. */ + +#include "libgomp.h" + +void +gomp_init_affinity (void) +{ +} + +void +gomp_init_thread_affinity (pthread_attr_t *attr) +{ + (void) attr; +} diff --git a/libgomp/config/posix/bar.c b/libgomp/config/posix/bar.c new file mode 100644 index 000000000..0101d1f25 --- /dev/null +++ b/libgomp/config/posix/bar.c @@ -0,0 +1,178 @@ +/* Copyright (C) 2005, 2008, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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; + bar->generation = 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, gomp_barrier_state_t state) +{ + unsigned int n; + + if (state & 1) + { + 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)); +} + +void +gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state) +{ + unsigned int n; + + if (state & 1) + { + n = --bar->arrived; + struct gomp_thread *thr = gomp_thread (); + struct gomp_team *team = thr->ts.team; + + if (team->task_count) + { + gomp_barrier_handle_tasks (state); + if (n > 0) + gomp_sem_wait (&bar->sem2); + gomp_mutex_unlock (&bar->mutex1); + return; + } + + bar->generation = state + 3; + 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); + do + { + gomp_sem_wait (&bar->sem1); + if (bar->generation & 1) + gomp_barrier_handle_tasks (state); + } + while (bar->generation != state + 4); + +#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_team_barrier_wait (gomp_barrier_t *barrier) +{ + gomp_team_barrier_wait_end (barrier, gomp_barrier_wait_start (barrier)); +} + +void +gomp_team_barrier_wake (gomp_barrier_t *bar, int count) +{ + if (count == 0) + count = bar->total - 1; + while (count-- > 0) + gomp_sem_post (&bar->sem1); +} diff --git a/libgomp/config/posix/bar.h b/libgomp/config/posix/bar.h new file mode 100644 index 000000000..ac8ae6f85 --- /dev/null +++ b/libgomp/config/posix/bar.h @@ -0,0 +1,115 @@ +/* Copyright (C) 2005, 2008, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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; + unsigned generation; +} gomp_barrier_t; +typedef unsigned int gomp_barrier_state_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 *, gomp_barrier_state_t); +extern void gomp_team_barrier_wait (gomp_barrier_t *); +extern void gomp_team_barrier_wait_end (gomp_barrier_t *, + gomp_barrier_state_t); +extern void gomp_team_barrier_wake (gomp_barrier_t *, int); + +static inline gomp_barrier_state_t +gomp_barrier_wait_start (gomp_barrier_t *bar) +{ + unsigned int ret; + gomp_mutex_lock (&bar->mutex1); + ret = bar->generation & ~3; + ret += ++bar->arrived == bar->total; + return ret; +} + +static inline bool +gomp_barrier_last_thread (gomp_barrier_state_t state) +{ + return state & 1; +} + +static inline void +gomp_barrier_wait_last (gomp_barrier_t *bar) +{ + gomp_barrier_wait (bar); +} + +/* All the inlines below must be called with team->task_lock + held. */ + +static inline void +gomp_team_barrier_set_task_pending (gomp_barrier_t *bar) +{ + bar->generation |= 1; +} + +static inline void +gomp_team_barrier_clear_task_pending (gomp_barrier_t *bar) +{ + bar->generation &= ~1; +} + +static inline void +gomp_team_barrier_set_waiting_for_tasks (gomp_barrier_t *bar) +{ + bar->generation |= 2; +} + +static inline bool +gomp_team_barrier_waiting_for_tasks (gomp_barrier_t *bar) +{ + return (bar->generation & 2) != 0; +} + +static inline void +gomp_team_barrier_done (gomp_barrier_t *bar, gomp_barrier_state_t state) +{ + bar->generation = (state & ~3) + 4; +} + +#endif /* GOMP_BARRIER_H */ diff --git a/libgomp/config/posix/lock.c b/libgomp/config/posix/lock.c new file mode 100644 index 000000000..8cd715e64 --- /dev/null +++ b/libgomp/config/posix/lock.c @@ -0,0 +1,307 @@ +/* Copyright (C) 2005, 2008, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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. On Tru64 UNIX V4.0F, + the declarations are available without _XOPEN_SOURCE, which actually + breaks compilation. */ +#ifndef __osf__ +#define _XOPEN_SOURCE 500 +#endif + +#include "libgomp.h" + +#ifdef HAVE_BROKEN_POSIX_SEMAPHORES +void +gomp_init_lock_30 (omp_lock_t *lock) +{ + pthread_mutex_init (lock, NULL); +} + +void +gomp_destroy_lock_30 (omp_lock_t *lock) +{ + pthread_mutex_destroy (lock); +} + +void +gomp_set_lock_30 (omp_lock_t *lock) +{ + pthread_mutex_lock (lock); +} + +void +gomp_unset_lock_30 (omp_lock_t *lock) +{ + pthread_mutex_unlock (lock); +} + +int +gomp_test_lock_30 (omp_lock_t *lock) +{ + return pthread_mutex_trylock (lock) == 0; +} + +void +gomp_init_nest_lock_30 (omp_nest_lock_t *lock) +{ + pthread_mutex_init (&lock->lock, NULL); + lock->count = 0; + lock->owner = NULL; +} + +void +gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) +{ + pthread_mutex_destroy (&lock->lock); +} + +void +gomp_set_nest_lock_30 (omp_nest_lock_t *lock) +{ + void *me = gomp_icv (true); + + if (lock->owner != me) + { + pthread_mutex_lock (&lock->lock); + lock->owner = me; + } + lock->count++; +} + +void +gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) +{ + if (--lock->count == 0) + { + lock->owner = NULL; + pthread_mutex_unlock (&lock->lock); + } +} + +int +gomp_test_nest_lock_30 (omp_nest_lock_t *lock) +{ + void *me = gomp_icv (true); + + if (lock->owner != me) + { + if (pthread_mutex_trylock (&lock->lock) != 0) + return 0; + lock->owner = me; + } + + return ++lock->count; +} + +#else + +void +gomp_init_lock_30 (omp_lock_t *lock) +{ + sem_init (lock, 0, 1); +} + +void +gomp_destroy_lock_30 (omp_lock_t *lock) +{ + sem_destroy (lock); +} + +void +gomp_set_lock_30 (omp_lock_t *lock) +{ + while (sem_wait (lock) != 0) + ; +} + +void +gomp_unset_lock_30 (omp_lock_t *lock) +{ + sem_post (lock); +} + +int +gomp_test_lock_30 (omp_lock_t *lock) +{ + return sem_trywait (lock) == 0; +} + +void +gomp_init_nest_lock_30 (omp_nest_lock_t *lock) +{ + sem_init (&lock->lock, 0, 1); + lock->count = 0; + lock->owner = NULL; +} + +void +gomp_destroy_nest_lock_30 (omp_nest_lock_t *lock) +{ + sem_destroy (&lock->lock); +} + +void +gomp_set_nest_lock_30 (omp_nest_lock_t *lock) +{ + void *me = gomp_icv (true); + + if (lock->owner != me) + { + while (sem_wait (&lock->lock) != 0) + ; + lock->owner = me; + } + lock->count++; +} + +void +gomp_unset_nest_lock_30 (omp_nest_lock_t *lock) +{ + if (--lock->count == 0) + { + lock->owner = NULL; + sem_post (&lock->lock); + } +} + +int +gomp_test_nest_lock_30 (omp_nest_lock_t *lock) +{ + void *me = gomp_icv (true); + + if (lock->owner != me) + { + if (sem_trywait (&lock->lock) != 0) + return 0; + lock->owner = me; + } + + return ++lock->count; +} +#endif + +#ifdef LIBGOMP_GNU_SYMBOL_VERSIONING +void +gomp_init_lock_25 (omp_lock_25_t *lock) +{ + pthread_mutex_init (lock, NULL); +} + +void +gomp_destroy_lock_25 (omp_lock_25_t *lock) +{ + pthread_mutex_destroy (lock); +} + +void +gomp_set_lock_25 (omp_lock_25_t *lock) +{ + pthread_mutex_lock (lock); +} + +void +gomp_unset_lock_25 (omp_lock_25_t *lock) +{ + pthread_mutex_unlock (lock); +} + +int +gomp_test_lock_25 (omp_lock_25_t *lock) +{ + return pthread_mutex_trylock (lock) == 0; +} + +void +gomp_init_nest_lock_25 (omp_nest_lock_25_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 +gomp_destroy_nest_lock_25 (omp_nest_lock_25_t *lock) +{ + pthread_mutex_destroy (&lock->lock); +} + +void +gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock) +{ + pthread_mutex_lock (&lock->lock); + lock->count++; +} + +void +gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock) +{ + lock->count--; + pthread_mutex_unlock (&lock->lock); +} + +int +gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock) +{ + if (pthread_mutex_trylock (&lock->lock) == 0) + return ++lock->count; + return 0; +} + +omp_lock_symver (omp_init_lock) +omp_lock_symver (omp_destroy_lock) +omp_lock_symver (omp_set_lock) +omp_lock_symver (omp_unset_lock) +omp_lock_symver (omp_test_lock) +omp_lock_symver (omp_init_nest_lock) +omp_lock_symver (omp_destroy_nest_lock) +omp_lock_symver (omp_set_nest_lock) +omp_lock_symver (omp_unset_nest_lock) +omp_lock_symver (omp_test_nest_lock) + +#else + +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) + +#endif diff --git a/libgomp/config/posix/mutex.c b/libgomp/config/posix/mutex.c new file mode 100644 index 000000000..39bb64da0 --- /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 000000000..b6617a4bd --- /dev/null +++ b/libgomp/config/posix/mutex.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2005, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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 000000000..e51dc271f --- /dev/null +++ b/libgomp/config/posix/omp-lock.h @@ -0,0 +1,23 @@ +/* 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 used to map the two locks to the + same PTHREADS primitive, but for OpenMP 3.0 sem_t needs to be used + instead, as pthread_mutex_unlock should not be called by different + thread than the one that called pthread_mutex_lock. */ + +#include <pthread.h> +#include <semaphore.h> + +typedef pthread_mutex_t omp_lock_25_t; +typedef struct { pthread_mutex_t lock; int count; } omp_nest_lock_25_t; +#ifdef HAVE_BROKEN_POSIX_SEMAPHORES +/* If we don't have working semaphores, we'll make all explicit tasks + tied to the creating thread. */ +typedef pthread_mutex_t omp_lock_t; +typedef struct { pthread_mutex_t lock; int count; void *owner; } omp_nest_lock_t; +#else +typedef sem_t omp_lock_t; +typedef struct { sem_t lock; int count; void *owner; } omp_nest_lock_t; +#endif diff --git a/libgomp/config/posix/proc.c b/libgomp/config/posix/proc.c new file mode 100644 index 000000000..aacf41e52 --- /dev/null +++ b/libgomp/config/posix/proc.c @@ -0,0 +1,101 @@ +/* Copyright (C) 2005, 2006, 2008, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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> +#ifdef HAVE_GETLOADAVG +# ifdef HAVE_SYS_LOADAVG_H +# include <sys/loadavg.h> +# endif +#endif + + +/* 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_global_icv.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; + unsigned nthreads_var = gomp_icv (false)->nthreads_var; + +#ifdef _SC_NPROCESSORS_ONLN + n_onln = sysconf (_SC_NPROCESSORS_ONLN); + if (n_onln > nthreads_var) + n_onln = nthreads_var; +#else + n_onln = 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_icv (false)->nthreads_var; +#endif +} + +ialias (omp_get_num_procs) diff --git a/libgomp/config/posix/ptrlock.c b/libgomp/config/posix/ptrlock.c new file mode 100644 index 000000000..39bb64da0 --- /dev/null +++ b/libgomp/config/posix/ptrlock.c @@ -0,0 +1 @@ +/* Everything is in the header. */ diff --git a/libgomp/config/posix/ptrlock.h b/libgomp/config/posix/ptrlock.h new file mode 100644 index 000000000..246e1caac --- /dev/null +++ b/libgomp/config/posix/ptrlock.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2008, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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_PTRLOCK_H +#define GOMP_PTRLOCK_H 1 + +typedef struct { void *ptr; gomp_mutex_t lock; } gomp_ptrlock_t; + +static inline void gomp_ptrlock_init (gomp_ptrlock_t *ptrlock, void *ptr) +{ + ptrlock->ptr = ptr; + gomp_mutex_init (&ptrlock->lock); +} + +static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock) +{ + if (ptrlock->ptr != NULL) + return ptrlock->ptr; + + gomp_mutex_lock (&ptrlock->lock); + if (ptrlock->ptr != NULL) + { + gomp_mutex_unlock (&ptrlock->lock); + return ptrlock->ptr; + } + + return NULL; +} + +static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr) +{ + ptrlock->ptr = ptr; + gomp_mutex_unlock (&ptrlock->lock); +} + +static inline void gomp_ptrlock_destroy (gomp_ptrlock_t *ptrlock) +{ + gomp_mutex_destroy (&ptrlock->lock); +} + +#endif /* GOMP_PTRLOCK_H */ diff --git a/libgomp/config/posix/sem.c b/libgomp/config/posix/sem.c new file mode 100644 index 000000000..e05767513 --- /dev/null +++ b/libgomp/config/posix/sem.c @@ -0,0 +1,123 @@ +/* Copyright (C) 2005, 2006, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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" + +#ifdef HAVE_BROKEN_POSIX_SEMAPHORES +#include <stdlib.h> + +void gomp_sem_init (gomp_sem_t *sem, int value) +{ + int ret; + + ret = pthread_mutex_init (&sem->mutex, NULL); + if (ret) + return; + + ret = pthread_cond_init (&sem->cond, NULL); + if (ret) + return; + + sem->value = value; +} + +void gomp_sem_wait (gomp_sem_t *sem) +{ + int ret; + + ret = pthread_mutex_lock (&sem->mutex); + if (ret) + return; + + if (sem->value > 0) + { + sem->value--; + ret = pthread_mutex_unlock (&sem->mutex); + return; + } + + while (sem->value <= 0) + { + ret = pthread_cond_wait (&sem->cond, &sem->mutex); + if (ret) + { + pthread_mutex_unlock (&sem->mutex); + return; + } + } + + sem->value--; + ret = pthread_mutex_unlock (&sem->mutex); + return; +} + +void gomp_sem_post (gomp_sem_t *sem) +{ + int ret; + + ret = pthread_mutex_lock (&sem->mutex); + if (ret) + return; + + sem->value++; + + ret = pthread_mutex_unlock (&sem->mutex); + if (ret) + return; + + ret = pthread_cond_signal (&sem->cond); + + return; +} + +void gomp_sem_destroy (gomp_sem_t *sem) +{ + int ret; + + ret = pthread_mutex_destroy (&sem->mutex); + if (ret) + return; + + ret = pthread_cond_destroy (&sem->cond); + + return; +} +#else /* HAVE_BROKEN_POSIX_SEMAPHORES */ +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; +} +#endif diff --git a/libgomp/config/posix/sem.h b/libgomp/config/posix/sem.h new file mode 100644 index 000000000..b68230de0 --- /dev/null +++ b/libgomp/config/posix/sem.h @@ -0,0 +1,87 @@ +/* Copyright (C) 2005, 2006, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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 + +#ifdef HAVE_BROKEN_POSIX_SEMAPHORES +#include <pthread.h> + +struct gomp_sem +{ + pthread_mutex_t mutex; + pthread_cond_t cond; + int value; +}; + +typedef struct gomp_sem gomp_sem_t; + +extern void gomp_sem_init (gomp_sem_t *sem, int value); + +extern void gomp_sem_wait (gomp_sem_t *sem); + +extern void gomp_sem_post (gomp_sem_t *sem); + +extern void gomp_sem_destroy (gomp_sem_t *sem); + +#else /* HAVE_BROKEN_POSIX_SEMAPHORES */ + +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 /* doesn't HAVE_BROKEN_POSIX_SEMAPHORES */ +#endif /* GOMP_SEM_H */ diff --git a/libgomp/config/posix/time.c b/libgomp/config/posix/time.c new file mode 100644 index 000000000..eb196f648 --- /dev/null +++ b/libgomp/config/posix/time.c @@ -0,0 +1,78 @@ +/* Copyright (C) 2005, 2009 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 General Public License as published by + the Free Software Foundation; either version 3, 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +/* 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) |