summaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-04-11 09:13:11 +0000
committer <>2014-04-23 12:05:38 +0000
commit6af3fdec2262dd94954acc5e426ef71cbd4521d3 (patch)
tree9be02de9a80f7935892a2d03741adee44723e65d /libgomp
parent19be2b4342ac32e9edc78ce6fed8f61b63ae98d1 (diff)
downloadgcc-tarball-6af3fdec2262dd94954acc5e426ef71cbd4521d3.tar.gz
Imported from /home/lorry/working-area/delta_gcc-tarball/gcc-4.7.3.tar.bz2.gcc-4.7.3
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/ChangeLog345
-rw-r--r--libgomp/Makefile.am28
-rw-r--r--libgomp/Makefile.in25
-rw-r--r--libgomp/acinclude.m47
-rw-r--r--libgomp/config/linux/affinity.c42
-rw-r--r--libgomp/config/linux/alpha/futex.h6
-rw-r--r--libgomp/config/linux/bar.c30
-rw-r--r--libgomp/config/linux/bar.h15
-rw-r--r--libgomp/config/linux/futex.h6
-rw-r--r--libgomp/config/linux/ia64/futex.h6
-rw-r--r--libgomp/config/linux/ia64/mutex.h65
-rw-r--r--libgomp/config/linux/lock.c26
-rw-r--r--libgomp/config/linux/mips/futex.h6
-rw-r--r--libgomp/config/linux/mutex.c33
-rw-r--r--libgomp/config/linux/mutex.h42
-rw-r--r--libgomp/config/linux/omp-lock.h4
-rw-r--r--libgomp/config/linux/powerpc/futex.h6
-rw-r--r--libgomp/config/linux/powerpc/mutex.h2
-rw-r--r--libgomp/config/linux/proc.c10
-rw-r--r--libgomp/config/linux/proc.h (renamed from libgomp/config/linux/arm/mutex.h)16
-rw-r--r--libgomp/config/linux/ptrlock.c10
-rw-r--r--libgomp/config/linux/ptrlock.h24
-rw-r--r--libgomp/config/linux/s390/futex.h6
-rw-r--r--libgomp/config/linux/sem.c60
-rw-r--r--libgomp/config/linux/sem.h58
-rw-r--r--libgomp/config/linux/sparc/futex.h16
-rw-r--r--libgomp/config/linux/tile/futex.h73
-rw-r--r--libgomp/config/linux/wait.h12
-rw-r--r--libgomp/config/linux/x86/futex.h10
-rw-r--r--libgomp/config/osf/sem.h (renamed from libgomp/config/linux/mips/mutex.h)34
-rw-r--r--libgomp/config/posix95/lock.c316
-rw-r--r--libgomp/config/posix95/omp-lock.h21
-rwxr-xr-xlibgomp/configure36
-rw-r--r--libgomp/configure.tgt11
-rw-r--r--libgomp/critical.c4
-rw-r--r--libgomp/env.c110
-rw-r--r--libgomp/fortran.c7
-rw-r--r--libgomp/iter.c15
-rw-r--r--libgomp/iter_ull.c15
-rw-r--r--libgomp/libgomp.h16
-rw-r--r--libgomp/libgomp.info362
-rw-r--r--libgomp/libgomp.map11
-rw-r--r--libgomp/libgomp.texi161
-rw-r--r--libgomp/libgomp_g.h3
-rw-r--r--libgomp/omp.h.in4
-rw-r--r--libgomp/omp_lib.f90.in47
-rw-r--r--libgomp/omp_lib.h.in12
-rw-r--r--libgomp/ordered.c7
-rw-r--r--libgomp/task.c56
-rw-r--r--libgomp/team.c20
-rw-r--r--libgomp/testsuite/lib/libgomp.exp2
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-2.C156
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-3.C74
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-4.C166
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-5.C79
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-6.C58
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-7.C63
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-8.C137
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-9.C148
-rw-r--r--libgomp/testsuite/libgomp.c++/pr56217.C36
-rw-r--r--libgomp/testsuite/libgomp.c++/reduction-4.C54
-rw-r--r--libgomp/testsuite/libgomp.c++/task-8.C44
-rw-r--r--libgomp/testsuite/libgomp.c/atomic-1.c2
-rw-r--r--libgomp/testsuite/libgomp.c/atomic-11.c156
-rw-r--r--libgomp/testsuite/libgomp.c/atomic-12.c98
-rw-r--r--libgomp/testsuite/libgomp.c/atomic-13.c59
-rw-r--r--libgomp/testsuite/libgomp.c/atomic-14.c137
-rw-r--r--libgomp/testsuite/libgomp.c/atomic-6.c2
-rw-r--r--libgomp/testsuite/libgomp.c/pr26943-2.c5
-rw-r--r--libgomp/testsuite/libgomp.c/pr26943-3.c5
-rw-r--r--libgomp/testsuite/libgomp.c/pr26943-4.c5
-rw-r--r--libgomp/testsuite/libgomp.c/pr46886.c28
-rw-r--r--libgomp/testsuite/libgomp.c/pr52547.c36
-rw-r--r--libgomp/testsuite/libgomp.c/reduction-6.c29
-rw-r--r--libgomp/testsuite/libgomp.c/task-5.c45
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable7.f9016
-rw-r--r--libgomp/testsuite/libgomp.fortran/allocatable8.f9014
-rw-r--r--libgomp/testsuite/libgomp.fortran/crayptr3.f9036
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic3.f9058
-rw-r--r--libgomp/testsuite/libgomp.fortran/omp_atomic4.f9037
-rw-r--r--libgomp/testsuite/libgomp.fortran/pointer1.f9077
-rw-r--r--libgomp/testsuite/libgomp.fortran/pointer2.f9028
-rw-r--r--libgomp/testsuite/libgomp.fortran/task4.f9045
-rw-r--r--libgomp/testsuite/libgomp.fortran/threadprivate4.f9078
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla4.f906
-rw-r--r--libgomp/testsuite/libgomp.fortran/vla5.f906
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-1.c3
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-2.c2
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-3.c4
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-6.c5
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-7.c3
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-8.c3
-rw-r--r--libgomp/testsuite/libgomp.graphite/force-parallel-9.c4
93 files changed, 3347 insertions, 959 deletions
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 95b247f534..bc33ea9a37 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,6 +1,180 @@
-2011-10-26 Release Manager
+2013-04-11 Release Manager
- * GCC 4.6.2 released.
+ * GCC 4.7.3 released.
+
+2013-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2013-02-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/56217
+ * testsuite/libgomp.c++/pr56217.C: New test.
+
+2013-01-22 Alan Modra <amodra@gmail.com>
+
+ PR libgomp/51376
+ PR libgomp/56073
+ * task.c (GOMP_task): Revert 2011-12-09 change.
+ (GOMP_taskwait): Likewise. Instead use atomic load with acquire
+ barrier to read task->children..
+ (gomp_barrier_handle_tasks): ..and matching atomic store with
+ release barrier here when setting parent->children to NULL.
+
+2012-11-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/55411
+ * team.c (gomp_free_thread): Decrease gomp_managed_threads
+ if pool had any threads_used.
+
+2012-09-20 Release Manager
+
+ * GCC 4.7.2 released.
+
+2012-06-14 Jakub Jelinek <jakub@redhat.com>
+
+ Backported from mainline
+ 2012-06-07 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/53580
+ * testsuite/libgomp.c/pr26943-2.c: Remove #pragma omp barrier,
+ use GOMP_barrier () call instead.
+ * testsuite/libgomp.c/pr26943-3.c: Likewise.
+ * testsuite/libgomp.c/pr26943-4.c: Likewise.
+ * testsuite/libgomp.fortran/vla4.f90: Remove !$omp barrier,
+ call GOMP_barrier instead.
+ * testsuite/libgomp.fortran/vla5.f90: Likewise.
+
+ 2012-06-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/52993
+ * config/linux/lock.c (gomp_init_nest_lock_25): Fix up last
+ argument to memset call.
+
+2012-06-14 Release Manager
+
+ * GCC 4.7.1 released.
+
+2012-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/52547
+ * testsuite/libgomp.c/pr52547.c: New test.
+
+2012-03-22 Release Manager
+
+ * GCC 4.7.0 released.
+
+2012-02-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/linux/sparc/futex.h (cpu_relax): Read from CC register.
+
+2012-02-27 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR libstdc++/52188
+ * acinclude.m4 (LIBGOMP_ENABLE_SYMVERS): Remove symvers_renaming.
+ Remove ENABLE_SYMVERS_SOL2.
+ * configure: Regenerate.
+ * Makefile.am [LIBGOMP_BUILD_VERSIONED_SHLIB] (comma): New variable.
+ (PREPROCESS): New variable.
+ (libgomp.ver): New target.
+ [LIBGOMP_BUILD_VERSIONED_SHLIB &&
+ LIBGOMP_BUILD_VERSIONED_SHLIB_GNU]: Remove
+ LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2 handling.
+ Use libgomp.ver.
+ [LIBGOMP_BUILD_VERSIONED_SHLIB_SUN]: Use libgomp.ver, libgomp.ver-sun.
+ * Makefile.in: Regenerate.
+
+2012-02-14 Walter Lee <walt@tilera.com>
+
+ * configure.tgt: Handle tilegx and tilepro.
+ * config/linux/tile/futex.h: New file.
+
+2012-02-08 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/46886
+ * testsuite/libgomp.c/pr46886.c: New testcase.
+
+2012-01-25 Matthias Klose <doko@ubuntu.com>
+
+ * config/linux/arm: Remove empty directory.
+ * configure.tgt (config_path): Remove linux-arm for arm*-*-linux*.
+
+2011-12-09 Alan Modra <amodra@gmail.com>
+
+ PR libgomp/51376
+ * task.c (GOMP_taskwait): Don't access task->children outside of
+ task_lock mutex region.
+ (GOMP_task): Likewise.
+
+2011-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/51132
+ * testsuite/libgomp.graphite/force-parallel-1.c: Move large arrays
+ to file scope.
+ * testsuite/libgomp.graphite/force-parallel-3.c: Likewise.
+ * testsuite/libgomp.graphite/force-parallel-6.c: Likewise.
+ * testsuite/libgomp.graphite/force-parallel-7.c: Likewise.
+ * testsuite/libgomp.graphite/force-parallel-8.c: Likewise.
+ * testsuite/libgomp.graphite/force-parallel-9.c: Likewise.
+
+2011-12-02 Alan Modra <amodra@gmail.com>
+
+ * config/linux/affinity.c: Use atomic rather than sync builtin.
+ * config/linux/lock.c: Likewise.
+ * config/linux/ptrlock.h: Likewise.
+ * config/linux/ptrlock.c: Likewise.
+ * config/linux/ptrlock.h (gomp_ptrlock_set): Always write here..
+ * config/linux/ptrlock.c (gomp_ptrlock_set_slow): ..not here.
+ * config/linux/futex.h (atomic_write_barrier): Delete unused function.
+ * config/linux/alpha/futex.h (atomic_write_barrier): Likewise.
+ * config/linux/ia64/futex.h (atomic_write_barrier): Likewise.
+ * config/linux/mips/futex.h (atomic_write_barrier): Likewise.
+ * config/linux/powerpc/futex.h (atomic_write_barrier): Likewise.
+ * config/linux/s390/futex.h (atomic_write_barrier): Likewise.
+ * config/linux/sparc/futex.h (atomic_write_barrier): Likewise.
+ * config/linux/x86/futex.h (atomic_write_barrier): Likewise.
+
+2011-11-30 Alan Modra <amodra@gmail.com>
+
+ PR libgomp/51298
+ * config/linux/bar.h: Use atomic rather than sync builtins.
+ * config/linux/bar.c: Likewise. Add missing acquire
+ synchronisation on generation field.
+ * task.c (gomp_barrier_handle_tasks): Regain lock so as to not
+ double unlock.
+
+2011-11-30 Alan Modra <amodra@gmail.com>
+
+ * ordered.c (gomp_ordered_sync): Add MEMMODEL_ACQ_REL fence.
+ * critical.c (GOMP_critical_start): Add MEMMODEL_RELEASE fence.
+ * config/linux/mutex.h: Use atomic rather than sync builtins.
+ * config/linux/mutex.c: Likewise. Comment. Use -1 for waiting state.
+ * config/linux/omp-lock.h: Comment fix.
+ * config/linux/arm/mutex.h: Delete.
+ * config/linux/powerpc/mutex.h: Delete.
+ * config/linux/ia64/mutex.h: Delete.
+ * config/linux/mips/mutex.h: Delete.
+
+2011-11-30 Alan Modra <amodra@gmail.com>
+
+ PR libgomp/51249
+ * config/linux/sem.h: Rewrite.
+ * config/linux/sem.c: Rewrite.
+
+2011-11-28 Richard Henderson <rth@redhat.com>
+
+ * libgomp.h (enum memmodel): New.
+
+2011-11-21 Andreas Tobler <andreast@fgznet.ch>
+
+ * configure: Regenerate.
+
+2011-10-10 Matthias Klose <doko@ubuntu.com>
+
+ * config/posix95: Remove empty directory.
+
+2011-08-26 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.fortran/threadprivate4.f90: New test.
2011-08-19 Jakub Jelinek <jakub@redhat.com>
@@ -8,6 +182,101 @@
* testsuite/libgomp.fortran/pr49792-1.f90: New test.
* testsuite/libgomp.fortran/pr49792-2.f90: New test.
+2011-08-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/posix95/lock.c, posix95/omp-lock.h: Remove.
+
+2011-08-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR libgomp/49965
+ * testsuite/libgomp.c++/task-8.C: Replaced err by errval.
+
+2011-08-03 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/linux/proc.h: New.
+ * config/linux/proc.c: Include "proc.h". Do not include <sched.h>.
+ (gomp_cpuset_popcount): Rename from cpuset_popcount. No more static.
+ (gomp_init_num_threads): Update call to cpuset_popcount.
+ (get_num_procs): Ditto.
+ * config/linux/affinity.c (gomp_init_affinity): Call
+ gomp_cpuset_popcount.
+
+2011-08-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/42041
+ PR fortran/46752
+ * omp.h.in (omp_in_final): New prototype.
+ * omp_lib.f90.in (omp_in_final): New interface.
+ (omp_integer_kind, omp_logical_kind): Remove
+ and replace all its uses in the module with 4.
+ (openmp_version): Change to 201107.
+ * omp_lib.h.in (omp_sched_static, omp_sched_dynamic,
+ omp_sched_guided, omp_sched_auto): Use omp_sched_kind
+ kind for the parameters.
+ (omp_in_final): New external.
+ (openmp_version): Change to 201107.
+ * task.c (omp_in_final): New function.
+ (gomp_init_task): Initialize final_task.
+ (GOMP_task): Remove unused attribute from flags. Handle final
+ tasks.
+ (GOMP_taskyield): New function.
+ (omp_in_final): Return true if if (false) or final (true) task
+ or descendant of final (true).
+ * fortran.c (omp_in_final_): New function.
+ * libgomp.map (OMP_3.1): Export omp_in_final and omp_in_final_.
+ (GOMP_3.0): Export GOMP_taskyield.
+ * env.c (gomp_nthreads_var_list, gomp_nthreads_var_list_len): New
+ variables.
+ (parse_unsigned_long_list): New function.
+ (initialize_env): Use it for OMP_NUM_THREADS. Call parse_boolean
+ with "OMP_PROC_BIND". If OMP_PROC_BIND=true, call gomp_init_affinity
+ even if parse_affinity returned false.
+ * config/linux/affinity.c (gomp_init_affinity): Handle
+ gomp_cpu_affinity_len == 0.
+ * libgomp_g.h (GOMP_taskyield): New prototype.
+ * libgomp.h (struct gomp_task): Add final_task field.
+ (gomp_nthreads_var_list, gomp_nthreads_var_list_len): New externs.
+ * team.c (gomp_team_start): Override new task's nthreads_var icv
+ if list form OMP_NUM_THREADS has been used and it has value for
+ the new nesting level.
+
+ * testsuite/libgomp.c/atomic-11.c: New test.
+ * testsuite/libgomp.c/atomic-12.c: New test.
+ * testsuite/libgomp.c/atomic-13.c: New test.
+ * testsuite/libgomp.c/atomic-14.c: New test.
+ * testsuite/libgomp.c/reduction-6.c: New test.
+ * testsuite/libgomp.c/task-5.c: New test.
+ * testsuite/libgomp.c++/atomic-2.C: New test.
+ * testsuite/libgomp.c++/atomic-3.C: New test.
+ * testsuite/libgomp.c++/atomic-4.C: New test.
+ * testsuite/libgomp.c++/atomic-5.C: New test.
+ * testsuite/libgomp.c++/atomic-6.C: New test.
+ * testsuite/libgomp.c++/atomic-7.C: New test.
+ * testsuite/libgomp.c++/atomic-8.C: New test.
+ * testsuite/libgomp.c++/atomic-9.C: New test.
+ * testsuite/libgomp.c++/task-8.C: New test.
+ * testsuite/libgomp.c++/reduction-4.C: New test.
+ * testsuite/libgomp.fortran/allocatable7.f90: New test.
+ * testsuite/libgomp.fortran/allocatable8.f90: New test.
+ * testsuite/libgomp.fortran/crayptr3.f90: New test.
+ * testsuite/libgomp.fortran/omp_atomic3.f90: New test.
+ * testsuite/libgomp.fortran/omp_atomic4.f90: New test.
+ * testsuite/libgomp.fortran/pointer1.f90: New test.
+ * testsuite/libgomp.fortran/pointer2.f90: New test.
+ * testsuite/libgomp.fortran/task4.f90: New test.
+
+2011-08-02 Tobias Burnus <burnus@net-b.de>
+
+ * libgomp.texi: Update OpenMP spec references to 3.1.
+ (omp_in_final,OMP_PROC_BIND): New sections.
+ (OMP_NUM_THREADS): Document that the value can be now a list.
+ (GOMP_STACKSIZE,GOMP_CPU_AFFINITY): Update @ref.
+
+2011-08-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/linux/x86/futex.h: Check __x86_64__ instead of
+ __LP64__.
+
2011-07-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/49897
@@ -17,15 +286,66 @@
* testsuite/libgomp.c/pr49898-1.c: New test.
* testsuite/libgomp.c/pr49898-2.c: New test.
+2011-07-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * testsuite/lib/libgomp.exp (libgomp_init): Add -march=i486
+ for ia32 instead of ilp32.
+
+ * testsuite/libgomp.c/atomic-1.c: Require ia32 instead of ilp32.
+ * testsuite/libgomp.c/atomic-6.c: Likewise.
+
+2011-07-23 Sebastian Pop <sebastian.pop@amd.com>
+
+ * testsuite/libgomp.graphite/force-parallel-1.c: Un-xfail.
+ * testsuite/libgomp.graphite/force-parallel-2.c: Adjust pattern.
+
+2011-07-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR libgomp/45351
+ * config/osf/sem.h: New file.
+ * configure.tgt (alpha*-dec-osf*): Prepend osf to config_path.
+
2011-07-18 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR target/49541
* testsuite/lib/libgomp.exp (libgomp_init): Don't add -lgomp to
ldflags.
-2011-06-27 Release Manager
-
- * GCC 4.6.1 released.
+2011-07-15 Jakub Jelinek <jakub@redhat.com>
+
+ * config/linux/wait.h (do_spin): New inline, largely copied
+ from do_wait, just don't do futex_wait here, instead return true if
+ it should be done.
+ (do_wait): Implement using do_spin.
+ * config/linux/mutex.h (gomp_mutex_lock_slow): Add an int argument
+ to prototype.
+ (gomp_mutex_lock): Use __sync_val_compare_and_swap instead of
+ __sync_bool_compare_and_swap, pass the oldval to
+ gomp_mutex_lock_slow.
+ * config/linux/mutex.c (gomp_mutex_lock_slow): Add oldval argument.
+ If all mutex contenders are just spinning and not sleeping, don't
+ change state to 2 unnecessarily. Optimize the loop when state has
+ already become 2 to use just one atomic operation per loop instead
+ of two.
+ * config/linux/ia64/mutex.h (gomp_mutex_lock_slow): Add an int argument
+ to prototype.
+ (gomp_mutex_lock): Use __sync_val_compare_and_swap instead of
+ __sync_bool_compare_and_swap, pass the oldval to
+ gomp_mutex_lock_slow.
+
+2011-06-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/49490
+ * iter.c (gomp_iter_static_next): For chunk size 0
+ only use n ceil/ nthreads size for the first
+ n % nthreads threads in the team instead of
+ all threads except for the last few ones which
+ get less work or none at all.
+ * iter_ull.c (gomp_iter_ull_static_next): Likewise.
+ * env.c (parse_schedule): If OMP_SCHEDULE doesn't have
+ chunk argument, set run_sched_modifier to 0 for static
+ resp. 1 for other kinds. If chunk argument is 0
+ and not static, set value to 1.
2011-05-19 Jakub Jelinek <jakub@redhat.com>
@@ -52,19 +372,12 @@
PR middle-end/48591
* testsuite/libgomp.c/pr48591.c: New test.
-2011-03-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
-
- Backport from mainline:
- 2011-03-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+2011-03-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR bootstrap/48135
* acinclude.m4 (enable_symvers): Handle --disable-symvers.
* configure: Regenerate.
-2011-03-25 Release Manager
-
- * GCC 4.6.0 released.
-
2011-02-27 Jakub Jelinek <jakub@redhat.com>
PR fortran/47886
@@ -165,7 +478,7 @@
Tobias Burnus <burnus@net-b.de>
PR fortran/32049
- * configure.ac:
+ * configure.ac:
* configure: Regenerate.
2010-10-06 Marcus Shawcroft <marcus.shawcroft@arm.com>
@@ -929,7 +1242,7 @@
(gomp_new_thread_pool, gomp_free_pool_helper, gomp_free_thread): New
functions.
(gomp_team_start): Create new pool if current thread doesn't have
- one. Use pool fields instead of global gomp_* variables.
+ one. Use pool fields instead of global gomp_* variables.
Initialize thread_pool field for new threads. Clear single_count.
Change last argument from ws to team, don't create
new team, set ts.work_share to &team->work_shares[0] and clear
@@ -1161,7 +1474,7 @@
inlines.
* config/posix/bar.c (gomp_barrier_init): Clear generation field.
(gomp_barrier_wait_end): Change second argument to
- gomp_barrier_state_t.
+ gomp_barrier_state_t.
(gomp_team_barrier_wait, gomp_team_barrier_wait_end,
gomp_team_barrier_wake): New functions.
* config/linux/mutex.c: Include wait.h instead of libgomp.h and
diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index c0c91678ba..2bc4986ad1 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -22,26 +22,26 @@ toolexeclib_LTLIBRARIES = libgomp.la
nodist_toolexeclib_HEADERS = libgomp.spec
if LIBGOMP_BUILD_VERSIONED_SHLIB
+# -Wc is only a libtool option.
+comma = ,
+PREPROCESS = $(subst -Wc$(comma), , $(COMPILE)) -E
+
+libgomp.ver: $(top_srcdir)/libgomp.map
+ $(EGREP) -v '#(#| |$$)' $< | \
+ $(PREPROCESS) -P -include config.h - > $@ || (rm -f $@ ; exit 1)
+
if LIBGOMP_BUILD_VERSIONED_SHLIB_GNU
-if LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2
-libgomp_version_script = -Wl,--version-script,libgomp.map-sol2
-libgomp_version_dep = libgomp.map-sol2
-libgomp.map-sol2 : $(top_srcdir)/libgomp.map
- sed -e '/^#ifdef HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT/,/^#endif/d' $< \
- > $@ || (rm -f $@ ; exit 1)
-else
-libgomp_version_script = -Wl,--version-script,$(top_srcdir)/libgomp.map
-libgomp_version_dep = $(top_srcdir)/libgomp.map
-endif
+libgomp_version_script = -Wl,--version-script,libgomp.ver
+libgomp_version_dep = libgomp.ver
endif
if LIBGOMP_BUILD_VERSIONED_SHLIB_SUN
-libgomp_version_script = -Wl,-M,libgomp.map-sun
-libgomp_version_dep = libgomp.map-sun
-libgomp.map-sun : $(top_srcdir)/libgomp.map \
+libgomp_version_script = -Wl,-M,libgomp.ver-sun
+libgomp_version_dep = libgomp.ver-sun
+libgomp.ver-sun : libgomp.ver \
$(top_srcdir)/../contrib/make_sunver.pl \
$(libgomp_la_OBJECTS) $(libgomp_la_LIBADD)
perl $(top_srcdir)/../contrib/make_sunver.pl \
- $(top_srcdir)/libgomp.map \
+ libgomp.ver \
$(libgomp_la_OBJECTS:%.lo=.libs/%.o) \
`echo $(libgomp_la_LIBADD) | \
sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index b81936ac5c..ecc010eda4 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -298,14 +298,16 @@ AM_CFLAGS = $(XCFLAGS)
AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS)
toolexeclib_LTLIBRARIES = libgomp.la
nodist_toolexeclib_HEADERS = libgomp.spec
+
+# -Wc is only a libtool option.
+@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@comma = ,
+@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@PREPROCESS = $(subst -Wc$(comma), , $(COMPILE)) -E
@LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE@libgomp_version_script =
-@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_FALSE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_script = -Wl,--version-script,$(top_srcdir)/libgomp.map
-@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_script = -Wl,--version-script,libgomp.map-sol2
-@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_script = -Wl,-M,libgomp.map-sun
+@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_script = -Wl,--version-script,libgomp.ver
+@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_script = -Wl,-M,libgomp.ver-sun
@LIBGOMP_BUILD_VERSIONED_SHLIB_FALSE@libgomp_version_dep =
-@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_FALSE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = $(top_srcdir)/libgomp.map
-@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.map-sol2
-@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.map-sun
+@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver
+@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp_version_dep = libgomp.ver-sun
libgomp_version_info = -version-info $(libtool_VERSION)
libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \
$(lt_host_flags)
@@ -1066,14 +1068,15 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
vpath % $(strip $(search_path))
-@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp.map-sol2 : $(top_srcdir)/libgomp.map
-@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ sed -e '/^#ifdef HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT/,/^#endif/d' $< \
-@LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ > $@ || (rm -f $@ ; exit 1)
-@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp.map-sun : $(top_srcdir)/libgomp.map \
+
+@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp.ver: $(top_srcdir)/libgomp.map
+@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ $(EGREP) -v '#(#| |$$)' $< | \
+@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ $(PREPROCESS) -P -include config.h - > $@ || (rm -f $@ ; exit 1)
+@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@libgomp.ver-sun : libgomp.ver \
@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ $(top_srcdir)/../contrib/make_sunver.pl \
@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ $(libgomp_la_OBJECTS) $(libgomp_la_LIBADD)
@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ perl $(top_srcdir)/../contrib/make_sunver.pl \
-@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ $(top_srcdir)/libgomp.map \
+@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ libgomp.ver \
@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ $(libgomp_la_OBJECTS:%.lo=.libs/%.o) \
@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ `echo $(libgomp_la_LIBADD) | \
@LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE@@LIBGOMP_BUILD_VERSIONED_SHLIB_TRUE@ sed 's,/\([^/.]*\)\.la,/.libs/\1.a,g'` \
diff --git a/libgomp/acinclude.m4 b/libgomp/acinclude.m4
index 4a4b62f01c..d43aa88547 100644
--- a/libgomp/acinclude.m4
+++ b/libgomp/acinclude.m4
@@ -355,15 +355,12 @@ if test $enable_symvers != no ; then
# The Solaris 2 runtime linker doesn't support the GNU extension of
# binding the same symbol to different versions
solaris2*)
- symvers_renaming=no ;;
+ ;;
# Other platforms with GNU symbol versioning (GNU/Linux, more?) do.
*)
AC_DEFINE(HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT, 1,
[Define to 1 if the target runtime linker supports binding the same symbol to different versions.])
- symvers_renaming=yes ;;
+ ;;
esac
-else
- symvers_renaming=no
fi
-AM_CONDITIONAL(LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2, test $symvers_renaming = no)
])
diff --git a/libgomp/config/linux/affinity.c b/libgomp/config/linux/affinity.c
index da9f3d8fdc..7a904df949 100644
--- a/libgomp/config/linux/affinity.c
+++ b/libgomp/config/linux/affinity.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -28,7 +29,7 @@
#define _GNU_SOURCE 1
#endif
#include "libgomp.h"
-#include <sched.h>
+#include "proc.h"
#include <stdlib.h>
#include <unistd.h>
@@ -53,17 +54,36 @@ gomp_init_affinity (void)
}
CPU_ZERO (&cpusetnew);
- for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
- if (gomp_cpu_affinity[idx] < CPU_SETSIZE
- && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
- {
- if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpusetnew))
+ if (gomp_cpu_affinity_len == 0)
+ {
+ unsigned long count = gomp_cpuset_popcount (&cpuset);
+ if (count >= 65536)
+ count = 65536;
+ gomp_cpu_affinity = malloc (count * sizeof (unsigned short));
+ if (gomp_cpu_affinity == NULL)
+ {
+ gomp_error ("not enough memory to store CPU affinity list");
+ return;
+ }
+ for (widx = idx = 0; widx < count && idx < 65536; idx++)
+ if (CPU_ISSET (idx, &cpuset))
{
cpus++;
- CPU_SET (gomp_cpu_affinity[idx], &cpusetnew);
+ gomp_cpu_affinity[widx++] = idx;
}
- gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];
- }
+ }
+ else
+ for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
+ if (gomp_cpu_affinity[idx] < CPU_SETSIZE
+ && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
+ {
+ if (! CPU_ISSET (gomp_cpu_affinity[idx], &cpusetnew))
+ {
+ cpus++;
+ CPU_SET (gomp_cpu_affinity[idx], &cpusetnew);
+ }
+ gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];
+ }
if (widx == 0)
{
@@ -89,7 +109,7 @@ gomp_init_thread_affinity (pthread_attr_t *attr)
unsigned int cpu;
cpu_set_t cpuset;
- cpu = __sync_fetch_and_add (&affinity_counter, 1);
+ cpu = __atomic_fetch_add (&affinity_counter, 1, MEMMODEL_RELAXED);
cpu %= gomp_cpu_affinity_len;
CPU_ZERO (&cpuset);
CPU_SET (gomp_cpu_affinity[cpu], &cpuset);
diff --git a/libgomp/config/linux/alpha/futex.h b/libgomp/config/linux/alpha/futex.h
index a594d1663e..c8076bd299 100644
--- a/libgomp/config/linux/alpha/futex.h
+++ b/libgomp/config/linux/alpha/futex.h
@@ -101,9 +101,3 @@ cpu_relax (void)
{
__asm volatile ("" : : : "memory");
}
-
-static inline void
-atomic_write_barrier (void)
-{
- __asm volatile ("wmb" : : : "memory");
-}
diff --git a/libgomp/config/linux/bar.c b/libgomp/config/linux/bar.c
index 3e0379eb69..223a2aec43 100644
--- a/libgomp/config/linux/bar.c
+++ b/libgomp/config/linux/bar.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -37,17 +37,15 @@ gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
{
/* Next time we'll be awaiting TOTAL threads again. */
bar->awaited = bar->total;
- atomic_write_barrier ();
- bar->generation += 4;
+ __atomic_store_n (&bar->generation, bar->generation + 4,
+ MEMMODEL_RELEASE);
futex_wake ((int *) &bar->generation, INT_MAX);
}
else
{
- unsigned int generation = state;
-
do
- do_wait ((int *) &bar->generation, generation);
- while (bar->generation == generation);
+ do_wait ((int *) &bar->generation, state);
+ while (__atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE) == state);
}
}
@@ -81,15 +79,15 @@ gomp_team_barrier_wake (gomp_barrier_t *bar, int count)
void
gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
{
- unsigned int generation;
+ unsigned int generation, gen;
if (__builtin_expect ((state & 1) != 0, 0))
{
/* Next time we'll be awaiting TOTAL threads again. */
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
+
bar->awaited = bar->total;
- atomic_write_barrier ();
if (__builtin_expect (team->task_count, 0))
{
gomp_barrier_handle_tasks (state);
@@ -97,7 +95,7 @@ gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
}
else
{
- bar->generation = state + 3;
+ __atomic_store_n (&bar->generation, state + 3, MEMMODEL_RELEASE);
futex_wake ((int *) &bar->generation, INT_MAX);
return;
}
@@ -107,12 +105,16 @@ gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
do
{
do_wait ((int *) &bar->generation, generation);
- if (__builtin_expect (bar->generation & 1, 0))
- gomp_barrier_handle_tasks (state);
- if ((bar->generation & 2))
+ gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
+ if (__builtin_expect (gen & 1, 0))
+ {
+ gomp_barrier_handle_tasks (state);
+ gen = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE);
+ }
+ if ((gen & 2) != 0)
generation |= 2;
}
- while (bar->generation != state + 4);
+ while (gen != state + 4);
}
void
diff --git a/libgomp/config/linux/bar.h b/libgomp/config/linux/bar.h
index 9c1a8a0768..58bd40d698 100644
--- a/libgomp/config/linux/bar.h
+++ b/libgomp/config/linux/bar.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -50,7 +50,7 @@ static inline void gomp_barrier_init (gomp_barrier_t *bar, unsigned count)
static inline void gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count)
{
- __sync_fetch_and_add (&bar->awaited, count - bar->total);
+ __atomic_add_fetch (&bar->awaited, count - bar->total, MEMMODEL_ACQ_REL);
bar->total = count;
}
@@ -69,10 +69,13 @@ 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 = bar->generation & ~3;
- /* Do we need any barrier here or is __sync_add_and_fetch acting
- as the needed LoadLoad barrier already? */
- ret += __sync_add_and_fetch (&bar->awaited, -1) == 0;
+ unsigned int ret = __atomic_load_n (&bar->generation, MEMMODEL_ACQUIRE) & ~3;
+ /* A memory barrier is needed before exiting from the various forms
+ of gomp_barrier_wait, to satisfy OpenMP API version 3.1 section
+ 2.8.6 flush Construct, which says there is an implicit flush during
+ a barrier region. This is a convenient place to add the barrier,
+ so we use MEMMODEL_ACQ_REL here rather than MEMMODEL_ACQUIRE. */
+ ret += __atomic_add_fetch (&bar->awaited, -1, MEMMODEL_ACQ_REL) == 0;
return ret;
}
diff --git a/libgomp/config/linux/futex.h b/libgomp/config/linux/futex.h
index bab088a558..d0136f50ac 100644
--- a/libgomp/config/linux/futex.h
+++ b/libgomp/config/linux/futex.h
@@ -67,9 +67,3 @@ cpu_relax (void)
{
__asm volatile ("" : : : "memory");
}
-
-static inline void
-atomic_write_barrier (void)
-{
- __sync_synchronize ();
-}
diff --git a/libgomp/config/linux/ia64/futex.h b/libgomp/config/linux/ia64/futex.h
index e5e9aac399..85cd02fa15 100644
--- a/libgomp/config/linux/ia64/futex.h
+++ b/libgomp/config/linux/ia64/futex.h
@@ -86,9 +86,3 @@ cpu_relax (void)
{
__asm volatile ("hint @pause" : : : "memory");
}
-
-static inline void
-atomic_write_barrier (void)
-{
- __sync_synchronize ();
-}
diff --git a/libgomp/config/linux/ia64/mutex.h b/libgomp/config/linux/ia64/mutex.h
deleted file mode 100644
index 6e294059b2..0000000000
--- a/libgomp/config/linux/ia64/mutex.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* 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 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);
-
-/* IA64 needs a __sync_synchronize call before __sync_lock_test_and_set
- because __sync_lock_test_and_set is not a full memory fence. */
-static inline void gomp_mutex_unlock (gomp_mutex_t *mutex)
-{
- int val;
- __sync_synchronize ();
- 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/lock.c b/libgomp/config/linux/lock.c
index 405460780a..047d8cdf78 100644
--- a/libgomp/config/linux/lock.c
+++ b/libgomp/config/linux/lock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -62,7 +62,10 @@ gomp_unset_lock_30 (omp_lock_t *lock)
int
gomp_test_lock_30 (omp_lock_t *lock)
{
- return __sync_bool_compare_and_swap (lock, 0, 1);
+ int oldval = 0;
+
+ return __atomic_compare_exchange_n (lock, &oldval, 1, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED);
}
void
@@ -104,11 +107,14 @@ int
gomp_test_nest_lock_30 (omp_nest_lock_t *lock)
{
void *me = gomp_icv (true);
+ int oldval;
if (lock->owner == me)
return ++lock->count;
- if (__sync_bool_compare_and_swap (&lock->lock, 0, 1))
+ oldval = 0;
+ if (__atomic_compare_exchange_n (&lock->lock, &oldval, 1, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
{
lock->owner = me;
lock->count = 1;
@@ -169,7 +175,7 @@ static inline int gomp_tid (void)
void
gomp_init_nest_lock_25 (omp_nest_lock_25_t *lock)
{
- memset (lock, 0, sizeof (lock));
+ memset (lock, 0, sizeof (*lock));
}
void
@@ -184,8 +190,9 @@ gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock)
while (1)
{
- otid = __sync_val_compare_and_swap (&lock->owner, 0, tid);
- if (otid == 0)
+ otid = 0;
+ if (__atomic_compare_exchange_n (&lock->owner, &otid, tid, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
{
lock->count = 1;
return;
@@ -207,7 +214,7 @@ gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock)
if (--lock->count == 0)
{
- __sync_lock_release (&lock->owner);
+ __atomic_store_n (&lock->owner, 0, MEMMODEL_RELEASE);
futex_wake (&lock->owner, 1);
}
}
@@ -217,8 +224,9 @@ gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock)
{
int otid, tid = gomp_tid ();
- otid = __sync_val_compare_and_swap (&lock->owner, 0, tid);
- if (otid == 0)
+ otid = 0;
+ if (__atomic_compare_exchange_n (&lock->owner, &otid, tid, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
{
lock->count = 1;
return 1;
diff --git a/libgomp/config/linux/mips/futex.h b/libgomp/config/linux/mips/futex.h
index 576ada452e..93655d3114 100644
--- a/libgomp/config/linux/mips/futex.h
+++ b/libgomp/config/linux/mips/futex.h
@@ -64,9 +64,3 @@ cpu_relax (void)
{
__asm volatile ("" : : : "memory");
}
-
-static inline void
-atomic_write_barrier (void)
-{
- __sync_synchronize ();
-}
diff --git a/libgomp/config/linux/mutex.c b/libgomp/config/linux/mutex.c
index 3ca37c19f5..1b84ffb099 100644
--- a/libgomp/config/linux/mutex.c
+++ b/libgomp/config/linux/mutex.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -32,15 +32,34 @@ long int gomp_futex_wake = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
long int gomp_futex_wait = FUTEX_WAIT | FUTEX_PRIVATE_FLAG;
void
-gomp_mutex_lock_slow (gomp_mutex_t *mutex)
+gomp_mutex_lock_slow (gomp_mutex_t *mutex, int oldval)
{
- do
+ /* First loop spins a while. */
+ while (oldval == 1)
{
- int oldval = __sync_val_compare_and_swap (mutex, 1, 2);
- if (oldval != 0)
- do_wait (mutex, 2);
+ if (do_spin (mutex, 1))
+ {
+ /* Spin timeout, nothing changed. Set waiting flag. */
+ oldval = __atomic_exchange_n (mutex, -1, MEMMODEL_ACQUIRE);
+ if (oldval == 0)
+ return;
+ futex_wait (mutex, -1);
+ break;
+ }
+ else
+ {
+ /* Something changed. If now unlocked, we're good to go. */
+ oldval = 0;
+ if (__atomic_compare_exchange_n (mutex, &oldval, 1, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
+ return;
+ }
}
- while (!__sync_bool_compare_and_swap (mutex, 0, 2));
+
+ /* Second loop waits until mutex is unlocked. We always exit this
+ loop with wait flag set, so next unlock will awaken a thread. */
+ while ((oldval = __atomic_exchange_n (mutex, -1, MEMMODEL_ACQUIRE)))
+ do_wait (mutex, -1);
}
void
diff --git a/libgomp/config/linux/mutex.h b/libgomp/config/linux/mutex.h
index 1905ce012f..912152ec3a 100644
--- a/libgomp/config/linux/mutex.h
+++ b/libgomp/config/linux/mutex.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -33,38 +33,34 @@ typedef int gomp_mutex_t;
#define GOMP_MUTEX_INIT_0 1
-static inline void gomp_mutex_init (gomp_mutex_t *mutex)
+extern void gomp_mutex_lock_slow (gomp_mutex_t *mutex, int);
+extern void gomp_mutex_unlock_slow (gomp_mutex_t *mutex);
+
+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)
+static inline void
+gomp_mutex_destroy (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)
+static inline void
+gomp_mutex_lock (gomp_mutex_t *mutex)
{
- /* Warning: By definition __sync_lock_test_and_set() does not have
- proper memory barrier semantics for a mutex unlock operation.
- However, this default implementation is written assuming that it
- does, which is true for some targets.
-
- Targets that require additional memory barriers before
- __sync_lock_test_and_set to achieve the release semantics of
- mutex unlock, are encouraged to include
- "config/linux/ia64/mutex.h" in a target specific mutex.h instead
- of using this file. */
- int val = __sync_lock_test_and_set (mutex, 0);
- if (__builtin_expect (val > 1, 0))
- gomp_mutex_unlock_slow (mutex);
+ int oldval = 0;
+ if (!__atomic_compare_exchange_n (mutex, &oldval, 1, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
+ gomp_mutex_lock_slow (mutex, oldval);
}
-static inline void gomp_mutex_destroy (gomp_mutex_t *mutex)
+static inline void
+gomp_mutex_unlock (gomp_mutex_t *mutex)
{
+ int wait = __atomic_exchange_n (mutex, 0, MEMMODEL_RELEASE);
+ if (__builtin_expect (wait < 0, 0))
+ gomp_mutex_unlock_slow (mutex);
}
-
#endif /* GOMP_MUTEX_H */
diff --git a/libgomp/config/linux/omp-lock.h b/libgomp/config/linux/omp-lock.h
index e65aff7fce..2ca7c5e1d6 100644
--- a/libgomp/config/linux/omp-lock.h
+++ b/libgomp/config/linux/omp-lock.h
@@ -3,8 +3,8 @@
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 task
- and so require one int and a pointer. */
+ one int. Recursive locks require we identify the owning task
+ and so require in addition one int and a pointer. */
typedef int omp_lock_t;
typedef struct { int lock, count; void *owner; } omp_nest_lock_t;
diff --git a/libgomp/config/linux/powerpc/futex.h b/libgomp/config/linux/powerpc/futex.h
index efc05c4163..9d928e2044 100644
--- a/libgomp/config/linux/powerpc/futex.h
+++ b/libgomp/config/linux/powerpc/futex.h
@@ -84,9 +84,3 @@ cpu_relax (void)
{
__asm volatile ("" : : : "memory");
}
-
-static inline void
-atomic_write_barrier (void)
-{
- __asm volatile ("eieio" : : : "memory");
-}
diff --git a/libgomp/config/linux/powerpc/mutex.h b/libgomp/config/linux/powerpc/mutex.h
deleted file mode 100644
index e64ff077c8..0000000000
--- a/libgomp/config/linux/powerpc/mutex.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* On PowerPC __sync_lock_test_and_set isn't a full barrier. */
-#include "config/linux/ia64/mutex.h"
diff --git a/libgomp/config/linux/proc.c b/libgomp/config/linux/proc.c
index 01f51dfa19..8d9cfb599b 100644
--- a/libgomp/config/linux/proc.c
+++ b/libgomp/config/linux/proc.c
@@ -30,7 +30,7 @@
#define _GNU_SOURCE 1
#endif
#include "libgomp.h"
-#include <sched.h>
+#include "proc.h"
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_GETLOADAVG
@@ -40,8 +40,8 @@
#endif
#ifdef HAVE_PTHREAD_AFFINITY_NP
-static unsigned long
-cpuset_popcount (cpu_set_t *cpusetp)
+unsigned long
+gomp_cpuset_popcount (cpu_set_t *cpusetp)
{
#ifdef CPU_COUNT
/* glibc 2.6 and above provide a macro for this. */
@@ -76,7 +76,7 @@ gomp_init_num_threads (void)
if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset) == 0)
{
/* Count only the CPUs this process can use. */
- gomp_global_icv.nthreads_var = cpuset_popcount (&cpuset);
+ gomp_global_icv.nthreads_var = gomp_cpuset_popcount (&cpuset);
if (gomp_global_icv.nthreads_var == 0)
gomp_global_icv.nthreads_var = 1;
return;
@@ -99,7 +99,7 @@ get_num_procs (void)
if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset),
&cpuset) == 0)
{
- int ret = cpuset_popcount (&cpuset);
+ int ret = gomp_cpuset_popcount (&cpuset);
return ret != 0 ? ret : 1;
}
}
diff --git a/libgomp/config/linux/arm/mutex.h b/libgomp/config/linux/proc.h
index 30021d5474..f9e311088b 100644
--- a/libgomp/config/linux/arm/mutex.h
+++ b/libgomp/config/linux/proc.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 2010 Free Software Foundation, Inc.
- Contributed by ARM Ltd.
+/* Copyright (C) 2011 Free Software Foundation, Inc.
+ Contributed by Uros Bizjak <ubizjak@gmail.com>
This file is part of the GNU OpenMP Library (libgomp).
@@ -22,7 +22,13 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-/* ARM needs the same correct usage of __sync_synchronize and
- __sync_lock_test_and_set as ia64. So we just use its mutex.h. */
+#ifndef GOMP_PROC_H
+#define GOMP_PROC_H 1
-#include "config/linux/ia64/mutex.h"
+#include <sched.h>
+
+#ifdef HAVE_PTHREAD_AFFINITY_NP
+extern unsigned long gomp_cpuset_popcount (cpu_set_t *);
+#endif
+
+#endif /* GOMP_PROC_H */
diff --git a/libgomp/config/linux/ptrlock.c b/libgomp/config/linux/ptrlock.c
index 7c2ad61928..5896f424a3 100644
--- a/libgomp/config/linux/ptrlock.c
+++ b/libgomp/config/linux/ptrlock.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -34,7 +34,10 @@ void *
gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock)
{
int *intptr;
- __sync_bool_compare_and_swap (ptrlock, 1, 2);
+ uintptr_t oldval = 1;
+
+ __atomic_compare_exchange_n (ptrlock, &oldval, 2, false,
+ MEMMODEL_RELAXED, MEMMODEL_RELAXED);
/* futex works on ints, not pointers.
But a valid work share pointer will be at least
@@ -53,11 +56,10 @@ gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock)
}
void
-gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock, void *ptr)
+gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock)
{
int *intptr;
- *ptrlock = ptr;
__asm volatile ("" : "=r" (intptr) : "0" (ptrlock));
#if __BYTE_ORDER == __BIG_ENDIAN
if (sizeof (*ptrlock) > sizeof (int))
diff --git a/libgomp/config/linux/ptrlock.h b/libgomp/config/linux/ptrlock.h
index 97a3a1ad9e..2f17e09cc7 100644
--- a/libgomp/config/linux/ptrlock.h
+++ b/libgomp/config/linux/ptrlock.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -24,7 +24,14 @@
/* 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. */
+ implementation uses atomic instructions and the futex syscall.
+
+ A ptrlock has four states:
+ 0/NULL Initial
+ 1 Owned by me, I get to write a pointer to ptrlock.
+ 2 Some thread is waiting on the ptrlock.
+ >2 Ptrlock contains a valid pointer.
+ It is not valid to gain the ptrlock and then write a NULL to it. */
#ifndef GOMP_PTRLOCK_H
#define GOMP_PTRLOCK_H 1
@@ -39,20 +46,25 @@ static inline void gomp_ptrlock_init (gomp_ptrlock_t *ptrlock, void *ptr)
extern void *gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock);
static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock)
{
+ uintptr_t oldval;
+
if ((uintptr_t) *ptrlock > 2)
return *ptrlock;
- if (__sync_bool_compare_and_swap (ptrlock, NULL, (uintptr_t) 1))
+ oldval = 0;
+ if (__atomic_compare_exchange_n (ptrlock, &oldval, 1, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_ACQUIRE))
return NULL;
return gomp_ptrlock_get_slow (ptrlock);
}
-extern void gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock, void *ptr);
+extern void gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock);
static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr)
{
- if (!__sync_bool_compare_and_swap (ptrlock, (uintptr_t) 1, ptr))
- gomp_ptrlock_set_slow (ptrlock, ptr);
+ void *wait = __atomic_exchange_n (ptrlock, ptr, MEMMODEL_RELEASE);
+ if ((uintptr_t) wait != 1)
+ gomp_ptrlock_set_slow (ptrlock);
}
static inline void gomp_ptrlock_destroy (gomp_ptrlock_t *ptrlock)
diff --git a/libgomp/config/linux/s390/futex.h b/libgomp/config/linux/s390/futex.h
index 060032d73d..e015c921de 100644
--- a/libgomp/config/linux/s390/futex.h
+++ b/libgomp/config/linux/s390/futex.h
@@ -76,9 +76,3 @@ cpu_relax (void)
{
__asm volatile ("" : : : "memory");
}
-
-static inline void
-atomic_write_barrier (void)
-{
- __sync_synchronize ();
-}
diff --git a/libgomp/config/linux/sem.c b/libgomp/config/linux/sem.c
index ea981024c5..3f2fc99881 100644
--- a/libgomp/config/linux/sem.c
+++ b/libgomp/config/linux/sem.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -28,34 +28,56 @@
#include "wait.h"
-
void
-gomp_sem_wait_slow (gomp_sem_t *sem)
+gomp_sem_wait_slow (gomp_sem_t *sem, int count)
{
+ /* First loop spins a while. */
+ while (count == 0)
+ if (do_spin (sem, 0)
+ /* Spin timeout, nothing changed. Set waiting flag. */
+ && __atomic_compare_exchange_n (sem, &count, SEM_WAIT, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
+ {
+ futex_wait (sem, SEM_WAIT);
+ count = *sem;
+ break;
+ }
+ /* Something changed. If it wasn't the wait flag, we're good to go. */
+ else if (__builtin_expect (((count = *sem) & SEM_WAIT) == 0 && count != 0,
+ 1))
+ {
+ if (__atomic_compare_exchange_n (sem, &count, count - SEM_INC, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
+ return;
+ }
+
+ /* Second loop waits until semaphore is posted. We always exit this
+ loop with wait flag set, so next post will awaken a thread. */
while (1)
{
- int val = __sync_val_compare_and_swap (sem, 0, -1);
- if (val > 0)
+ unsigned int wake = count & ~SEM_WAIT;
+ int newval = SEM_WAIT;
+
+ if (wake != 0)
+ newval |= wake - SEM_INC;
+ if (__atomic_compare_exchange_n (sem, &count, newval, false,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
{
- if (__sync_bool_compare_and_swap (sem, val, val - 1))
- return;
+ if (wake != 0)
+ {
+ /* If we can wake more threads, do so now. */
+ if (wake > SEM_INC)
+ gomp_sem_post_slow (sem);
+ break;
+ }
+ do_wait (sem, SEM_WAIT);
+ count = *sem;
}
- do_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);
+ futex_wake (sem, 1);
}
diff --git a/libgomp/config/linux/sem.h b/libgomp/config/linux/sem.h
index 9b0f0f82ba..9bf480ded3 100644
--- a/libgomp/config/linux/sem.h
+++ b/libgomp/config/linux/sem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -24,34 +24,64 @@
/* 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. */
+ counting semaphore implementation uses atomic instructions and the
+ futex syscall, and a single 32-bit int to store semaphore state.
+ The low 31 bits are the count, the top bit is a flag set when some
+ threads may be waiting. */
#ifndef GOMP_SEM_H
#define GOMP_SEM_H 1
+#include <limits.h> /* For INT_MIN */
+
typedef int gomp_sem_t;
+#define SEM_WAIT INT_MIN
+#define SEM_INC 1
+
+extern void gomp_sem_wait_slow (gomp_sem_t *, int);
+extern void gomp_sem_post_slow (gomp_sem_t *);
-static inline void gomp_sem_init (gomp_sem_t *sem, int value)
+static inline void
+gomp_sem_init (gomp_sem_t *sem, int value)
{
- *sem = value;
+ *sem = value * SEM_INC;
}
-extern void gomp_sem_wait_slow (gomp_sem_t *);
-static inline void gomp_sem_wait (gomp_sem_t *sem)
+static inline void
+gomp_sem_destroy (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)
+static inline void
+gomp_sem_wait (gomp_sem_t *sem)
{
- if (!__sync_bool_compare_and_swap (sem, 0, 1))
- gomp_sem_post_slow (sem);
+ int count = *sem;
+
+ while ((count & ~SEM_WAIT) != 0)
+ if (__atomic_compare_exchange_n (sem, &count, count - SEM_INC, true,
+ MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
+ return;
+ gomp_sem_wait_slow (sem, count);
}
-static inline void gomp_sem_destroy (gomp_sem_t *sem)
+static inline void
+gomp_sem_post (gomp_sem_t *sem)
{
-}
+ int count = *sem;
+
+ /* Clear SEM_WAIT here so that if there are no more waiting threads
+ we transition back to the uncontended state that does not make
+ futex syscalls. If there are waiting threads then when one is
+ awoken it will set SEM_WAIT again, so other waiting threads are
+ woken on a future gomp_sem_post. Furthermore, the awoken thread
+ will wake other threads in case gomp_sem_post was called again
+ before it had time to set SEM_WAIT. */
+ while (!__atomic_compare_exchange_n (sem, &count,
+ (count + SEM_INC) & ~SEM_WAIT, true,
+ MEMMODEL_RELEASE, MEMMODEL_RELAXED))
+ continue;
+ if (__builtin_expect (count & SEM_WAIT, 0))
+ gomp_sem_post_slow (sem);
+}
#endif /* GOMP_SEM_H */
diff --git a/libgomp/config/linux/sparc/futex.h b/libgomp/config/linux/sparc/futex.h
index 214b786f7f..96e37b820c 100644
--- a/libgomp/config/linux/sparc/futex.h
+++ b/libgomp/config/linux/sparc/futex.h
@@ -90,19 +90,5 @@ futex_wake (int *addr, int count)
static inline void
cpu_relax (void)
{
-#if defined __arch64__ || defined __sparc_v9__
- __asm volatile ("membar #LoadLoad" : : : "memory");
-#else
- __asm volatile ("" : : : "memory");
-#endif
-}
-
-static inline void
-atomic_write_barrier (void)
-{
-#if defined __arch64__ || defined __sparc_v9__
- __asm volatile ("membar #StoreStore" : : : "memory");
-#else
- __sync_synchronize ();
-#endif
+ __asm volatile ("rd %%ccr, %%g0" : : : "memory");
}
diff --git a/libgomp/config/linux/tile/futex.h b/libgomp/config/linux/tile/futex.h
new file mode 100644
index 0000000000..2e733a7401
--- /dev/null
+++ b/libgomp/config/linux/tile/futex.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2011, 2012
+ Free Software Foundation, Inc.
+ Contributed by Walter Lee (walt@tilera.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/>. */
+
+/* Provide target-specific access to the futex system call. */
+
+#include <sys/syscall.h>
+#include <linux/futex.h>
+
+static inline void
+sys_futex0 (int *addr, int op, int val)
+{
+ long _sys_result;
+ long _clobber_r2, _clobber_r3, _clobber_r4, _clobber_r5, _clobber_r10;
+ int err;
+
+ __asm__ __volatile__ (
+ "swint1"
+ : "=R00" (_sys_result), "=R01" (err), "=R02" (_clobber_r2),
+ "=R03" (_clobber_r3), "=R04" (_clobber_r4), "=R05" (_clobber_r5),
+ "=R10" (_clobber_r10)
+ : "R10" (SYS_futex), "R00" (addr), "R01" (op), "R02" (val),
+ "R03" (0)
+ : "r6", "r7",
+ "r8", "r9", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "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);
+}
+
+static inline void
+cpu_relax (void)
+{
+ __asm volatile ("" : : : "memory");
+}
+
+static inline void
+atomic_write_barrier (void)
+{
+ __sync_synchronize ();
+}
diff --git a/libgomp/config/linux/wait.h b/libgomp/config/linux/wait.h
index 0e8abf111b..4f65985581 100644
--- a/libgomp/config/linux/wait.h
+++ b/libgomp/config/linux/wait.h
@@ -44,7 +44,7 @@ extern long int gomp_futex_wait, gomp_futex_wake;
#include <futex.h>
-static inline void do_wait (int *addr, int val)
+static inline int do_spin (int *addr, int val)
{
unsigned long long i, count = gomp_spin_count_var;
@@ -52,10 +52,16 @@ static inline void do_wait (int *addr, int val)
count = gomp_throttled_spin_count_var;
for (i = 0; i < count; i++)
if (__builtin_expect (*addr != val, 0))
- return;
+ return 0;
else
cpu_relax ();
- futex_wait (addr, val);
+ return 1;
+}
+
+static inline void do_wait (int *addr, int val)
+{
+ if (do_spin (addr, val))
+ futex_wait (addr, val);
}
#ifdef HAVE_ATTRIBUTE_VISIBILITY
diff --git a/libgomp/config/linux/x86/futex.h b/libgomp/config/linux/x86/futex.h
index cb7461d89e..f6d26dc491 100644
--- a/libgomp/config/linux/x86/futex.h
+++ b/libgomp/config/linux/x86/futex.h
@@ -24,7 +24,7 @@
/* Provide target-specific access to the futex system call. */
-#ifdef __LP64__
+#ifdef __x86_64__
# ifndef SYS_futex
# define SYS_futex 202
# endif
@@ -138,16 +138,10 @@ futex_wake (int *addr, int count)
}
}
-#endif /* __LP64__ */
+#endif /* __x86_64__ */
static inline void
cpu_relax (void)
{
__asm volatile ("rep; nop" : : : "memory");
}
-
-static inline void
-atomic_write_barrier (void)
-{
- __sync_synchronize ();
-}
diff --git a/libgomp/config/linux/mips/mutex.h b/libgomp/config/osf/sem.h
index 668cc11b29..7dcb542d55 100644
--- a/libgomp/config/linux/mips/mutex.h
+++ b/libgomp/config/osf/sem.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2011 Free Software Foundation, Inc.
This file is part of the GNU OpenMP Library (libgomp).
@@ -21,7 +21,33 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
-/* MIPS needs the same correct usage of __sync_synchronize and
- __sync_lock_test_and_set as ia64. So we just use its mutex.h. */
+/* This is a variant of config/posix/sem.h for Tru64 UNIX. The librt
+ sem_init implementation assumes int (4-byte) alignment for sem_t, while
+ the type only requires short (2-byte) alignment. This mismatch causes
+ lots of unaligned access warnings from the kernel, so enforce that
+ alignment. */
-#include "config/linux/ia64/mutex.h"
+#ifndef GOMP_SEM_H
+#define GOMP_SEM_H 1
+
+#include <semaphore.h>
+
+typedef sem_t gomp_sem_t __attribute__((aligned (__alignof__ (int))));
+
+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/posix95/lock.c b/libgomp/config/posix95/lock.c
deleted file mode 100644
index 22420417c6..0000000000
--- a/libgomp/config/posix95/lock.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
-
- 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 POSIX95 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. */
-
-#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->owner = NULL;
- lock->count = 0;
-}
-
-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)
-{
- lock->count--;
-
- 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_mutex_init (&lock->lock, NULL);
- lock->owner = (pthread_t) 0;
- lock->count = 0;
-}
-
-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_t me = pthread_self ();
-
- if (lock->owner != me)
- {
- pthread_mutex_lock (&lock->lock);
- lock->owner = me;
- }
-
- lock->count++;
-}
-
-void
-gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock)
-{
- lock->count--;
-
- if (lock->count == 0)
- {
- lock->owner = (pthread_t) 0;
- pthread_mutex_unlock (&lock->lock);
- }
-}
-
-int
-gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock)
-{
- pthread_t me = pthread_self ();
-
- if (lock->owner != me)
- {
- if (pthread_mutex_trylock (&lock->lock) != 0)
- return 0;
- lock->owner = me;
- }
-
- return ++lock->count;
-}
-
-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/posix95/omp-lock.h b/libgomp/config/posix95/omp-lock.h
deleted file mode 100644
index b542ba1319..0000000000
--- a/libgomp/config/posix95/omp-lock.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* 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 POSIX95 implementation, we map the two locks to the
- same PTHREADS primitive. */
-
-#include <pthread.h>
-#include <semaphore.h>
-
-typedef pthread_mutex_t omp_lock_25_t;
-typedef struct { pthread_mutex_t lock; pthread_t owner; 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/configure b/libgomp/configure
index 50dc29a620..8ed841a06e 100755
--- a/libgomp/configure
+++ b/libgomp/configure
@@ -619,8 +619,6 @@ link_gomp
XLDFLAGS
XCFLAGS
config_path
-LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_FALSE
-LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE
LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_FALSE
LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE
LIBGOMP_BUILD_VERSIONED_SHLIB_GNU_FALSE
@@ -9317,7 +9315,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
# Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
+ freebsd2.*)
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
hardcode_direct=yes
hardcode_minus_L=yes
@@ -10230,7 +10228,7 @@ freebsd* | dragonfly*)
objformat=`/usr/bin/objformat`
else
case $host_os in
- freebsd[123]*) objformat=aout ;;
+ freebsd[23].*) objformat=aout ;;
*) objformat=elf ;;
esac
fi
@@ -10248,7 +10246,7 @@ freebsd* | dragonfly*)
esac
shlibpath_var=LD_LIBRARY_PATH
case $host_os in
- freebsd2*)
+ freebsd2.*)
shlibpath_overrides_runpath=yes
;;
freebsd3.[01]* | freebsdelf3.[01]*)
@@ -11082,7 +11080,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11085 "configure"
+#line 11083 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11188,7 +11186,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11191 "configure"
+#line 11189 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13164,7 +13162,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
# Unfortunately, older versions of FreeBSD 2 do not have this feature.
- freebsd2*)
+ freebsd2.*)
archive_cmds_FC='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
hardcode_direct_FC=yes
hardcode_minus_L_FC=yes
@@ -13869,7 +13867,7 @@ freebsd* | dragonfly*)
objformat=`/usr/bin/objformat`
else
case $host_os in
- freebsd[123]*) objformat=aout ;;
+ freebsd[23].*) objformat=aout ;;
*) objformat=elf ;;
esac
fi
@@ -13887,7 +13885,7 @@ freebsd* | dragonfly*)
esac
shlibpath_var=LD_LIBRARY_PATH
case $host_os in
- freebsd2*)
+ freebsd2.*)
shlibpath_overrides_runpath=yes
;;
freebsd3.[01]* | freebsdelf3.[01]*)
@@ -15994,27 +15992,17 @@ if test $enable_symvers != no ; then
# The Solaris 2 runtime linker doesn't support the GNU extension of
# binding the same symbol to different versions
solaris2*)
- symvers_renaming=no ;;
+ ;;
# Other platforms with GNU symbol versioning (GNU/Linux, more?) do.
*)
$as_echo "#define HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT 1" >>confdefs.h
- symvers_renaming=yes ;;
+ ;;
esac
-else
- symvers_renaming=no
-fi
- if test $symvers_renaming = no; then
- LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE=
- LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_FALSE='#'
-else
- LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE='#'
- LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_FALSE=
fi
-
if test $enable_symvers = gnu; then
$as_echo "#define LIBGOMP_GNU_SYMBOL_VERSIONING 1" >>confdefs.h
@@ -16404,10 +16392,6 @@ if test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_SUN_TRUE}" && test -z "${LIBGOMP_BUI
as_fn_error "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB_SUN\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-if test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_TRUE}" && test -z "${LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2_FALSE}"; then
- as_fn_error "conditional \"LIBGOMP_BUILD_VERSIONED_SHLIB_SOL2\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
if test -z "${USE_FORTRAN_TRUE}" && test -z "${USE_FORTRAN_FALSE}"; then
as_fn_error "conditional \"USE_FORTRAN\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index 429c8e6bca..210dd5da34 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -32,7 +32,7 @@ if test $enable_linux_futex = yes; then
;;
arm*-*-linux*)
- config_path="linux/arm linux posix"
+ config_path="linux posix"
;;
ia64*-*-linux*)
@@ -51,6 +51,10 @@ if test $enable_linux_futex = yes; then
config_path="linux/s390 linux posix"
;;
+ tile*-*-linux*)
+ config_path="linux/tile linux posix"
+ ;;
+
# Note that bare i386 is not included here. We need cmpxchg.
i[456]86-*-linux*)
config_path="linux/x86 linux posix"
@@ -129,6 +133,11 @@ case "${target}" in
XLDFLAGS="${XLDFLAGS} -lpthread"
;;
+ alpha*-dec-osf*)
+ # Use Tru64 UNIX-specific sem.h version.
+ config_path="osf posix"
+ ;;
+
mips-sgi-irix6*)
# Need to link with -lpthread so libgomp.so is self-contained.
XLDFLAGS="${XLDFLAGS} -lpthread"
diff --git a/libgomp/critical.c b/libgomp/critical.c
index daf1ffc213..414c422162 100644
--- a/libgomp/critical.c
+++ b/libgomp/critical.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -33,6 +33,8 @@ static gomp_mutex_t default_lock;
void
GOMP_critical_start (void)
{
+ /* There is an implicit flush on entry to a critical region. */
+ __atomic_thread_fence (MEMMODEL_RELEASE);
gomp_mutex_lock (&default_lock);
}
diff --git a/libgomp/env.c b/libgomp/env.c
index 92fa8c3749..aff7490a8b 100644
--- a/libgomp/env.c
+++ b/libgomp/env.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
@@ -67,6 +67,7 @@ gomp_mutex_t gomp_remaining_threads_lock;
#endif
unsigned long gomp_available_cpus = 1, gomp_managed_threads = 1;
unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
+unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len;
/* Parse the OMP_SCHEDULE environment variable. */
@@ -108,7 +109,11 @@ parse_schedule (void)
while (isspace ((unsigned char) *env))
++env;
if (*env == '\0')
- return;
+ {
+ gomp_global_icv.run_sched_modifier
+ = gomp_global_icv.run_sched_var != GFS_STATIC;
+ return;
+ }
if (*env++ != ',')
goto unknown;
while (isspace ((unsigned char) *env))
@@ -129,6 +134,8 @@ parse_schedule (void)
if ((int)value != value)
goto invalid;
+ if (value == 0 && gomp_global_icv.run_sched_var != GFS_STATIC)
+ value = 1;
gomp_global_icv.run_sched_modifier = value;
return;
@@ -178,6 +185,95 @@ parse_unsigned_long (const char *name, unsigned long *pvalue, bool allow_zero)
return false;
}
+/* Parse an unsigned long list environment variable. Return true if one was
+ present and it was successfully parsed. */
+
+static bool
+parse_unsigned_long_list (const char *name, unsigned long *p1stvalue,
+ unsigned long **pvalues,
+ unsigned long *pnvalues)
+{
+ char *env, *end;
+ unsigned long value, *values = NULL;
+
+ env = getenv (name);
+ if (env == NULL)
+ return false;
+
+ while (isspace ((unsigned char) *env))
+ ++env;
+ if (*env == '\0')
+ goto invalid;
+
+ errno = 0;
+ value = strtoul (env, &end, 10);
+ if (errno || (long) value <= 0)
+ goto invalid;
+
+ while (isspace ((unsigned char) *end))
+ ++end;
+ if (*end != '\0')
+ {
+ if (*end == ',')
+ {
+ unsigned long nvalues = 0, nalloced = 0;
+
+ do
+ {
+ env = end + 1;
+ if (nvalues == nalloced)
+ {
+ unsigned long *n;
+ nalloced = nalloced ? nalloced * 2 : 16;
+ n = realloc (values, nalloced * sizeof (unsigned long));
+ if (n == NULL)
+ {
+ free (values);
+ gomp_error ("Out of memory while trying to parse"
+ " environment variable %s", name);
+ return false;
+ }
+ values = n;
+ if (nvalues == 0)
+ values[nvalues++] = value;
+ }
+
+ while (isspace ((unsigned char) *env))
+ ++env;
+ if (*env == '\0')
+ goto invalid;
+
+ errno = 0;
+ value = strtoul (env, &end, 10);
+ if (errno || (long) value <= 0)
+ goto invalid;
+
+ values[nvalues++] = value;
+ while (isspace ((unsigned char) *end))
+ ++end;
+ if (*end == '\0')
+ break;
+ if (*end != ',')
+ goto invalid;
+ }
+ while (1);
+ *p1stvalue = values[0];
+ *pvalues = values;
+ *pnvalues = nvalues;
+ return true;
+ }
+ goto invalid;
+ }
+
+ *p1stvalue = value;
+ return true;
+
+ invalid:
+ free (values);
+ gomp_error ("Invalid value for environment variable %s", name);
+ return false;
+}
+
/* Parse the OMP_STACKSIZE environment varible. Return true if one was
present and it was successfully parsed. */
@@ -475,6 +571,7 @@ initialize_env (void)
{
unsigned long stacksize;
int wait_policy;
+ bool bind_var = false;
/* Do a compile time check that mkomp_h.pl did good job. */
omp_check_defines ();
@@ -482,6 +579,7 @@ initialize_env (void)
parse_schedule ();
parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
parse_boolean ("OMP_NESTED", &gomp_global_icv.nest_var);
+ parse_boolean ("OMP_PROC_BIND", &bind_var);
parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var,
true);
parse_unsigned_long ("OMP_THREAD_LIMIT", &gomp_thread_limit_var, false);
@@ -492,10 +590,12 @@ initialize_env (void)
#endif
gomp_init_num_threads ();
gomp_available_cpus = gomp_global_icv.nthreads_var;
- if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_global_icv.nthreads_var,
- false))
+ if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
+ &gomp_global_icv.nthreads_var,
+ &gomp_nthreads_var_list,
+ &gomp_nthreads_var_list_len))
gomp_global_icv.nthreads_var = gomp_available_cpus;
- if (parse_affinity ())
+ if (parse_affinity () || bind_var)
gomp_init_affinity ();
wait_policy = parse_wait_policy ();
if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
diff --git a/libgomp/fortran.c b/libgomp/fortran.c
index 39bd7486b0..de806f8aba 100644
--- a/libgomp/fortran.c
+++ b/libgomp/fortran.c
@@ -69,6 +69,7 @@ ialias_redirect (omp_get_level)
ialias_redirect (omp_get_ancestor_thread_num)
ialias_redirect (omp_get_team_size)
ialias_redirect (omp_get_active_level)
+ialias_redirect (omp_in_final)
#endif
#ifndef LIBGOMP_GNU_SYMBOL_VERSIONING
@@ -428,3 +429,9 @@ omp_get_active_level_ (void)
{
return omp_get_active_level ();
}
+
+int32_t
+omp_in_final_ (void)
+{
+ return omp_in_final ();
+}
diff --git a/libgomp/iter.c b/libgomp/iter.c
index 9ec4dbd225..cd9484a1ea 100644
--- a/libgomp/iter.c
+++ b/libgomp/iter.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -59,7 +59,7 @@ gomp_iter_static_next (long *pstart, long *pend)
trip through the outer loop. */
if (ws->chunk_size == 0)
{
- unsigned long n, q, i;
+ unsigned long n, q, i, t;
unsigned long s0, e0;
long s, e;
@@ -74,11 +74,14 @@ gomp_iter_static_next (long *pstart, long *pend)
/* Compute the "zero-based" start and end points. That is, as
if the loop began at zero and incremented by one. */
q = n / nthreads;
- q += (q * nthreads != n);
- s0 = q * i;
+ t = n % nthreads;
+ if (i < t)
+ {
+ t = 0;
+ q++;
+ }
+ s0 = q * i + t;
e0 = s0 + q;
- if (e0 > n)
- e0 = n;
/* Notice when no iterations allocated for this thread. */
if (s0 >= e0)
diff --git a/libgomp/iter_ull.c b/libgomp/iter_ull.c
index 1754e6333c..a393920b55 100644
--- a/libgomp/iter_ull.c
+++ b/libgomp/iter_ull.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -60,7 +60,7 @@ gomp_iter_ull_static_next (gomp_ull *pstart, gomp_ull *pend)
trip through the outer loop. */
if (ws->chunk_size_ull == 0)
{
- gomp_ull n, q, i, s0, e0, s, e;
+ gomp_ull n, q, i, t, s0, e0, s, e;
if (thr->ts.static_trip > 0)
return 1;
@@ -75,11 +75,14 @@ gomp_iter_ull_static_next (gomp_ull *pstart, gomp_ull *pend)
/* Compute the "zero-based" start and end points. That is, as
if the loop began at zero and incremented by one. */
q = n / nthreads;
- q += (q * nthreads != n);
- s0 = q * i;
+ t = n % nthreads;
+ if (i < t)
+ {
+ t = 0;
+ q++;
+ }
+ s0 = q * i + t;
e0 = s0 + q;
- if (e0 > n)
- e0 = n;
/* Notice when no iterations allocated for this thread. */
if (s0 >= e0)
diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h
index aa2f580ca5..2c9c0716cd 100644
--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -44,6 +45,17 @@
# pragma GCC visibility push(hidden)
#endif
+/* If we were a C++ library, we'd get this from <std/atomic>. */
+enum memmodel
+{
+ MEMMODEL_RELAXED = 0,
+ MEMMODEL_CONSUME = 1,
+ MEMMODEL_ACQUIRE = 2,
+ MEMMODEL_RELEASE = 3,
+ MEMMODEL_ACQ_REL = 4,
+ MEMMODEL_SEQ_CST = 5
+};
+
#include "sem.h"
#include "mutex.h"
#include "bar.h"
@@ -226,6 +238,7 @@ extern gomp_mutex_t gomp_remaining_threads_lock;
extern unsigned long gomp_max_active_levels_var;
extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
extern unsigned long gomp_available_cpus, gomp_managed_threads;
+extern unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len;
enum gomp_task_kind
{
@@ -251,6 +264,7 @@ struct gomp_task
enum gomp_task_kind kind;
bool in_taskwait;
bool in_tied_task;
+ bool final_task;
gomp_sem_t taskwait_sem;
};
diff --git a/libgomp/libgomp.info b/libgomp/libgomp.info
index 408ed74662..b3f040ec94 100644
--- a/libgomp/libgomp.info
+++ b/libgomp/libgomp.info
@@ -1,5 +1,5 @@
-This is libgomp.info, produced by makeinfo version 4.13 from
-/d/gcc-4.6.2/gcc-4.6.2/libgomp/libgomp.texi.
+This is libgomp.info, produced by makeinfo version 4.12 from
+/space/rguenther/gcc-4.7.3/gcc-4.7.3/libgomp/libgomp.texi.
Copyright (C) 2006, 2007, 2008, 2010, 2011 Free Software Foundation,
Inc.
@@ -98,7 +98,7 @@ of the OpenMP runtime library (*note Runtime Library Routines::).
A complete description of all OpenMP directives accepted may be
found in the OpenMP Application Program Interface
-(http://www.openmp.org) manual, version 3.0.
+(http://www.openmp.org) manual, version 3.1.

File: libgomp.info, Node: Runtime Library Routines, Next: Environment Variables, Prev: Enabling OpenMP, Up: Top
@@ -107,7 +107,7 @@ File: libgomp.info, Node: Runtime Library Routines, Next: Environment Variable
**************************
The runtime routines described here are defined by section 3 of the
-OpenMP specifications in version 3.0. The routines are structured in
+OpenMP specifications in version 3.1. The routines are structured in
following three parts:
Control threads, processors and the parallel environment.
@@ -128,6 +128,7 @@ following three parts:
* omp_get_thread_limit:: Maximum number of threads
* omp_get_thread_num:: Current thread ID
* omp_in_parallel:: Whether a parallel region is active
+* omp_in_final:: Whether in final or included task region
* omp_set_dynamic:: Enable/disable dynamic teams
* omp_set_max_active_levels:: Limits the number of active parallel regions
* omp_set_nested:: Enable/disable nested parallel regions
@@ -177,7 +178,7 @@ _See also_:
omp_set_max_active_levels::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.19.

@@ -204,7 +205,7 @@ _See also_:
omp_get_team_size::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.17.

@@ -232,7 +233,7 @@ _See also_:
*note omp_set_dynamic::, *note OMP_DYNAMIC::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.8.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.8.

File: libgomp.info, Node: omp_get_level, Next: omp_get_max_active_levels, Prev: omp_get_dynamic, Up: Runtime Library Routines
@@ -254,7 +255,7 @@ _See also_:
*note omp_get_active_level::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.16.

@@ -277,8 +278,8 @@ _See also_:
*note omp_set_max_active_levels::, *note omp_get_active_level::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
- 3.2.14.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
+ 3.2.15.

File: libgomp.info, Node: omp_get_max_threads, Next: omp_get_nested, Prev: omp_get_max_active_levels, Up: Runtime Library Routines
@@ -301,7 +302,7 @@ _See also_:
omp_get_thread_limit::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.3.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.3.

File: libgomp.info, Node: omp_get_nested, Next: omp_get_num_procs, Prev: omp_get_max_threads, Up: Runtime Library Routines
@@ -329,7 +330,7 @@ _See also_:
*note omp_set_nested::, *note OMP_NESTED::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.10.

@@ -348,7 +349,7 @@ _Fortran_:
_Interface_: `integer function omp_get_num_procs()'
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.5.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.5.

File: libgomp.info, Node: omp_get_num_threads, Next: omp_get_schedule, Prev: omp_get_num_procs, Up: Runtime Library Routines
@@ -378,7 +379,7 @@ _See also_:
OMP_NUM_THREADS::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.2.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.2.

File: libgomp.info, Node: omp_get_schedule, Next: omp_get_team_size, Prev: omp_get_num_threads, Up: Runtime Library Routines
@@ -393,7 +394,7 @@ _Description_:
MODIFIER, is set to the chunk size.
_C/C++_
- _Prototype_: `omp_schedule(omp_sched_t *kind, int *modifier);'
+ _Prototype_: `void omp_schedule(omp_sched_t *kind, int *modifier);'
_Fortran_:
_Interface_: `subroutine omp_schedule(kind, modifier)'
@@ -404,7 +405,7 @@ _See also_:
*note omp_set_schedule::, *note OMP_SCHEDULE::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.12.

@@ -432,7 +433,7 @@ _See also_:
omp_get_ancestor_thread_num::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.18.

@@ -454,7 +455,7 @@ _See also_:
*note omp_get_max_threads::, *note OMP_THREAD_LIMIT::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.13.

@@ -480,10 +481,10 @@ _See also_:
*note omp_get_num_threads::, *note omp_get_ancestor_thread_num::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.4.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.4.

-File: libgomp.info, Node: omp_in_parallel, Next: omp_set_dynamic, Prev: omp_get_thread_num, Up: Runtime Library Routines
+File: libgomp.info, Node: omp_in_parallel, Next: omp_in_final, Prev: omp_get_thread_num, Up: Runtime Library Routines
2.14 `omp_in_parallel' - Whether a parallel region is active
============================================================
@@ -500,12 +501,33 @@ _Fortran_:
_Interface_: `logical function omp_in_parallel()'
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.6.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.6.
+
+
+File: libgomp.info, Node: omp_in_final, Next: omp_set_dynamic, Prev: omp_in_parallel, Up: Runtime Library Routines
+
+2.15 `omp_in_final' - Whether in final or included task region
+==============================================================
+
+_Description_:
+ This function returns `true' if currently running in a final or
+ included task region, `false' otherwise. Here, `true' and `false'
+ represent their language-specific counterparts.
+
+_C/C++_:
+ _Prototype_: `int omp_in_final(void);'
+
+_Fortran_:
+ _Interface_: `logical function omp_in_final()'
+
+_Reference_:
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
+ 3.2.20.

-File: libgomp.info, Node: omp_set_dynamic, Next: omp_set_max_active_levels, Prev: omp_in_parallel, Up: Runtime Library Routines
+File: libgomp.info, Node: omp_set_dynamic, Next: omp_set_max_active_levels, Prev: omp_in_final, Up: Runtime Library Routines
-2.15 `omp_set_dynamic' - Enable/disable dynamic teams
+2.16 `omp_set_dynamic' - Enable/disable dynamic teams
=====================================================
_Description_:
@@ -525,12 +547,12 @@ _See also_:
*note OMP_DYNAMIC::, *note omp_get_dynamic::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.7.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.7.

File: libgomp.info, Node: omp_set_max_active_levels, Next: omp_set_nested, Prev: omp_set_dynamic, Up: Runtime Library Routines
-2.16 `omp_set_max_active_levels' - Limits the number of active parallel regions
+2.17 `omp_set_max_active_levels' - Limits the number of active parallel regions
===============================================================================
_Description_:
@@ -548,13 +570,13 @@ _See also_:
*note omp_get_max_active_levels::, *note omp_get_active_level::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.14.

File: libgomp.info, Node: omp_set_nested, Next: omp_set_num_threads, Prev: omp_set_max_active_levels, Up: Runtime Library Routines
-2.17 `omp_set_nested' - Enable/disable nested parallel regions
+2.18 `omp_set_nested' - Enable/disable nested parallel regions
==============================================================
_Description_:
@@ -574,12 +596,12 @@ _See also_:
*note OMP_NESTED::, *note omp_get_nested::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.9.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.9.

File: libgomp.info, Node: omp_set_num_threads, Next: omp_set_schedule, Prev: omp_set_nested, Up: Runtime Library Routines
-2.18 `omp_set_num_threads' - Set upper team size limit
+2.19 `omp_set_num_threads' - Set upper team size limit
======================================================
_Description_:
@@ -599,12 +621,12 @@ _See also_:
omp_get_max_threads::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.2.1.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.2.1.

File: libgomp.info, Node: omp_set_schedule, Next: omp_init_lock, Prev: omp_set_num_threads, Up: Runtime Library Routines
-2.19 `omp_set_schedule' - Set the runtime scheduling method
+2.20 `omp_set_schedule' - Set the runtime scheduling method
===========================================================
_Description_:
@@ -616,7 +638,7 @@ _Description_:
argument is ignored.
_C/C++_
- _Prototype_: `int omp_set_schedule(omp_sched_t *kind, int
+ _Prototype_: `void omp_set_schedule(omp_sched_t *kind, int
*modifier);'
_Fortran_:
@@ -628,13 +650,13 @@ _See also_:
*note omp_get_schedule:: *note OMP_SCHEDULE::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section
+ OpenMP specifications v3.1 (http://www.openmp.org/), section
3.2.11.

File: libgomp.info, Node: omp_init_lock, Next: omp_set_lock, Prev: omp_set_schedule, Up: Runtime Library Routines
-2.20 `omp_init_lock' - Initialize simple lock
+2.21 `omp_init_lock' - Initialize simple lock
=============================================
_Description_:
@@ -652,12 +674,12 @@ _See also_:
*note omp_destroy_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.1.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.1.

File: libgomp.info, Node: omp_set_lock, Next: omp_test_lock, Prev: omp_init_lock, Up: Runtime Library Routines
-2.21 `omp_set_lock' - Wait for and set simple lock
+2.22 `omp_set_lock' - Wait for and set simple lock
==================================================
_Description_:
@@ -678,12 +700,12 @@ _See also_:
omp_unset_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.3.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.3.

File: libgomp.info, Node: omp_test_lock, Next: omp_unset_lock, Prev: omp_set_lock, Up: Runtime Library Routines
-2.22 `omp_test_lock' - Test and set simple lock if available
+2.23 `omp_test_lock' - Test and set simple lock if available
============================================================
_Description_:
@@ -697,20 +719,19 @@ _C/C++_:
_Prototype_: `int omp_test_lock(omp_lock_t *lock);'
_Fortran_:
- _Interface_: `subroutine omp_test_lock(lock)'
- `logical(omp_logical_kind) :: omp_test_lock'
+ _Interface_: `logical function omp_test_lock(lock)'
`integer(omp_lock_kind), intent(inout) :: lock'
_See also_:
*note omp_init_lock::, *note omp_set_lock::, *note omp_set_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.5.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.5.

File: libgomp.info, Node: omp_unset_lock, Next: omp_destroy_lock, Prev: omp_test_lock, Up: Runtime Library Routines
-2.23 `omp_unset_lock' - Unset simple lock
+2.24 `omp_unset_lock' - Unset simple lock
=========================================
_Description_:
@@ -718,7 +739,7 @@ _Description_:
`omp_set_lock' or `omp_test_lock' before. In addition, the lock
must be held by the thread calling `omp_unset_lock'. Then, the
lock becomes unlocked. If one or more threads attempted to set the
- lock before, one of them is chosen to, again, set the lock for
+ lock before, one of them is chosen to, again, set the lock to
itself.
_C/C++_:
@@ -732,12 +753,12 @@ _See also_:
*note omp_set_lock::, *note omp_test_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.4.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.4.

File: libgomp.info, Node: omp_destroy_lock, Next: omp_init_nest_lock, Prev: omp_unset_lock, Up: Runtime Library Routines
-2.24 `omp_destroy_lock' - Destroy simple lock
+2.25 `omp_destroy_lock' - Destroy simple lock
=============================================
_Description_:
@@ -755,12 +776,12 @@ _See also_:
*note omp_init_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.2.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.2.

File: libgomp.info, Node: omp_init_nest_lock, Next: omp_set_nest_lock, Prev: omp_destroy_lock, Up: Runtime Library Routines
-2.25 `omp_init_nest_lock' - Initialize nested lock
+2.26 `omp_init_nest_lock' - Initialize nested lock
==================================================
_Description_:
@@ -778,19 +799,19 @@ _See also_:
*note omp_destroy_nest_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.1.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.1.

File: libgomp.info, Node: omp_set_nest_lock, Next: omp_test_nest_lock, Prev: omp_init_nest_lock, Up: Runtime Library Routines
-2.26 `omp_set_nest_lock' - Wait for and set nested lock
+2.27 `omp_set_nest_lock' - Wait for and set nested lock
=======================================================
_Description_:
Before setting a nested lock, the lock variable must be
initialized by `omp_init_nest_lock'. The calling thread is blocked
until the lock is available. If the lock is already held by the
- current thread, the nesting count for the lock in incremented.
+ current thread, the nesting count for the lock is incremented.
_C/C++_:
_Prototype_: `void omp_set_nest_lock(omp_nest_lock_t *lock);'
@@ -803,12 +824,12 @@ _See also_:
*note omp_init_nest_lock::, *note omp_unset_nest_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.3.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.3.

File: libgomp.info, Node: omp_test_nest_lock, Next: omp_unset_nest_lock, Prev: omp_set_nest_lock, Up: Runtime Library Routines
-2.27 `omp_test_nest_lock' - Test and set nested lock if available
+2.28 `omp_test_nest_lock' - Test and set nested lock if available
=================================================================
_Description_:
@@ -823,20 +844,19 @@ _C/C++_:
_Prototype_: `int omp_test_nest_lock(omp_nest_lock_t *lock);'
_Fortran_:
- _Interface_: `integer function omp_test_nest_lock(lock)'
- `integer(omp_integer_kind) :: omp_test_nest_lock'
+ _Interface_: `logical function omp_test_nest_lock(lock)'
`integer(omp_nest_lock_kind), intent(inout) :: lock'
_See also_:
*note omp_init_lock::, *note omp_set_lock::, *note omp_set_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.5.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.5.

File: libgomp.info, Node: omp_unset_nest_lock, Next: omp_destroy_nest_lock, Prev: omp_test_nest_lock, Up: Runtime Library Routines
-2.28 `omp_unset_nest_lock' - Unset nested lock
+2.29 `omp_unset_nest_lock' - Unset nested lock
==============================================
_Description_:
@@ -845,7 +865,7 @@ _Description_:
addition, the lock must be held by the thread calling
`omp_unset_nested_lock'. If the nesting count drops to zero, the
lock becomes unlocked. If one ore more threads attempted to set
- the lock before, one of them is chosen to, again, set the lock for
+ the lock before, one of them is chosen to, again, set the lock to
itself.
_C/C++_:
@@ -859,12 +879,12 @@ _See also_:
*note omp_set_nest_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.4.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.4.

File: libgomp.info, Node: omp_destroy_nest_lock, Next: omp_get_wtick, Prev: omp_unset_nest_lock, Up: Runtime Library Routines
-2.29 `omp_destroy_nest_lock' - Destroy nested lock
+2.30 `omp_destroy_nest_lock' - Destroy nested lock
==================================================
_Description_:
@@ -883,12 +903,12 @@ _See also_:
*note omp_init_lock::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.3.2.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.3.2.

File: libgomp.info, Node: omp_get_wtick, Next: omp_get_wtime, Prev: omp_destroy_nest_lock, Up: Runtime Library Routines
-2.30 `omp_get_wtick' - Get timer precision
+2.31 `omp_get_wtick' - Get timer precision
==========================================
_Description_:
@@ -905,12 +925,12 @@ _See also_:
*note omp_get_wtime::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.4.2.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.4.2.

File: libgomp.info, Node: omp_get_wtime, Prev: omp_get_wtick, Up: Runtime Library Routines
-2.31 `omp_get_wtime' - Elapsed wall clock time
+2.32 `omp_get_wtime' - Elapsed wall clock time
==============================================
_Description_:
@@ -930,7 +950,7 @@ _See also_:
*note omp_get_wtick::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 3.4.1.
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 3.4.1.

File: libgomp.info, Node: Environment Variables, Next: The libgomp ABI, Prev: Runtime Library Routines, Up: Top
@@ -941,7 +961,7 @@ File: libgomp.info, Node: Environment Variables, Next: The libgomp ABI, Prev:
The variables `OMP_DYNAMIC', `OMP_MAX_ACTIVE_LEVELS', `OMP_NESTED',
`OMP_NUM_THREADS', `OMP_SCHEDULE', `OMP_STACKSIZE',`OMP_THREAD_LIMIT'
and `OMP_WAIT_POLICY' are defined by section 4 of the OpenMP
-specifications in version 3.0, while `GOMP_CPU_AFFINITY' and
+specifications in version 3.1, while `GOMP_CPU_AFFINITY' and
`GOMP_STACKSIZE' are GNU extensions.
* Menu:
@@ -954,6 +974,7 @@ specifications in version 3.0, while `GOMP_CPU_AFFINITY' and
* OMP_SCHEDULE:: How threads are scheduled
* OMP_THREAD_LIMIT:: Set the maximum number of threads
* OMP_WAIT_POLICY:: How waiting threads are handled
+* OMP_PROC_BIND:: Whether theads may be moved between CPUs
* GOMP_CPU_AFFINITY:: Bind threads to specific CPUs
* GOMP_STACKSIZE:: Set default thread stack size
@@ -973,7 +994,7 @@ _See also_:
*note omp_set_dynamic::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 4.3
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 4.3

File: libgomp.info, Node: OMP_MAX_ACTIVE_LEVELS, Next: OMP_NESTED, Prev: OMP_DYNAMIC, Up: Environment Variables
@@ -983,14 +1004,14 @@ File: libgomp.info, Node: OMP_MAX_ACTIVE_LEVELS, Next: OMP_NESTED, Prev: OMP_
_Description_:
Specifies the initial value for the maximum number of nested
- parallel regions. The value of this variable shall be positive
+ parallel regions. The value of this variable shall be a positive
integer. If undefined, the number of active levels is unlimited.
_See also_:
*note omp_set_max_active_levels::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 4.7
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 4.8

File: libgomp.info, Node: OMP_NESTED, Next: OMP_NUM_THREADS, Prev: OMP_MAX_ACTIVE_LEVELS, Up: Environment Variables
@@ -1008,7 +1029,7 @@ _See also_:
*note omp_set_nested::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 4.4
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 4.5

File: libgomp.info, Node: OMP_NUM_THREADS, Next: OMP_STACKSIZE, Prev: OMP_NESTED, Up: Environment Variables
@@ -1018,14 +1039,16 @@ File: libgomp.info, Node: OMP_NUM_THREADS, Next: OMP_STACKSIZE, Prev: OMP_NES
_Description_:
Specifies the default number of threads to use in parallel
- regions. The value of this variable shall be a positive integer.
- If undefined one thread per CPU is used.
+ regions. The value of this variable shall be a comma-separated
+ list of positive integers; the value specified the number of
+ threads to use for the corresponding nested level. If undefined
+ one thread per CPU is used.
_See also_:
*note omp_set_num_threads::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 4.2
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 4.2

File: libgomp.info, Node: OMP_SCHEDULE, Next: OMP_THREAD_LIMIT, Prev: OMP_STACKSIZE, Up: Environment Variables
@@ -1044,7 +1067,7 @@ _See also_:
*note omp_set_schedule::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), sections
+ OpenMP specifications v3.1 (http://www.openmp.org/), sections
2.5.1 and 4.1

@@ -1058,13 +1081,13 @@ _Description_:
is suffixed by `B', `K', `M' or `G', in which case the size is,
respectively, in bytes, kilobytes, megabytes or gigabytes. This is
different from `pthread_attr_setstacksize' which gets the number
- of bytes as an argument. If the stacksize cannot be set due to
- system constraints, an error is reported and the initial stacksize
- is left unchanged. If undefined, the stack size is system
+ of bytes as an argument. If the stack size cannot be set due to
+ system constraints, an error is reported and the initial stack
+ size is left unchanged. If undefined, the stack size is system
dependent.
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), sections 4.5
+ OpenMP specifications v3.1 (http://www.openmp.org/), sections 4.6

File: libgomp.info, Node: OMP_THREAD_LIMIT, Next: OMP_WAIT_POLICY, Prev: OMP_SCHEDULE, Up: Environment Variables
@@ -1081,10 +1104,10 @@ _See also_:
*note OMP_NUM_THREADS:: *note omp_get_thread_limit::
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), section 4.8
+ OpenMP specifications v3.1 (http://www.openmp.org/), section 4.9

-File: libgomp.info, Node: OMP_WAIT_POLICY, Next: GOMP_CPU_AFFINITY, Prev: OMP_THREAD_LIMIT, Up: Environment Variables
+File: libgomp.info, Node: OMP_WAIT_POLICY, Next: OMP_PROC_BIND, Prev: OMP_THREAD_LIMIT, Up: Environment Variables
3.8 `OMP_WAIT_POLICY' - How waiting threads are handled
=======================================================
@@ -1096,13 +1119,30 @@ _Description_:
they should.
_Reference_:
- OpenMP specifications v3.0 (http://www.openmp.org/), sections 4.6
+ OpenMP specifications v3.1 (http://www.openmp.org/), sections 4.7

-File: libgomp.info, Node: GOMP_CPU_AFFINITY, Next: GOMP_STACKSIZE, Prev: OMP_WAIT_POLICY, Up: Environment Variables
+File: libgomp.info, Node: OMP_PROC_BIND, Next: GOMP_CPU_AFFINITY, Prev: OMP_WAIT_POLICY, Up: Environment Variables
-3.9 `GOMP_CPU_AFFINITY' - Bind threads to specific CPUs
-=======================================================
+3.9 `OMP_PROC_BIND' - Whether theads may be moved between CPUs
+==============================================================
+
+_Description_:
+ Specifies whether threads may be moved between processors. If set
+ to `true', OpenMP theads should not be moved, if set to `false'
+ they may be moved.
+
+_See also_:
+ *note GOMP_CPU_AFFINITY::
+
+_Reference_:
+ OpenMP specifications v3.1 (http://www.openmp.org/), sections 4.4
+
+
+File: libgomp.info, Node: GOMP_CPU_AFFINITY, Next: GOMP_STACKSIZE, Prev: OMP_PROC_BIND, Up: Environment Variables
+
+3.10 `GOMP_CPU_AFFINITY' - Bind threads to specific CPUs
+========================================================
_Description_:
Binds threads to specific CPUs. The variable should contain a
@@ -1128,17 +1168,20 @@ _Description_:
If this environment variable is omitted, the host system will
handle the assignment of threads to CPUs.
+_See also_:
+ *note OMP_PROC_BIND::
+

File: libgomp.info, Node: GOMP_STACKSIZE, Prev: GOMP_CPU_AFFINITY, Up: Environment Variables
-3.10 `GOMP_STACKSIZE' - Set default thread stack size
+3.11 `GOMP_STACKSIZE' - Set default thread stack size
=====================================================
_Description_:
Set the default thread stack size in kilobytes. This is different
from `pthread_attr_setstacksize' which gets the number of bytes as
- an argument. If the stacksize cannot be set due to system
- constraints, an error is reported and the initial stacksize is
+ an argument. If the stack size cannot be set due to system
+ constraints, an error is reported and the initial stack size is
left unchanged. If undefined, the stack size is system dependent.
_See also_:
@@ -2425,13 +2468,14 @@ Index
* Environment Variable <1>: GOMP_STACKSIZE. (line 6)
* Environment Variable <2>: GOMP_CPU_AFFINITY. (line 6)
-* Environment Variable <3>: OMP_WAIT_POLICY. (line 6)
-* Environment Variable <4>: OMP_THREAD_LIMIT. (line 6)
-* Environment Variable <5>: OMP_STACKSIZE. (line 6)
-* Environment Variable <6>: OMP_SCHEDULE. (line 6)
-* Environment Variable <7>: OMP_NUM_THREADS. (line 6)
-* Environment Variable <8>: OMP_NESTED. (line 6)
-* Environment Variable <9>: OMP_MAX_ACTIVE_LEVELS. (line 6)
+* Environment Variable <3>: OMP_PROC_BIND. (line 6)
+* Environment Variable <4>: OMP_WAIT_POLICY. (line 6)
+* Environment Variable <5>: OMP_THREAD_LIMIT. (line 6)
+* Environment Variable <6>: OMP_STACKSIZE. (line 6)
+* Environment Variable <7>: OMP_SCHEDULE. (line 6)
+* Environment Variable <8>: OMP_NUM_THREADS. (line 6)
+* Environment Variable <9>: OMP_NESTED. (line 6)
+* Environment Variable <10>: OMP_MAX_ACTIVE_LEVELS. (line 6)
* Environment Variable: OMP_DYNAMIC. (line 6)
* FDL, GNU Free Documentation License: GNU Free Documentation License.
(line 6)
@@ -2444,70 +2488,72 @@ Index

Tag Table:
-Node: Top2063
-Node: Enabling OpenMP3257
-Node: Runtime Library Routines4042
-Node: omp_get_active_level6417
-Node: omp_get_ancestor_thread_num7121
-Node: omp_get_dynamic8048
-Node: omp_get_level8926
-Node: omp_get_max_active_levels9550
-Node: omp_get_max_threads10253
-Node: omp_get_nested11009
-Node: omp_get_num_procs11921
-Node: omp_get_num_threads12439
-Node: omp_get_schedule13521
-Node: omp_get_team_size14437
-Node: omp_get_thread_limit15399
-Node: omp_get_thread_num16022
-Node: omp_in_parallel16890
-Node: omp_set_dynamic17540
-Node: omp_set_max_active_levels18380
-Node: omp_set_nested19160
-Node: omp_set_num_threads20039
-Node: omp_set_schedule20875
-Node: omp_init_lock21946
-Node: omp_set_lock22597
-Node: omp_test_lock23448
-Node: omp_unset_lock24477
-Node: omp_destroy_lock25404
-Node: omp_init_nest_lock26078
-Node: omp_set_nest_lock26811
-Node: omp_test_nest_lock27722
-Node: omp_unset_nest_lock28820
-Node: omp_destroy_nest_lock29831
-Node: omp_get_wtick30579
-Node: omp_get_wtime31170
-Node: Environment Variables31944
-Node: OMP_DYNAMIC33005
-Node: OMP_MAX_ACTIVE_LEVELS33573
-Node: OMP_NESTED34210
-Node: OMP_NUM_THREADS34814
-Node: OMP_SCHEDULE35382
-Node: OMP_STACKSIZE36076
-Node: OMP_THREAD_LIMIT36900
-Node: OMP_WAIT_POLICY37495
-Node: GOMP_CPU_AFFINITY38060
-Node: GOMP_STACKSIZE39561
-Node: The libgomp ABI40369
-Node: Implementing MASTER construct41168
-Node: Implementing CRITICAL construct41582
-Node: Implementing ATOMIC construct42321
-Node: Implementing FLUSH construct42802
-Node: Implementing BARRIER construct43073
-Node: Implementing THREADPRIVATE construct43342
-Node: Implementing PRIVATE clause43994
-Node: Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses44575
-Node: Implementing REDUCTION clause45899
-Node: Implementing PARALLEL construct46456
-Node: Implementing FOR construct47713
-Node: Implementing ORDERED construct49711
-Node: Implementing SECTIONS construct50017
-Node: Implementing SINGLE construct50783
-Node: Reporting Bugs51445
-Node: Copying51755
-Node: GNU Free Documentation License70965
-Node: Funding96107
-Node: Index98624
+Node: Top2077
+Node: Enabling OpenMP3271
+Node: Runtime Library Routines4056
+Node: omp_get_active_level6504
+Node: omp_get_ancestor_thread_num7208
+Node: omp_get_dynamic8135
+Node: omp_get_level9013
+Node: omp_get_max_active_levels9637
+Node: omp_get_max_threads10340
+Node: omp_get_nested11096
+Node: omp_get_num_procs12008
+Node: omp_get_num_threads12526
+Node: omp_get_schedule13608
+Node: omp_get_team_size14529
+Node: omp_get_thread_limit15491
+Node: omp_get_thread_num16114
+Node: omp_in_parallel16982
+Node: omp_in_final17629
+Node: omp_set_dynamic18300
+Node: omp_set_max_active_levels19137
+Node: omp_set_nested19917
+Node: omp_set_num_threads20796
+Node: omp_set_schedule21632
+Node: omp_init_lock22704
+Node: omp_set_lock23355
+Node: omp_test_lock24206
+Node: omp_unset_lock25177
+Node: omp_destroy_lock26103
+Node: omp_init_nest_lock26777
+Node: omp_set_nest_lock27510
+Node: omp_test_nest_lock28421
+Node: omp_unset_nest_lock29450
+Node: omp_destroy_nest_lock30460
+Node: omp_get_wtick31208
+Node: omp_get_wtime31799
+Node: Environment Variables32573
+Node: OMP_DYNAMIC33701
+Node: OMP_MAX_ACTIVE_LEVELS34269
+Node: OMP_NESTED34908
+Node: OMP_NUM_THREADS35512
+Node: OMP_SCHEDULE36200
+Node: OMP_STACKSIZE36894
+Node: OMP_THREAD_LIMIT37720
+Node: OMP_WAIT_POLICY38315
+Node: OMP_PROC_BIND38876
+Node: GOMP_CPU_AFFINITY39434
+Node: GOMP_STACKSIZE40975
+Node: The libgomp ABI41785
+Node: Implementing MASTER construct42584
+Node: Implementing CRITICAL construct42998
+Node: Implementing ATOMIC construct43737
+Node: Implementing FLUSH construct44218
+Node: Implementing BARRIER construct44489
+Node: Implementing THREADPRIVATE construct44758
+Node: Implementing PRIVATE clause45410
+Node: Implementing FIRSTPRIVATE LASTPRIVATE COPYIN and COPYPRIVATE clauses45991
+Node: Implementing REDUCTION clause47315
+Node: Implementing PARALLEL construct47872
+Node: Implementing FOR construct49129
+Node: Implementing ORDERED construct51127
+Node: Implementing SECTIONS construct51433
+Node: Implementing SINGLE construct52199
+Node: Reporting Bugs52861
+Node: Copying53171
+Node: GNU Free Documentation License72381
+Node: Funding97523
+Node: Index100040

End Tag Table
diff --git a/libgomp/libgomp.map b/libgomp/libgomp.map
index d95693dbdd..7b051f96aa 100644
--- a/libgomp/libgomp.map
+++ b/libgomp/libgomp.map
@@ -107,6 +107,12 @@ OMP_3.0 {
omp_unset_nest_lock_;
} OMP_2.0;
+OMP_3.1 {
+ global:
+ omp_in_final;
+ omp_in_final_;
+} OMP_3.0;
+
GOMP_1.0 {
global:
GOMP_atomic_end;
@@ -173,3 +179,8 @@ GOMP_2.0 {
GOMP_loop_ull_static_next;
GOMP_loop_ull_static_start;
} GOMP_1.0;
+
+GOMP_3.0 {
+ global:
+ GOMP_taskyield;
+} GOMP_2.0;
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 58199437a5..29c078b668 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -116,7 +116,7 @@ arranges for automatic linking of the OpenMP runtime library
A complete description of all OpenMP directives accepted may be found in
the @uref{http://www.openmp.org, OpenMP Application Program Interface} manual,
-version 3.0.
+version 3.1.
@c ---------------------------------------------------------------------
@@ -127,7 +127,7 @@ version 3.0.
@chapter Runtime Library Routines
The runtime routines described here are defined by section 3 of the OpenMP
-specifications in version 3.0. The routines are structured in following
+specifications in version 3.1. The routines are structured in following
three parts:
Control threads, processors and the parallel environment.
@@ -147,6 +147,7 @@ Control threads, processors and the parallel environment.
* omp_get_thread_limit:: Maximum number of threads
* omp_get_thread_num:: Current thread ID
* omp_in_parallel:: Whether a parallel region is active
+* omp_in_final:: Whether in final or included task region
* omp_set_dynamic:: Enable/disable dynamic teams
* omp_set_max_active_levels:: Limits the number of active parallel regions
* omp_set_nested:: Enable/disable nested parallel regions
@@ -199,7 +200,7 @@ which enclose the calling call.
@ref{omp_get_level}, @ref{omp_get_max_active_levels}, @ref{omp_set_max_active_levels}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.19.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.19.
@end table
@@ -228,7 +229,7 @@ zero to @code{omp_get_level} -1 is returned; if @var{level} is
@ref{omp_get_level}, @ref{omp_get_thread_num}, @ref{omp_get_team_size}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.17.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.17.
@end table
@@ -260,7 +261,7 @@ disabled by default.
@ref{omp_set_dynamic}, @ref{OMP_DYNAMIC}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.8.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.8.
@end table
@@ -286,7 +287,7 @@ which enclose the calling call.
@ref{omp_get_active_level}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.16.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.16.
@end table
@@ -311,7 +312,7 @@ This function obtains the maximum allowed number of nested, active parallel regi
@ref{omp_set_max_active_levels}, @ref{omp_get_active_level}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.14.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.15.
@end table
@@ -337,7 +338,7 @@ that does not use the clause @code{num_threads}.
@ref{omp_set_num_threads}, @ref{omp_set_dynamic}, @ref{omp_get_thread_limit}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.3.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.3.
@end table
@@ -369,7 +370,7 @@ disabled by default.
@ref{omp_set_nested}, @ref{OMP_NESTED}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.10.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.10.
@end table
@@ -391,7 +392,7 @@ Returns the number of processors online.
@end multitable
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.5.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.5.
@end table
@@ -424,7 +425,7 @@ one thread per CPU online is used.
@ref{omp_get_max_threads}, @ref{omp_set_num_threads}, @ref{OMP_NUM_THREADS}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.2.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.2.
@end table
@@ -440,7 +441,7 @@ set to the value @code{omp_sched_static}, @code{omp_sched_dynamic},
@item @emph{C/C++}
@multitable @columnfractions .20 .80
-@item @emph{Prototype}: @tab @code{omp_schedule(omp_sched_t *kind, int *modifier);}
+@item @emph{Prototype}: @tab @code{void omp_schedule(omp_sched_t *kind, int *modifier);}
@end multitable
@item @emph{Fortran}:
@@ -454,7 +455,7 @@ set to the value @code{omp_sched_static}, @code{omp_sched_dynamic},
@ref{omp_set_schedule}, @ref{OMP_SCHEDULE}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.12.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.12.
@end table
@@ -484,7 +485,7 @@ to @code{omp_get_num_threads}.
@ref{omp_get_num_threads}, @ref{omp_get_level}, @ref{omp_get_ancestor_thread_num}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.18.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.18.
@end table
@@ -509,7 +510,7 @@ Return the maximum number of threads of the program.
@ref{omp_get_max_threads}, @ref{OMP_THREAD_LIMIT}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.13.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.13.
@end table
@@ -538,7 +539,7 @@ value of the master thread of a team is always 0.
@ref{omp_get_num_threads}, @ref{omp_get_ancestor_thread_num}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.4.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.4.
@end table
@@ -562,7 +563,30 @@ their language-specific counterparts.
@end multitable
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.6.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.6.
+@end table
+
+
+@node omp_in_final
+@section @code{omp_in_final} -- Whether in final or included task region
+@table @asis
+@item @emph{Description}:
+This function returns @code{true} if currently running in a final
+or included task region, @code{false} otherwise. Here, @code{true}
+and @code{false} represent their language-specific counterparts.
+
+@item @emph{C/C++}:
+@multitable @columnfractions .20 .80
+@item @emph{Prototype}: @tab @code{int omp_in_final(void);}
+@end multitable
+
+@item @emph{Fortran}:
+@multitable @columnfractions .20 .80
+@item @emph{Interface}: @tab @code{logical function omp_in_final()}
+@end multitable
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.20.
@end table
@@ -590,7 +614,7 @@ adjustment of team sizes and @code{false} disables it.
@ref{OMP_DYNAMIC}, @ref{omp_get_dynamic}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.7.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.7.
@end table
@@ -617,7 +641,7 @@ parallel regions.
@ref{omp_get_max_active_levels}, @ref{omp_get_active_level}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.14.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.14.
@end table
@@ -646,7 +670,7 @@ dynamic adjustment of team sizes and @code{false} disables it.
@ref{OMP_NESTED}, @ref{omp_get_nested}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.9.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.9.
@end table
@@ -674,7 +698,7 @@ argument of @code{omp_set_num_threads} shall be a positive integer.
@ref{OMP_NUM_THREADS}, @ref{omp_get_num_threads}, @ref{omp_get_max_threads}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.1.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.1.
@end table
@@ -692,7 +716,7 @@ For @code{omp_sched_auto} the @var{modifier} argument is ignored.
@item @emph{C/C++}
@multitable @columnfractions .20 .80
-@item @emph{Prototype}: @tab @code{int omp_set_schedule(omp_sched_t *kind, int *modifier);}
+@item @emph{Prototype}: @tab @code{void omp_set_schedule(omp_sched_t *kind, int *modifier);}
@end multitable
@item @emph{Fortran}:
@@ -707,7 +731,7 @@ For @code{omp_sched_auto} the @var{modifier} argument is ignored.
@ref{OMP_SCHEDULE}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.2.11.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.2.11.
@end table
@@ -734,7 +758,7 @@ an unlocked state.
@ref{omp_destroy_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.1.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.1.
@end table
@@ -763,7 +787,7 @@ a deadlock occurs.
@ref{omp_init_lock}, @ref{omp_test_lock}, @ref{omp_unset_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.3.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.3.
@end table
@@ -785,8 +809,7 @@ does not block if the lock is not available. This function returns
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
-@item @emph{Interface}: @tab @code{subroutine omp_test_lock(lock)}
-@item @tab @code{logical(omp_logical_kind) :: omp_test_lock}
+@item @emph{Interface}: @tab @code{logical function omp_test_lock(lock)}
@item @tab @code{integer(omp_lock_kind), intent(inout) :: lock}
@end multitable
@@ -794,7 +817,7 @@ does not block if the lock is not available. This function returns
@ref{omp_init_lock}, @ref{omp_set_lock}, @ref{omp_set_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.5.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.5.
@end table
@@ -807,7 +830,7 @@ A simple lock about to be unset must have been locked by @code{omp_set_lock}
or @code{omp_test_lock} before. In addition, the lock must be held by the
thread calling @code{omp_unset_lock}. Then, the lock becomes unlocked. If one
or more threads attempted to set the lock before, one of them is chosen to,
-again, set the lock for itself.
+again, set the lock to itself.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
@@ -824,7 +847,7 @@ again, set the lock for itself.
@ref{omp_set_lock}, @ref{omp_test_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.4.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.4.
@end table
@@ -851,7 +874,7 @@ in the unlocked state.
@ref{omp_init_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.2.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.2.
@end table
@@ -878,7 +901,7 @@ an unlocked state and the nesting count is set to zero.
@ref{omp_destroy_nest_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.1.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.1.
@end table
@@ -889,7 +912,7 @@ an unlocked state and the nesting count is set to zero.
Before setting a nested lock, the lock variable must be initialized by
@code{omp_init_nest_lock}. The calling thread is blocked until the lock
is available. If the lock is already held by the current thread, the
-nesting count for the lock in incremented.
+nesting count for the lock is incremented.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
@@ -906,7 +929,7 @@ nesting count for the lock in incremented.
@ref{omp_init_nest_lock}, @ref{omp_unset_nest_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.3.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.3.
@end table
@@ -928,8 +951,7 @@ is returned. Otherwise, the return value equals zero.
@item @emph{Fortran}:
@multitable @columnfractions .20 .80
-@item @emph{Interface}: @tab @code{integer function omp_test_nest_lock(lock)}
-@item @tab @code{integer(omp_integer_kind) :: omp_test_nest_lock}
+@item @emph{Interface}: @tab @code{logical function omp_test_nest_lock(lock)}
@item @tab @code{integer(omp_nest_lock_kind), intent(inout) :: lock}
@end multitable
@@ -938,7 +960,7 @@ is returned. Otherwise, the return value equals zero.
@ref{omp_init_lock}, @ref{omp_set_lock}, @ref{omp_set_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.5.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.5.
@end table
@@ -951,7 +973,7 @@ A nested lock about to be unset must have been locked by @code{omp_set_nested_lo
or @code{omp_test_nested_lock} before. In addition, the lock must be held by the
thread calling @code{omp_unset_nested_lock}. If the nesting count drops to zero, the
lock becomes unlocked. If one ore more threads attempted to set the lock before,
-one of them is chosen to, again, set the lock for itself.
+one of them is chosen to, again, set the lock to itself.
@item @emph{C/C++}:
@multitable @columnfractions .20 .80
@@ -968,7 +990,7 @@ one of them is chosen to, again, set the lock for itself.
@ref{omp_set_nest_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.4.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.4.
@end table
@@ -995,7 +1017,7 @@ in the unlocked state and its nesting count must equal zero.
@ref{omp_init_lock}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.3.2.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.3.2.
@end table
@@ -1021,7 +1043,7 @@ successive clock ticks.
@ref{omp_get_wtime}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.4.2.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.4.2.
@end table
@@ -1049,7 +1071,7 @@ guaranteed not to change during the execution of the program.
@ref{omp_get_wtick}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 3.4.1.
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 3.4.1.
@end table
@@ -1064,7 +1086,7 @@ guaranteed not to change during the execution of the program.
The variables @env{OMP_DYNAMIC}, @env{OMP_MAX_ACTIVE_LEVELS},
@env{OMP_NESTED}, @env{OMP_NUM_THREADS}, @env{OMP_SCHEDULE},
@env{OMP_STACKSIZE},@env{OMP_THREAD_LIMIT} and @env{OMP_WAIT_POLICY}
-are defined by section 4 of the OpenMP specifications in version 3.0,
+are defined by section 4 of the OpenMP specifications in version 3.1,
while @env{GOMP_CPU_AFFINITY} and @env{GOMP_STACKSIZE} are GNU
extensions.
@@ -1077,6 +1099,7 @@ extensions.
* OMP_SCHEDULE:: How threads are scheduled
* OMP_THREAD_LIMIT:: Set the maximum number of threads
* OMP_WAIT_POLICY:: How waiting threads are handled
+* OMP_PROC_BIND:: Whether theads may be moved between CPUs
* GOMP_CPU_AFFINITY:: Bind threads to specific CPUs
* GOMP_STACKSIZE:: Set default thread stack size
@end menu
@@ -1096,7 +1119,7 @@ disabled by default.
@ref{omp_set_dynamic}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 4.3
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 4.3
@end table
@@ -1107,14 +1130,14 @@ disabled by default.
@table @asis
@item @emph{Description}:
Specifies the initial value for the maximum number of nested parallel
-regions. The value of this variable shall be positive integer.
+regions. The value of this variable shall be a positive integer.
If undefined, the number of active levels is unlimited.
@item @emph{See also}:
@ref{omp_set_max_active_levels}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 4.7
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 4.8
@end table
@@ -1134,7 +1157,7 @@ regions are disabled by default.
@ref{omp_set_nested}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 4.4
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 4.5
@end table
@@ -1146,14 +1169,15 @@ regions are disabled by default.
@table @asis
@item @emph{Description}:
Specifies the default number of threads to use in parallel regions. The
-value of this variable shall be a positive integer. If undefined one thread
-per CPU is used.
+value of this variable shall be a comma-separated list of positive integers;
+the value specified the number of threads to use for the corresponding nested
+level. If undefined one thread per CPU is used.
@item @emph{See also}:
@ref{omp_set_num_threads}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 4.2
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 4.2
@end table
@@ -1174,7 +1198,7 @@ dynamic scheduling and a chunk size of 1 is used.
@ref{omp_set_schedule}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, sections 2.5.1 and 4.1
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, sections 2.5.1 and 4.1
@end table
@@ -1188,13 +1212,13 @@ Set the default thread stack size in kilobytes, unless the number
is suffixed by @code{B}, @code{K}, @code{M} or @code{G}, in which
case the size is, respectively, in bytes, kilobytes, megabytes
or gigabytes. This is different from @code{pthread_attr_setstacksize}
-which gets the number of bytes as an argument. If the stacksize cannot
+which gets the number of bytes as an argument. If the stack size cannot
be set due to system constraints, an error is reported and the initial
-stacksize is left unchanged. If undefined, the stack size is system
+stack size is left unchanged. If undefined, the stack size is system
dependent.
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, sections 4.5
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, sections 4.6
@end table
@@ -1213,7 +1237,7 @@ the number of threads is not limited.
@ref{omp_get_thread_limit}
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, section 4.8
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, section 4.9
@end table
@@ -1229,7 +1253,25 @@ power while waiting; while the value is @code{ACTIVE} specifies that
they should.
@item @emph{Reference}:
-@uref{http://www.openmp.org/, OpenMP specifications v3.0}, sections 4.6
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, sections 4.7
+@end table
+
+
+
+@node OMP_PROC_BIND
+@section @env{OMP_PROC_BIND} -- Whether theads may be moved between CPUs
+@cindex Environment Variable
+@table @asis
+@item @emph{Description}:
+Specifies whether threads may be moved between processors. If set to
+@code{true}, OpenMP theads should not be moved, if set to @code{false}
+they may be moved.
+
+@item @emph{See also}:
+@ref{GOMP_CPU_AFFINITY}
+
+@item @emph{Reference}:
+@uref{http://www.openmp.org/, OpenMP specifications v3.1}, sections 4.4
@end table
@@ -1258,6 +1300,9 @@ or disabled during the runtime of the application.
If this environment variable is omitted, the host system will handle the
assignment of threads to CPUs.
+
+@item @emph{See also}:
+@ref{OMP_PROC_BIND}
@end table
@@ -1270,8 +1315,8 @@ assignment of threads to CPUs.
@item @emph{Description}:
Set the default thread stack size in kilobytes. This is different from
@code{pthread_attr_setstacksize} which gets the number of bytes as an
-argument. If the stacksize cannot be set due to system constraints, an
-error is reported and the initial stacksize is left unchanged. If undefined,
+argument. If the stack size cannot be set due to system constraints, an
+error is reported and the initial stack size is left unchanged. If undefined,
the stack size is system dependent.
@item @emph{See also}:
diff --git a/libgomp/libgomp_g.h b/libgomp/libgomp_g.h
index 18f69bc1e3..8a7c31f0d2 100644
--- a/libgomp/libgomp_g.h
+++ b/libgomp/libgomp_g.h
@@ -158,11 +158,12 @@ extern void GOMP_ordered_end (void);
extern void GOMP_parallel_start (void (*) (void *), void *, unsigned);
extern void GOMP_parallel_end (void);
-/* team.c */
+/* task.c */
extern void GOMP_task (void (*) (void *), void *, void (*) (void *, void *),
long, long, bool, unsigned);
extern void GOMP_taskwait (void);
+extern void GOMP_taskyield (void);
/* sections.c */
diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in
index 0198b8fd7e..f2d7ba4e11 100644
--- a/libgomp/omp.h.in
+++ b/libgomp/omp.h.in
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -98,6 +98,8 @@ int omp_get_ancestor_thread_num (int) __GOMP_NOTHROW;
int omp_get_team_size (int) __GOMP_NOTHROW;
int omp_get_active_level (void) __GOMP_NOTHROW;
+int omp_in_final (void) __GOMP_NOTHROW;
+
#ifdef __cplusplus
}
#endif
diff --git a/libgomp/omp_lib.f90.in b/libgomp/omp_lib.f90.in
index 6b0b7aa26c..d00fa0551f 100644
--- a/libgomp/omp_lib.f90.in
+++ b/libgomp/omp_lib.f90.in
@@ -1,4 +1,4 @@
-! Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+! Copyright (C) 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
! Contributed by Jakub Jelinek <jakub@redhat.com>.
! This file is part of the GNU OpenMP Library (libgomp).
@@ -24,8 +24,6 @@
module omp_lib_kinds
implicit none
- integer, parameter :: omp_integer_kind = 4
- integer, parameter :: omp_logical_kind = 4
integer, parameter :: omp_lock_kind = @OMP_LOCK_KIND@
integer, parameter :: omp_nest_lock_kind = @OMP_NEST_LOCK_KIND@
integer, parameter :: omp_sched_kind = 4
@@ -34,7 +32,7 @@
module omp_lib
use omp_lib_kinds
implicit none
- integer, parameter :: openmp_version = 200805
+ integer, parameter :: openmp_version = 201107
integer (omp_sched_kind), parameter :: omp_sched_static = 1
integer (omp_sched_kind), parameter :: omp_sched_dynamic = 2
integer (omp_sched_kind), parameter :: omp_sched_guided = 3
@@ -126,28 +124,28 @@
interface
function omp_get_dynamic ()
use omp_lib_kinds
- logical (omp_logical_kind) :: omp_get_dynamic
+ logical (4) :: omp_get_dynamic
end function omp_get_dynamic
end interface
interface
function omp_get_nested ()
use omp_lib_kinds
- logical (omp_logical_kind) :: omp_get_nested
+ logical (4) :: omp_get_nested
end function omp_get_nested
end interface
interface
function omp_in_parallel ()
use omp_lib_kinds
- logical (omp_logical_kind) :: omp_in_parallel
+ logical (4) :: omp_in_parallel
end function omp_in_parallel
end interface
interface
function omp_test_lock (lock)
use omp_lib_kinds
- logical (omp_logical_kind) :: omp_test_lock
+ logical (4) :: omp_test_lock
integer (omp_lock_kind), intent (inout) :: lock
end function omp_test_lock
end interface
@@ -155,35 +153,35 @@
interface
function omp_get_max_threads ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_max_threads
+ integer (4) :: omp_get_max_threads
end function omp_get_max_threads
end interface
interface
function omp_get_num_procs ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_num_procs
+ integer (4) :: omp_get_num_procs
end function omp_get_num_procs
end interface
interface
function omp_get_num_threads ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_num_threads
+ integer (4) :: omp_get_num_threads
end function omp_get_num_threads
end interface
interface
function omp_get_thread_num ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_thread_num
+ integer (4) :: omp_get_thread_num
end function omp_get_thread_num
end interface
interface
function omp_test_nest_lock (lock)
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_test_nest_lock
+ integer (4) :: omp_test_nest_lock
integer (omp_nest_lock_kind), intent (inout) :: lock
end function omp_test_nest_lock
end interface
@@ -229,7 +227,7 @@
interface
function omp_get_thread_limit ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_thread_limit
+ integer (4) :: omp_get_thread_limit
end function omp_get_thread_limit
end interface
@@ -247,14 +245,14 @@
interface
function omp_get_max_active_levels ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_max_active_levels
+ integer (4) :: omp_get_max_active_levels
end function omp_get_max_active_levels
end interface
interface
function omp_get_level ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_level
+ integer (4) :: omp_get_level
end function omp_get_level
end interface
@@ -262,12 +260,12 @@
function omp_get_ancestor_thread_num (level)
use omp_lib_kinds
integer (4), intent (in) :: level
- integer (omp_integer_kind) :: omp_get_ancestor_thread_num
+ integer (4) :: omp_get_ancestor_thread_num
end function omp_get_ancestor_thread_num
function omp_get_ancestor_thread_num_8 (level)
use omp_lib_kinds
integer (8), intent (in) :: level
- integer (omp_integer_kind) :: omp_get_ancestor_thread_num_8
+ integer (4) :: omp_get_ancestor_thread_num_8
end function omp_get_ancestor_thread_num_8
end interface
@@ -275,20 +273,27 @@
function omp_get_team_size (level)
use omp_lib_kinds
integer (4), intent (in) :: level
- integer (omp_integer_kind) :: omp_get_team_size
+ integer (4) :: omp_get_team_size
end function omp_get_team_size
function omp_get_team_size_8 (level)
use omp_lib_kinds
integer (8), intent (in) :: level
- integer (omp_integer_kind) :: omp_get_team_size_8
+ integer (4) :: omp_get_team_size_8
end function omp_get_team_size_8
end interface
interface
function omp_get_active_level ()
use omp_lib_kinds
- integer (omp_integer_kind) :: omp_get_active_level
+ integer (4) :: omp_get_active_level
end function omp_get_active_level
end interface
+ interface
+ function omp_in_final ()
+ use omp_lib_kinds
+ logical (4) :: omp_in_final
+ end function omp_in_final
+ end interface
+
end module omp_lib
diff --git a/libgomp/omp_lib.h.in b/libgomp/omp_lib.h.in
index 2ff7a42fa8..c583ba3d24 100644
--- a/libgomp/omp_lib.h.in
+++ b/libgomp/omp_lib.h.in
@@ -1,4 +1,4 @@
-! Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+! Copyright (C) 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
! Contributed by Jakub Jelinek <jakub@redhat.com>.
! This file is part of the GNU OpenMP Library (libgomp).
@@ -23,16 +23,17 @@
! <http://www.gnu.org/licenses/>.
integer omp_lock_kind, omp_nest_lock_kind, openmp_version
- integer omp_sched_kind, omp_sched_static, omp_sched_dynamic
- integer omp_sched_guided, omp_sched_auto
parameter (omp_lock_kind = @OMP_LOCK_KIND@)
parameter (omp_nest_lock_kind = @OMP_NEST_LOCK_KIND@)
+ integer omp_sched_kind
parameter (omp_sched_kind = 4)
+ integer (omp_sched_kind) omp_sched_static, omp_sched_dynamic
+ integer (omp_sched_kind) omp_sched_guided, omp_sched_auto
parameter (omp_sched_static = 1)
parameter (omp_sched_dynamic = 2)
parameter (omp_sched_guided = 3)
parameter (omp_sched_auto = 4)
- parameter (openmp_version = 200805)
+ parameter (openmp_version = 201107)
external omp_init_lock, omp_init_nest_lock
external omp_destroy_lock, omp_destroy_nest_lock
@@ -64,3 +65,6 @@
integer(4) omp_get_thread_limit, omp_get_max_active_levels
integer(4) omp_get_level, omp_get_ancestor_thread_num
integer(4) omp_get_team_size, omp_get_active_level
+
+ external omp_in_final
+ logical(4) omp_in_final
diff --git a/libgomp/ordered.c b/libgomp/ordered.c
index e5673fe1c0..f84d52eb9f 100644
--- a/libgomp/ordered.c
+++ b/libgomp/ordered.c
@@ -207,8 +207,13 @@ gomp_ordered_sync (void)
post to our release semaphore. So the two cases are that we will
either win the race an momentarily block on the semaphore, or lose
the race and find the semaphore already unlocked and so not block.
- Either way we get correct results. */
+ Either way we get correct results.
+ However, there is an implicit flush on entry to an ordered region,
+ so we do need to have a barrier here. If we were taking a lock
+ this could be MEMMODEL_RELEASE since the acquire would be coverd
+ by the lock. */
+ __atomic_thread_fence (MEMMODEL_ACQ_REL);
if (ws->ordered_owner != thr->ts.team_id)
{
gomp_sem_wait (team->ordered_release[thr->ts.team_id]);
diff --git a/libgomp/task.c b/libgomp/task.c
index 95f163d53c..13e6605a99 100644
--- a/libgomp/task.c
+++ b/libgomp/task.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -41,6 +41,7 @@ gomp_init_task (struct gomp_task *task, struct gomp_task *parent_task,
task->kind = GOMP_TASK_IMPLICIT;
task->in_taskwait = false;
task->in_tied_task = false;
+ task->final_task = false;
task->children = NULL;
gomp_sem_init (&task->taskwait_sem, 0);
}
@@ -77,8 +78,7 @@ gomp_clear_parent (struct gomp_task *children)
void
GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
- long arg_size, long arg_align, bool if_clause,
- unsigned flags __attribute__((unused)))
+ long arg_size, long arg_align, bool if_clause, unsigned flags)
{
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr->ts.team;
@@ -95,12 +95,14 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
#endif
if (!if_clause || team == NULL
+ || (thr->task && thr->task->final_task)
|| team->task_count > 64 * team->nthreads)
{
struct gomp_task task;
gomp_init_task (&task, thr->task, gomp_icv (false));
task.kind = GOMP_TASK_IFFALSE;
+ task.final_task = (thr->task && thr->task->final_task) || (flags & 2);
if (thr->task)
task.in_tied_task = thr->task->in_tied_task;
thr->task = &task;
@@ -114,7 +116,16 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
}
else
fn (data);
- if (task.children)
+ /* Access to "children" is normally done inside a task_lock
+ mutex region, but the only way this particular task.children
+ can be set is if this thread's task work function (fn)
+ creates children. So since the setter is *this* thread, we
+ need no barriers here when testing for non-NULL. We can have
+ task.children set by the current thread then changed by a
+ child thread, but seeing a stale non-NULL value is not a
+ problem. Once past the task_lock acquisition, this thread
+ will see the real value of task.children. */
+ if (task.children != NULL)
{
gomp_mutex_lock (&team->task_lock);
gomp_clear_parent (task.children);
@@ -145,6 +156,7 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
task->fn = fn;
task->fn_data = arg;
task->in_tied_task = true;
+ task->final_task = (flags & 2) >> 1;
gomp_mutex_lock (&team->task_lock);
if (parent->children)
{
@@ -254,7 +266,13 @@ gomp_barrier_handle_tasks (gomp_barrier_state_t state)
parent->children = child_task->next_child;
else
{
- parent->children = NULL;
+ /* We access task->children in GOMP_taskwait
+ outside of the task lock mutex region, so
+ need a release barrier here to ensure memory
+ written by child_task->fn above is flushed
+ before the NULL is written. */
+ __atomic_store_n (&parent->children, NULL,
+ MEMMODEL_RELEASE);
if (parent->in_taskwait)
gomp_sem_post (&parent->taskwait_sem);
}
@@ -270,6 +288,7 @@ gomp_barrier_handle_tasks (gomp_barrier_state_t state)
gomp_team_barrier_done (&team->barrier, state);
gomp_mutex_unlock (&team->task_lock);
gomp_team_barrier_wake (&team->barrier, 0);
+ gomp_mutex_lock (&team->task_lock);
}
}
}
@@ -286,8 +305,16 @@ GOMP_taskwait (void)
struct gomp_task *child_task = NULL;
struct gomp_task *to_free = NULL;
- if (task == NULL || task->children == NULL)
+ /* The acquire barrier on load of task->children here synchronizes
+ with the write of a NULL in gomp_barrier_handle_tasks. It is
+ not necessary that we synchronize with other non-NULL writes at
+ this point, but we must ensure that all writes to memory by a
+ child thread task work function are seen before we exit from
+ GOMP_taskwait. */
+ if (task == NULL
+ || __atomic_load_n (&task->children, MEMMODEL_ACQUIRE) == NULL)
return;
+
gomp_mutex_lock (&team->task_lock);
while (1)
{
@@ -362,3 +389,20 @@ GOMP_taskwait (void)
}
}
}
+
+/* Called when encountering a taskyield directive. */
+
+void
+GOMP_taskyield (void)
+{
+ /* Nothing at the moment. */
+}
+
+int
+omp_in_final (void)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ return thr->task && thr->task->final_task;
+}
+
+ialias (omp_in_final)
diff --git a/libgomp/team.c b/libgomp/team.c
index 44ffd56095..110bd47116 100644
--- a/libgomp/team.c
+++ b/libgomp/team.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2011, 2012
+ Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp).
@@ -231,6 +232,15 @@ gomp_free_thread (void *arg __attribute__((unused)))
gomp_barrier_wait (&pool->threads_dock);
/* Now it is safe to destroy the barrier and free the pool. */
gomp_barrier_destroy (&pool->threads_dock);
+
+#ifdef HAVE_SYNC_BUILTINS
+ __sync_fetch_and_add (&gomp_managed_threads,
+ 1L - pool->threads_used);
+#else
+ gomp_mutex_lock (&gomp_remaining_threads_lock);
+ gomp_managed_threads -= pool->threads_used - 1L;
+ gomp_mutex_unlock (&gomp_remaining_threads_lock);
+#endif
}
free (pool->threads);
if (pool->last_team)
@@ -260,6 +270,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
struct gomp_thread_pool *pool;
unsigned i, n, old_threads_used = 0;
pthread_attr_t thread_attr, *attr;
+ unsigned long nthreads_var;
thr = gomp_thread ();
nested = thr->ts.team != NULL;
@@ -289,7 +300,12 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
#endif
thr->ts.static_trip = 0;
thr->task = &team->implicit_task[0];
+ nthreads_var = icv->nthreads_var;
+ if (__builtin_expect (gomp_nthreads_var_list != NULL, 0)
+ && thr->ts.level < gomp_nthreads_var_list_len)
+ nthreads_var = gomp_nthreads_var_list[thr->ts.level];
gomp_init_task (thr->task, task, icv);
+ team->implicit_task[0].icv.nthreads_var = nthreads_var;
if (nthreads == 1)
return;
@@ -342,6 +358,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
nthr->ts.static_trip = 0;
nthr->task = &team->implicit_task[i];
gomp_init_task (nthr->task, task, icv);
+ team->implicit_task[i].icv.nthreads_var = nthreads_var;
nthr->fn = fn;
nthr->data = data;
team->ordered_release[i] = &nthr->release;
@@ -413,6 +430,7 @@ gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
start_data->ts.static_trip = 0;
start_data->task = &team->implicit_task[i];
gomp_init_task (start_data->task, task, icv);
+ team->implicit_task[i].icv.nthreads_var = nthreads_var;
start_data->thread_pool = pool;
start_data->nested = nested;
diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp
index 976543dab1..a75e22f789 100644
--- a/libgomp/testsuite/lib/libgomp.exp
+++ b/libgomp/testsuite/lib/libgomp.exp
@@ -140,7 +140,7 @@ proc libgomp_init { args } {
# We use atomic operations in the testcases to validate results.
if { ([istarget i?86-*-*] || [istarget x86_64-*-*])
- && [check_effective_target_ilp32] } {
+ && [check_effective_target_ia32] } {
lappend ALWAYS_CFLAGS "additional_flags=-march=i486"
}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-2.C b/libgomp/testsuite/libgomp.c++/atomic-2.C
new file mode 100644
index 0000000000..e7217590a3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-2.C
@@ -0,0 +1,156 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+int x = 6;
+float y;
+
+int
+main (void)
+{
+ int v;
+ float f;
+ #pragma omp atomic read
+ v = x;
+ if (v != 6)
+ abort ();
+ #pragma omp atomic write
+ x = 17;
+ #pragma omp atomic read
+ v = x;
+ if (v != 17)
+ abort ();
+ #pragma omp atomic update
+ x++;
+ #pragma omp atomic read
+ v = x;
+ if (v != 18)
+ abort ();
+ #pragma omp atomic capture
+ v = x++;
+ if (v != 18)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 19)
+ abort ();
+ #pragma omp atomic capture
+ v = ++x;
+ if (v != 20)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 20)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x *= 3; }
+ if (v != 20)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 60)
+ abort ();
+ #pragma omp atomic capture
+ {
+ x |= 2;
+ v = x;
+ }
+ if (v != 62)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 62)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x++; }
+ if (v != 62)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; ++x; }
+ if (v != 63)
+ abort ();
+ #pragma omp atomic capture
+ {
+ ++x;
+ v = x;
+ }
+ if (v != 65)
+ abort ();
+#pragma omp atomic capture
+{x++;v=x;}if (v != 66)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 66)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x--; }
+ if (v != 66)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; --x; }
+ if (v != 65)
+ abort ();
+ #pragma omp atomic capture
+ {
+ --x;
+ v = x;
+ }
+ if (v != 63)
+ abort ();
+ #pragma omp atomic capture
+ { x--; v = x; } if (v != 62)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 62)
+ abort ();
+ #pragma omp atomic write
+ y = 17.5f;
+ #pragma omp atomic read
+ f = y;
+ if (f != 17.5)
+ abort ();
+ #pragma omp atomic update
+ y *= 2.0f;
+ #pragma omp atomic read
+ f = y;
+ if (y != 35.0)
+ abort ();
+ #pragma omp atomic capture
+ f = y *= 2.0f;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic capture
+ f = y++;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 71.0)
+ abort ();
+ #pragma omp atomic capture
+ f = --y;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic capture
+ { f = y; y /= 2.0f; }
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 35.0)
+ abort ();
+ #pragma omp atomic capture
+ { y /= 2.0f; f = y; }
+ if (f != 17.5)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 17.5)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-3.C b/libgomp/testsuite/libgomp.c++/atomic-3.C
new file mode 100644
index 0000000000..660b260e19
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-3.C
@@ -0,0 +1,74 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+bool v, x1, x2, x3, x4, x5, x6;
+
+void
+foo ()
+{
+ #pragma omp atomic capture
+ v = ++x1;
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ v = x2++;
+ if (v)
+ abort ();
+ #pragma omp atomic read
+ v = x3;
+ if (!v)
+ abort ();
+ #pragma omp atomic read
+ v = x4;
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x5; x5 |= 1; }
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ { x6 |= 1; v = x6; }
+ if (!v)
+ abort ();
+}
+
+void
+bar ()
+{
+ #pragma omp atomic write
+ x1 = false;
+ #pragma omp atomic write
+ x2 = false;
+ #pragma omp atomic capture
+ { ++x1; v = x1; }
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x2; x2++; }
+ if (v)
+ abort ();
+ #pragma omp atomic write
+ x1 = false;
+ #pragma omp atomic write
+ x2 = false;
+ #pragma omp atomic capture
+ { x1++; v = x1; }
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x2; ++x2; }
+ if (v)
+ abort ();
+}
+
+int
+main ()
+{
+ #pragma omp atomic write
+ x3 = true;
+ #pragma omp atomic write
+ x4 = true;
+ foo ();
+ bar ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-4.C b/libgomp/testsuite/libgomp.c++/atomic-4.C
new file mode 100644
index 0000000000..82439df2bb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-4.C
@@ -0,0 +1,166 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+template <typename T, typename T2>
+int
+foo (void)
+{
+ extern T x;
+ extern T2 y;
+ T v;
+ T2 f;
+ #pragma omp atomic read
+ v = x;
+ if (v != 6)
+ abort ();
+ #pragma omp atomic write
+ x = 17;
+ #pragma omp atomic read
+ v = x;
+ if (v != 17)
+ abort ();
+ #pragma omp atomic update
+ x++;
+ #pragma omp atomic read
+ v = x;
+ if (v != 18)
+ abort ();
+ #pragma omp atomic capture
+ v = x++;
+ if (v != 18)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 19)
+ abort ();
+ #pragma omp atomic capture
+ v = ++x;
+ if (v != 20)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 20)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x *= 3; }
+ if (v != 20)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 60)
+ abort ();
+ #pragma omp atomic capture
+ {
+ x |= 2;
+ v = x;
+ }
+ if (v != 62)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 62)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x++; }
+ if (v != 62)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; ++x; }
+ if (v != 63)
+ abort ();
+ #pragma omp atomic capture
+ {
+ ++x;
+ v = x;
+ }
+ if (v != 65)
+ abort ();
+#pragma omp atomic capture
+{x++;v=x;}if (v != 66)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 66)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x--; }
+ if (v != 66)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; --x; }
+ if (v != 65)
+ abort ();
+ #pragma omp atomic capture
+ {
+ --x;
+ v = x;
+ }
+ if (v != 63)
+ abort ();
+ #pragma omp atomic capture
+ { x--; v = x; } if (v != 62)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 62)
+ abort ();
+ #pragma omp atomic write
+ y = 17.5f;
+ #pragma omp atomic read
+ f = y;
+ if (f != 17.5)
+ abort ();
+ #pragma omp atomic update
+ y *= 2.0f;
+ #pragma omp atomic read
+ f = y;
+ if (y != 35.0)
+ abort ();
+ #pragma omp atomic capture
+ f = y *= 2.0f;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic capture
+ f = y++;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 71.0)
+ abort ();
+ #pragma omp atomic capture
+ f = --y;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic capture
+ { f = y; y /= 2.0f; }
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 35.0)
+ abort ();
+ #pragma omp atomic capture
+ { y /= 2.0f; f = y; }
+ if (f != 17.5)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 17.5)
+ abort ();
+ return 0;
+}
+
+int x = 6;
+float y;
+
+int
+main ()
+{
+ foo <int, float> ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-5.C b/libgomp/testsuite/libgomp.c++/atomic-5.C
new file mode 100644
index 0000000000..e9bd2cc1cb
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-5.C
@@ -0,0 +1,79 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+
+template <typename T>
+void
+foo ()
+{
+ extern T v, x1, x2, x3, x4, x5, x6;
+ #pragma omp atomic capture
+ v = ++x1;
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ v = x2++;
+ if (v)
+ abort ();
+ #pragma omp atomic read
+ v = x3;
+ if (!v)
+ abort ();
+ #pragma omp atomic read
+ v = x4;
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x5; x5 |= 1; }
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ { x6 |= 1; v = x6; }
+ if (!v)
+ abort ();
+}
+
+template <typename T>
+void
+bar ()
+{
+ extern T v, x1, x2;
+ #pragma omp atomic write
+ x1 = false;
+ #pragma omp atomic write
+ x2 = false;
+ #pragma omp atomic capture
+ { ++x1; v = x1; }
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x2; x2++; }
+ if (v)
+ abort ();
+ #pragma omp atomic write
+ x1 = false;
+ #pragma omp atomic write
+ x2 = false;
+ #pragma omp atomic capture
+ { x1++; v = x1; }
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x2; ++x2; }
+ if (v)
+ abort ();
+}
+
+bool v, x1, x2, x3, x4, x5, x6;
+
+int
+main ()
+{
+ #pragma omp atomic write
+ x3 = true;
+ #pragma omp atomic write
+ x4 = true;
+ foo <bool> ();
+ bar <bool> ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-6.C b/libgomp/testsuite/libgomp.c++/atomic-6.C
new file mode 100644
index 0000000000..d7d0eb981f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-6.C
@@ -0,0 +1,58 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+long long l, m;
+int i, j;
+
+void
+foo (void)
+{
+ #pragma omp atomic read
+ i = l;
+ #pragma omp atomic read
+ m = j;
+ if (i != 77 || m != 88)
+ abort ();
+ #pragma omp atomic write
+ l = 1 + i + 6 * 1;
+ #pragma omp atomic write
+ j = 170 - 170 + m + 1 * 7;
+ #pragma omp atomic capture
+ i = l += 4;
+ #pragma omp atomic capture
+ m = j += 4;
+ if (i != 88 || m != 99)
+ abort ();
+ #pragma omp atomic capture
+ {
+ i = l;
+ l += 4;
+ }
+ #pragma omp atomic capture
+ {
+ m = j;
+ j += 4;
+ }
+ if (i != 88 || m != 99)
+ abort ();
+ #pragma omp atomic capture
+ {
+ l += 4;
+ i = l;
+ }
+ #pragma omp atomic capture
+ {
+ j += 4;
+ m = j;
+ }
+ if (i != 96 || m != 107)
+ abort ();
+}
+
+int
+main ()
+{
+ l = 77;
+ j = 88;
+ foo ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-7.C b/libgomp/testsuite/libgomp.c++/atomic-7.C
new file mode 100644
index 0000000000..fe1b4d7aa9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-7.C
@@ -0,0 +1,63 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+
+template <typename S, typename T>
+void
+foo (void)
+{
+ extern S l, m;
+ extern T i, j;
+
+ #pragma omp atomic read
+ i = l;
+ #pragma omp atomic read
+ m = j;
+ if (i != 77 || m != 88)
+ abort ();
+ #pragma omp atomic write
+ l = 1 + i + 6 * 1;
+ #pragma omp atomic write
+ j = 170 - 170 + m + 1 * 7;
+ #pragma omp atomic capture
+ i = l += 4;
+ #pragma omp atomic capture
+ m = j += 4;
+ if (i != 88 || m != 99)
+ abort ();
+ #pragma omp atomic capture
+ {
+ i = l;
+ l += 4;
+ }
+ #pragma omp atomic capture
+ {
+ m = j;
+ j += 4;
+ }
+ if (i != 88 || m != 99)
+ abort ();
+ #pragma omp atomic capture
+ {
+ l += 4;
+ i = l;
+ }
+ #pragma omp atomic capture
+ {
+ j += 4;
+ m = j;
+ }
+ if (i != 96 || m != 107)
+ abort ();
+}
+
+long long l, m;
+int i, j;
+
+int
+main ()
+{
+ l = 77;
+ j = 88;
+ foo <long long, int> ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-8.C b/libgomp/testsuite/libgomp.c++/atomic-8.C
new file mode 100644
index 0000000000..744b3409c9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-8.C
@@ -0,0 +1,137 @@
+// { dg-do run }
+
+extern "C" void abort ();
+int x = 6, cnt;
+
+int
+foo ()
+{
+ return cnt++;
+}
+
+int
+main ()
+{
+ int v, *p;
+ #pragma omp atomic update
+ x = x + 7;
+ #pragma omp atomic
+ x = x + 7 + 6;
+ #pragma omp atomic update
+ x = x + 2 * 3;
+ #pragma omp atomic
+ x = x * (2 - 1);
+ #pragma omp atomic read
+ v = x;
+ if (v != 32)
+ abort ();
+ #pragma omp atomic write
+ x = 0;
+ #pragma omp atomic capture
+ {
+ v = x;
+ x = x | 1 ^ 2;
+ }
+ if (v != 0)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = x;
+ x = x | 4 | 2;
+ }
+ if (v != 3)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 7)
+ abort ();
+ #pragma omp atomic capture
+ {
+ x = x ^ 6 & 2;
+ v = x;
+ }
+ if (v != 5)
+ abort ();
+ #pragma omp atomic capture
+ { x = x - (6 + 4); v = x; }
+ if (v != -5)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x = x - (1 | 2); }
+ if (v != -5)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != -8)
+ abort ();
+ #pragma omp atomic
+ x = x * -4 / 2;
+ #pragma omp atomic read
+ v = x;
+ if (v != 16)
+ abort ();
+ p = &x;
+ #pragma omp atomic update
+ p[foo (), 0] = p[foo (), 0] - 16;
+ #pragma omp atomic read
+ v = x;
+ if (cnt != 2 || v != 0)
+ abort ();
+ #pragma omp atomic capture
+ {
+ p[foo (), 0] += 6;
+ v = p[foo (), 0];
+ }
+ if (cnt != 4 || v != 6)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = p[foo (), 0];
+ p[foo (), 0] += 6;
+ }
+ if (cnt != 6 || v != 6)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12)
+ abort ();
+ #pragma omp atomic capture
+ {
+ p[foo (), 0] = p[foo (), 0] + 6;
+ v = p[foo (), 0];
+ }
+ if (cnt != 9 || v != 18)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = p[foo (), 0];
+ p[foo (), 0] = p[foo (), 0] + 6;
+ }
+ if (cnt != 12 || v != 18)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 24)
+ abort ();
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; p[foo (), 0]++; }
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; ++p[foo (), 0]; }
+ #pragma omp atomic capture
+ { p[foo (), 0]++; v = p[foo (), 0]; }
+ #pragma omp atomic capture
+ { ++p[foo (), 0]; v = p[foo (), 0]; }
+ if (cnt != 20 || v != 28)
+ abort ();
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; p[foo (), 0]--; }
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; --p[foo (), 0]; }
+ #pragma omp atomic capture
+ { p[foo (), 0]--; v = p[foo (), 0]; }
+ #pragma omp atomic capture
+ { --p[foo (), 0]; v = p[foo (), 0]; }
+ if (cnt != 28 || v != 24)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/atomic-9.C b/libgomp/testsuite/libgomp.c++/atomic-9.C
new file mode 100644
index 0000000000..ece1bf3f02
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/atomic-9.C
@@ -0,0 +1,148 @@
+// { dg-do run }
+
+extern "C" void abort ();
+
+int cnt;
+
+int
+foo ()
+{
+ return cnt++;
+}
+
+template <typename T>
+void
+bar ()
+{
+ extern T x;
+ T v, *p;
+ #pragma omp atomic update
+ x = x + 7;
+ #pragma omp atomic
+ x = x + 7 + 6;
+ #pragma omp atomic update
+ x = x + 2 * 3;
+ #pragma omp atomic
+ x = x * (2 - 1);
+ #pragma omp atomic read
+ v = x;
+ if (v != 32)
+ abort ();
+ #pragma omp atomic write
+ x = 0;
+ #pragma omp atomic capture
+ {
+ v = x;
+ x = x | 1 ^ 2;
+ }
+ if (v != 0)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = x;
+ x = x | 4 | 2;
+ }
+ if (v != 3)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 7)
+ abort ();
+ #pragma omp atomic capture
+ {
+ x = x ^ 6 & 2;
+ v = x;
+ }
+ if (v != 5)
+ abort ();
+ #pragma omp atomic capture
+ { x = x - (6 + 4); v = x; }
+ if (v != -5)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x = x - (1 | 2); }
+ if (v != -5)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != -8)
+ abort ();
+ #pragma omp atomic
+ x = x * -4 / 2;
+ #pragma omp atomic read
+ v = x;
+ if (v != 16)
+ abort ();
+ p = &x;
+ #pragma omp atomic update
+ p[foo (), 0] = p[foo (), 0] - 16;
+ #pragma omp atomic read
+ v = x;
+ if (cnt != 2 || v != 0)
+ abort ();
+ #pragma omp atomic capture
+ {
+ p[foo (), 0] += 6;
+ v = p[foo (), 0];
+ }
+ if (cnt != 4 || v != 6)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = p[foo (), 0];
+ p[foo (), 0] += 6;
+ }
+ if (cnt != 6 || v != 6)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12)
+ abort ();
+ #pragma omp atomic capture
+ {
+ p[foo (), 0] = p[foo (), 0] + 6;
+ v = p[foo (), 0];
+ }
+ if (cnt != 9 || v != 18)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = p[foo (), 0];
+ p[foo (), 0] = p[foo (), 0] + 6;
+ }
+ if (cnt != 12 || v != 18)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 24)
+ abort ();
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; p[foo (), 0]++; }
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; ++p[foo (), 0]; }
+ #pragma omp atomic capture
+ { p[foo (), 0]++; v = p[foo (), 0]; }
+ #pragma omp atomic capture
+ { ++p[foo (), 0]; v = p[foo (), 0]; }
+ if (cnt != 20 || v != 28)
+ abort ();
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; p[foo (), 0]--; }
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; --p[foo (), 0]; }
+ #pragma omp atomic capture
+ { p[foo (), 0]--; v = p[foo (), 0]; }
+ #pragma omp atomic capture
+ { --p[foo (), 0]; v = p[foo (), 0]; }
+ if (cnt != 28 || v != 24)
+ abort ();
+}
+
+int x = 6;
+
+int
+main ()
+{
+ bar <int> ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/pr56217.C b/libgomp/testsuite/libgomp.c++/pr56217.C
new file mode 100644
index 0000000000..19da918535
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/pr56217.C
@@ -0,0 +1,36 @@
+// PR middle-end/56217
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+extern "C" void abort ();
+
+template <typename T>
+struct ptr {
+ T *p;
+ ptr () : p () {}
+ ptr (ptr &) = delete;
+ ptr (ptr &&o) : p(o) {}
+ operator T * () { return p; }
+};
+
+int a[6] = { 100, 101, 102, 103, 104, 105 };
+
+static ptr<int>
+f ()
+{
+ ptr<int> pt;
+ #pragma omp task shared (pt)
+ pt.p = a + 2;
+ #pragma omp taskwait
+ return pt;
+}
+
+int
+main ()
+{
+ ptr<int> pt;
+ #pragma omp parallel
+ #pragma omp single
+ if (f () != a + 2 || *f () != 102)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c++/reduction-4.C b/libgomp/testsuite/libgomp.c++/reduction-4.C
new file mode 100644
index 0000000000..e7ef8a13c2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/reduction-4.C
@@ -0,0 +1,54 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+
+template <typename I, typename F>
+void
+foo ()
+{
+ I j = -10000;
+ F f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+}
+
+int
+main ()
+{
+ int j = -10000;
+ float f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+ foo <int, float> ();
+ foo <long, double> ();
+ foo <long long, long double> ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/task-8.C b/libgomp/testsuite/libgomp.c++/task-8.C
new file mode 100644
index 0000000000..b523c4d225
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/task-8.C
@@ -0,0 +1,44 @@
+// { dg-do run }
+
+#include <omp.h>
+#include <cstdlib>
+
+int errval;
+
+int
+main ()
+{
+ int e;
+#pragma omp parallel shared(errval)
+ {
+ if (omp_in_final ())
+ #pragma omp atomic write
+ errval = 1;
+ #pragma omp task if (0) shared(errval)
+ {
+ if (omp_in_final ())
+ #pragma omp atomic write
+ errval = 1;
+ #pragma omp task if (0) shared(errval)
+ if (omp_in_final ())
+ #pragma omp atomic write
+ errval = 1;
+ }
+ #pragma omp task final (1) shared(errval)
+ {
+ if (!omp_in_final ())
+ #pragma omp atomic write
+ errval = 1;
+ #pragma omp taskyield
+ #pragma omp taskwait
+ #pragma omp task shared(errval)
+ if (!omp_in_final ())
+ #pragma omp atomic write
+ errval = 1;
+ }
+ }
+ #pragma omp atomic read
+ e = errval;
+ if (e)
+ abort ();
+}
diff --git a/libgomp/testsuite/libgomp.c/atomic-1.c b/libgomp/testsuite/libgomp.c/atomic-1.c
index b2be8f022e..4725b7de25 100644
--- a/libgomp/testsuite/libgomp.c/atomic-1.c
+++ b/libgomp/testsuite/libgomp.c/atomic-1.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O2 -march=pentium" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-O2 -march=pentium" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
#ifdef __i386__
#include "cpuid.h"
diff --git a/libgomp/testsuite/libgomp.c/atomic-11.c b/libgomp/testsuite/libgomp.c/atomic-11.c
new file mode 100644
index 0000000000..d1d6ca53a3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/atomic-11.c
@@ -0,0 +1,156 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int x = 6;
+float y;
+
+int
+main (void)
+{
+ int v;
+ float f;
+ #pragma omp atomic read
+ v = x;
+ if (v != 6)
+ abort ();
+ #pragma omp atomic write
+ x = 17;
+ #pragma omp atomic read
+ v = x;
+ if (v != 17)
+ abort ();
+ #pragma omp atomic update
+ x++;
+ #pragma omp atomic read
+ v = x;
+ if (v != 18)
+ abort ();
+ #pragma omp atomic capture
+ v = x++;
+ if (v != 18)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 19)
+ abort ();
+ #pragma omp atomic capture
+ v = ++x;
+ if (v != 20)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 20)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x *= 3; }
+ if (v != 20)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 60)
+ abort ();
+ #pragma omp atomic capture
+ {
+ x |= 2;
+ v = x;
+ }
+ if (v != 62)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 62)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x++; }
+ if (v != 62)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; ++x; }
+ if (v != 63)
+ abort ();
+ #pragma omp atomic capture
+ {
+ ++x;
+ v = x;
+ }
+ if (v != 65)
+ abort ();
+#pragma omp atomic capture
+{x++;v=x;}if (v != 66)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 66)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x--; }
+ if (v != 66)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; --x; }
+ if (v != 65)
+ abort ();
+ #pragma omp atomic capture
+ {
+ --x;
+ v = x;
+ }
+ if (v != 63)
+ abort ();
+ #pragma omp atomic capture
+ { x--; v = x; } if (v != 62)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 62)
+ abort ();
+ #pragma omp atomic write
+ y = 17.5f;
+ #pragma omp atomic read
+ f = y;
+ if (f != 17.5)
+ abort ();
+ #pragma omp atomic update
+ y *= 2.0f;
+ #pragma omp atomic read
+ f = y;
+ if (y != 35.0)
+ abort ();
+ #pragma omp atomic capture
+ f = y *= 2.0f;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic capture
+ f = y++;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 71.0)
+ abort ();
+ #pragma omp atomic capture
+ f = --y;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic capture
+ { f = y; y /= 2.0f; }
+ if (f != 70.0)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 35.0)
+ abort ();
+ #pragma omp atomic capture
+ { y /= 2.0f; f = y; }
+ if (f != 17.5)
+ abort ();
+ #pragma omp atomic read
+ f = y;
+ if (f != 17.5)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/atomic-12.c b/libgomp/testsuite/libgomp.c/atomic-12.c
new file mode 100644
index 0000000000..a9fe560653
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/atomic-12.c
@@ -0,0 +1,98 @@
+/* { dg-do run } */
+
+extern void abort (void);
+_Bool v, x1, x2, x3, x4, x5, x6;
+
+void
+foo (void)
+{
+ #pragma omp atomic capture
+ v = ++x1;
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ v = x2++;
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ v = --x3;
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ v = x4--;
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x5; x5 |= 1; }
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ { x6 |= 1; v = x6; }
+ if (!v)
+ abort ();
+}
+
+void
+bar (void)
+{
+ #pragma omp atomic write
+ x1 = 0;
+ #pragma omp atomic write
+ x2 = 0;
+ #pragma omp atomic write
+ x3 = 1;
+ #pragma omp atomic write
+ x4 = 1;
+ #pragma omp atomic capture
+ { ++x1; v = x1; }
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x2; x2++; }
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ { --x3; v = x3; }
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x4; x4--; }
+ if (!v)
+ abort ();
+ #pragma omp atomic write
+ x1 = 0;
+ #pragma omp atomic write
+ x2 = 0;
+ #pragma omp atomic write
+ x3 = 1;
+ #pragma omp atomic write
+ x4 = 1;
+ #pragma omp atomic capture
+ { x1++; v = x1; }
+ if (!v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x2; ++x2; }
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ { x3--; v = x3; }
+ if (v)
+ abort ();
+ #pragma omp atomic capture
+ { v = x4; --x4; }
+ if (!v)
+ abort ();
+}
+
+int
+main ()
+{
+ #pragma omp atomic write
+ x3 = 1;
+ #pragma omp atomic write
+ x4 = 1;
+ foo ();
+ bar ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/atomic-13.c b/libgomp/testsuite/libgomp.c/atomic-13.c
new file mode 100644
index 0000000000..52800fc719
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/atomic-13.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+
+extern void abort (void);
+long long l, m;
+int i, j;
+
+void
+foo (void)
+{
+ #pragma omp atomic read
+ i = l;
+ #pragma omp atomic read
+ m = j;
+ if (i != 77 || m != 88)
+ abort ();
+ #pragma omp atomic write
+ l = 1 + i + 6 * 1;
+ #pragma omp atomic write
+ j = 170 - 170 + m + 1 * 7;
+ #pragma omp atomic capture
+ i = l += 4;
+ #pragma omp atomic capture
+ m = j += 4;
+ if (i != 88 || m != 99)
+ abort ();
+ #pragma omp atomic capture
+ {
+ i = l;
+ l += 4;
+ }
+ #pragma omp atomic capture
+ {
+ m = j;
+ j += 4;
+ }
+ if (i != 88 || m != 99)
+ abort ();
+ #pragma omp atomic capture
+ {
+ l += 4;
+ i = l;
+ }
+ #pragma omp atomic capture
+ {
+ j += 4;
+ m = j;
+ }
+ if (i != 96 || m != 107)
+ abort ();
+}
+
+int
+main ()
+{
+ l = 77;
+ j = 88;
+ foo ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/atomic-14.c b/libgomp/testsuite/libgomp.c/atomic-14.c
new file mode 100644
index 0000000000..593665046c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/atomic-14.c
@@ -0,0 +1,137 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int x = 6, cnt;
+
+int
+foo (void)
+{
+ return cnt++;
+}
+
+int
+main ()
+{
+ int v, *p;
+ #pragma omp atomic update
+ x = x + 7;
+ #pragma omp atomic
+ x = x + 7 + 6;
+ #pragma omp atomic update
+ x = x + 2 * 3;
+ #pragma omp atomic
+ x = x * (2 - 1);
+ #pragma omp atomic read
+ v = x;
+ if (v != 32)
+ abort ();
+ #pragma omp atomic write
+ x = 0;
+ #pragma omp atomic capture
+ {
+ v = x;
+ x = x | 1 ^ 2;
+ }
+ if (v != 0)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = x;
+ x = x | 4 | 2;
+ }
+ if (v != 3)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 7)
+ abort ();
+ #pragma omp atomic capture
+ {
+ x = x ^ 6 & 2;
+ v = x;
+ }
+ if (v != 5)
+ abort ();
+ #pragma omp atomic capture
+ { x = x - (6 + 4); v = x; }
+ if (v != -5)
+ abort ();
+ #pragma omp atomic capture
+ { v = x; x = x - (1 | 2); }
+ if (v != -5)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != -8)
+ abort ();
+ #pragma omp atomic
+ x = x * -4 / 2;
+ #pragma omp atomic read
+ v = x;
+ if (v != 16)
+ abort ();
+ p = &x;
+ #pragma omp atomic update
+ p[foo (), 0] = p[foo (), 0] - 16;
+ #pragma omp atomic read
+ v = x;
+ if (cnt != 2 || v != 0)
+ abort ();
+ #pragma omp atomic capture
+ {
+ p[foo (), 0] += 6;
+ v = p[foo (), 0];
+ }
+ if (cnt != 4 || v != 6)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = p[foo (), 0];
+ p[foo (), 0] += 6;
+ }
+ if (cnt != 6 || v != 6)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 12)
+ abort ();
+ #pragma omp atomic capture
+ {
+ p[foo (), 0] = p[foo (), 0] + 6;
+ v = p[foo (), 0];
+ }
+ if (cnt != 9 || v != 18)
+ abort ();
+ #pragma omp atomic capture
+ {
+ v = p[foo (), 0];
+ p[foo (), 0] = p[foo (), 0] + 6;
+ }
+ if (cnt != 12 || v != 18)
+ abort ();
+ #pragma omp atomic read
+ v = x;
+ if (v != 24)
+ abort ();
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; p[foo (), 0]++; }
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; ++p[foo (), 0]; }
+ #pragma omp atomic capture
+ { p[foo (), 0]++; v = p[foo (), 0]; }
+ #pragma omp atomic capture
+ { ++p[foo (), 0]; v = p[foo (), 0]; }
+ if (cnt != 20 || v != 28)
+ abort ();
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; p[foo (), 0]--; }
+ #pragma omp atomic capture
+ { v = p[foo (), 0]; --p[foo (), 0]; }
+ #pragma omp atomic capture
+ { p[foo (), 0]--; v = p[foo (), 0]; }
+ #pragma omp atomic capture
+ { --p[foo (), 0]; v = p[foo (), 0]; }
+ if (cnt != 28 || v != 24)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/atomic-6.c b/libgomp/testsuite/libgomp.c/atomic-6.c
index 59baf7dd3e..f8ab75e6a8 100644
--- a/libgomp/testsuite/libgomp.c/atomic-6.c
+++ b/libgomp/testsuite/libgomp.c/atomic-6.c
@@ -1,7 +1,7 @@
/* PR middle-end/36106 */
/* { dg-options "-O2" } */
/* { dg-options "-O2 -mieee" { target alpha*-*-* } } */
-/* { dg-options "-O2 -march=i586" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+/* { dg-options "-O2 -march=i586" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
#ifdef __i386__
# include "cpuid.h"
diff --git a/libgomp/testsuite/libgomp.c/pr26943-2.c b/libgomp/testsuite/libgomp.c/pr26943-2.c
index c052e81128..2ed21ae963 100644
--- a/libgomp/testsuite/libgomp.c/pr26943-2.c
+++ b/libgomp/testsuite/libgomp.c/pr26943-2.c
@@ -3,6 +3,7 @@
extern int omp_set_dynamic (int);
extern void abort (void);
+extern void GOMP_barrier (void);
int a = 8, b = 12, c = 16, d = 20, j = 0;
char e[10] = "a", f[10] = "b", g[10] = "c", h[10] = "d";
@@ -20,7 +21,7 @@ main (void)
{
if (a != 8 || b != 12 || e[0] != 'a' || f[0] != 'b')
j++;
-#pragma omp barrier /* { dg-warning "may not be closely nested" } */
+ GOMP_barrier ();
#pragma omp atomic
a += i;
b += i;
@@ -31,7 +32,7 @@ main (void)
f[0] += i;
g[0] = 'g' + i;
h[0] = 'h' + i;
-#pragma omp barrier /* { dg-warning "may not be closely nested" } */
+ GOMP_barrier ();
if (a != 8 + 6 || b != 12 + i || c != i || d != i)
j += 8;
if (e[0] != 'a' + 6 || f[0] != 'b' + i || g[0] != 'g' + i)
diff --git a/libgomp/testsuite/libgomp.c/pr26943-3.c b/libgomp/testsuite/libgomp.c/pr26943-3.c
index dc3d5010da..855a4b2744 100644
--- a/libgomp/testsuite/libgomp.c/pr26943-3.c
+++ b/libgomp/testsuite/libgomp.c/pr26943-3.c
@@ -4,6 +4,7 @@
extern int omp_set_dynamic (int);
extern int omp_get_thread_num (void);
extern void abort (void);
+extern void GOMP_barrier (void);
int a = 8, b = 12, c = 16, d = 20, j = 0, l = 0;
char e[10] = "a", f[10] = "b", g[10] = "c", h[10] = "d";
@@ -26,7 +27,7 @@ main (void)
{
if (a != 8 || b != 12 || e[0] != 'a' || f[0] != 'b')
j++;
-#pragma omp barrier /* { dg-warning "may not be closely nested" } */
+ GOMP_barrier ();
#pragma omp atomic
a += i;
b += i;
@@ -37,7 +38,7 @@ main (void)
f[0] += i;
g[0] = 'g' + i;
h[0] = 'h' + i;
-#pragma omp barrier /* { dg-warning "may not be closely nested" } */
+ GOMP_barrier ();
if (a != 8 + 6 || b != 12 + i || c != i || d != i)
j += 8;
if (e[0] != 'a' + 6 || f[0] != 'b' + i || g[0] != 'g' + i)
diff --git a/libgomp/testsuite/libgomp.c/pr26943-4.c b/libgomp/testsuite/libgomp.c/pr26943-4.c
index 0f1d4197a5..24f253d236 100644
--- a/libgomp/testsuite/libgomp.c/pr26943-4.c
+++ b/libgomp/testsuite/libgomp.c/pr26943-4.c
@@ -4,6 +4,7 @@
extern int omp_set_dynamic (int);
extern int omp_get_thread_num (void);
extern void abort (void);
+extern void GOMP_barrier (void);
int a = 8, b = 12, c = 16, d = 20, j = 0, l = 0;
char e[10] = "a", f[10] = "b", g[10] = "c", h[10] = "d";
@@ -27,7 +28,7 @@ main (void)
{
if (a != 8 || b != 12 || e[0] != 'a' || f[0] != 'b')
j++;
-#pragma omp barrier /* { dg-warning "may not be closely nested" } */
+ GOMP_barrier ();
#pragma omp atomic
a += i;
b += i;
@@ -38,7 +39,7 @@ main (void)
f[0] += i;
g[0] = 'g' + i;
h[0] = 'h' + i;
-#pragma omp barrier /* { dg-warning "may not be closely nested" } */
+ GOMP_barrier ();
if (a != 8 + 6 || b != 12 + i || c != i || d != i)
j += 8;
if (e[0] != 'a' + 6 || f[0] != 'b' + i || g[0] != 'g' + i)
diff --git a/libgomp/testsuite/libgomp.c/pr46886.c b/libgomp/testsuite/libgomp.c/pr46886.c
new file mode 100644
index 0000000000..fbdc4e130d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr46886.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O -ftree-parallelize-loops=4 -fno-tree-ch -fno-tree-dominator-opts" } */
+
+void abort(void);
+
+int d[1024], e[1024];
+
+int foo (void)
+{
+ int s = 0;
+ int i;
+ for (i = 0; i < 1024; i++)
+ s += d[i] - e[i];
+ return s;
+}
+
+int main ()
+{
+ int i;
+ for (i = 0; i < 1024; i++)
+ {
+ d[i] = i * 2;
+ e[i] = i;
+ }
+ if (foo () != 1023 * 1024 / 2)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr52547.c b/libgomp/testsuite/libgomp.c/pr52547.c
new file mode 100644
index 0000000000..f746e2ec46
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr52547.c
@@ -0,0 +1,36 @@
+/* PR middle-end/52547 */
+/* { dg-do run } */
+
+extern void abort (void);
+
+__attribute__((noinline, noclone)) int
+baz (int *x, int (*fn) (int *))
+{
+ return fn (x);
+}
+
+__attribute__((noinline, noclone)) int
+foo (int x, int *y)
+{
+ int i, e = 0;
+#pragma omp parallel for reduction(|:e)
+ for (i = 0; i < x; ++i)
+ {
+ __label__ lab;
+ int bar (int *z) { return z - y; }
+ if (baz (&y[i], bar) != i)
+ e |= 1;
+ }
+ return e;
+}
+
+int
+main ()
+{
+ int a[100], i;
+ for (i = 0; i < 100; i++)
+ a[i] = i;
+ if (foo (100, a))
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/reduction-6.c b/libgomp/testsuite/libgomp.c/reduction-6.c
new file mode 100644
index 0000000000..d378bad9a6
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/reduction-6.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int j;
+float f;
+
+int
+main ()
+{
+ j = -10000;
+ f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/task-5.c b/libgomp/testsuite/libgomp.c/task-5.c
new file mode 100644
index 0000000000..b152371276
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/task-5.c
@@ -0,0 +1,45 @@
+/* { dg-do run } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int err;
+
+int
+main ()
+{
+ int e;
+#pragma omp parallel shared(err)
+ {
+ if (omp_in_final ())
+ #pragma omp atomic write
+ err = 1;
+ #pragma omp task if (0) shared(err)
+ {
+ if (omp_in_final ())
+ #pragma omp atomic write
+ err = 1;
+ #pragma omp task if (0) shared(err)
+ if (omp_in_final ())
+ #pragma omp atomic write
+ err = 1;
+ }
+ #pragma omp task final (1) shared(err)
+ {
+ if (!omp_in_final ())
+ #pragma omp atomic write
+ err = 1;
+ #pragma omp taskyield
+ #pragma omp taskwait
+ #pragma omp task shared(err)
+ if (!omp_in_final ())
+ #pragma omp atomic write
+ err = 1;
+ }
+ }
+ #pragma omp atomic read
+ e = err;
+ if (e)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable7.f90 b/libgomp/testsuite/libgomp.fortran/allocatable7.f90
new file mode 100644
index 0000000000..dc68baa754
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/allocatable7.f90
@@ -0,0 +1,16 @@
+! { dg-do run }
+
+ integer, allocatable :: a(:)
+ logical :: l
+ l = .false.
+!$omp parallel firstprivate (a) reduction (.or.:l)
+ l = allocated (a)
+ allocate (a(10))
+ l = l .or. .not. allocated (a)
+ a = 10
+ if (any (a .ne. 10)) l = .true.
+ deallocate (a)
+ l = l .or. allocated (a)
+!$omp end parallel
+ if (l) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/allocatable8.f90 b/libgomp/testsuite/libgomp.fortran/allocatable8.f90
new file mode 100644
index 0000000000..209378259e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/allocatable8.f90
@@ -0,0 +1,14 @@
+! { dg-do run }
+! { dg-require-effective-target tls_runtime }
+!$ use omp_lib
+
+ integer, save, allocatable :: a(:, :)
+ logical :: l
+!$omp threadprivate (a)
+ if (allocated (a)) call abort
+ l = .false.
+!$omp parallel copyin (a) num_threads (4) reduction(.or.:l)
+ l = l.or.allocated (a)
+!$omp end parallel
+ if (l.or.allocated (a)) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/crayptr3.f90 b/libgomp/testsuite/libgomp.fortran/crayptr3.f90
new file mode 100644
index 0000000000..9777c6b22c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/crayptr3.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+! { dg-options "-fopenmp -fcray-pointer" }
+
+ use omp_lib
+ integer :: a, b, c, i, p
+ logical :: l
+ pointer (ip, p)
+ a = 1
+ b = 2
+ c = 3
+ l = .false.
+ ip = loc (a)
+
+!$omp parallel num_threads (2) reduction (.or.:l) firstprivate (ip)
+ l = p .ne. 1
+ ip = loc (b)
+ if (omp_get_thread_num () .eq. 1) ip = loc (c)
+ l = l .or. (p .ne. (2 + omp_get_thread_num ()))
+!$omp end parallel
+
+ if (l) call abort
+
+ l = .false.
+ ip = loc (a)
+!$omp parallel do num_threads (2) reduction (.or.:l) &
+!$omp & firstprivate (ip) lastprivate (ip)
+ do i = 0, 1
+ l = l .or. (p .ne. 1)
+ ip = loc (b)
+ if (i .eq. 1) ip = loc (c)
+ l = l .or. (p .ne. (2 + i))
+ end do
+
+ if (l) call abort
+ if (p .ne. 3) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic3.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic3.f90
new file mode 100644
index 0000000000..e8923d1f21
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic3.f90
@@ -0,0 +1,58 @@
+! { dg-do run }
+ integer (kind = 4) :: a, a2
+ integer (kind = 2) :: b, b2
+ real :: c, f
+ double precision :: d, d2, c2
+ integer, dimension (10) :: e
+!$omp atomic write
+ a = 1
+!$omp atomic write
+ b = 2
+!$omp end atomic
+!$omp atomic write
+ c = 3
+!$omp atomic write
+ d = 1 + 2 + 3 - 2
+ e = 5
+!$omp atomic write
+ f = 6
+!$omp end atomic
+!$omp atomic
+ a = a + 4
+!$omp end atomic
+!$omp atomic update
+ b = 4 - b
+!$omp atomic
+ c = c * 2
+!$omp atomic update
+ d = 2 / d
+!$omp end atomic
+!$omp atomic read
+ a2 = a
+!$omp atomic read
+ b2 = b
+!$omp end atomic
+!$omp atomic read
+ c2 = c
+!$omp atomic read
+ d2 = d
+ if (a2 .ne. 5 .or. b2 .ne. 2 .or. c2 .ne. 6 .or. d2 .ne. 0.5) call abort
+!$omp atomic write
+ d = 1.2
+!$omp atomic
+ a = a + c + d
+!$omp atomic
+ b = b - (a + c + d)
+ if (a .ne. 12 .or. b .ne. -17) call abort
+!$omp atomic
+ a = c + d + a
+!$omp atomic
+ b = a + c + d - b
+ if (a .ne. 19 .or. b .ne. 43) call abort
+!$omp atomic
+ b = (a + c + d) - b
+ a = 32
+!$omp atomic
+ a = a / 3.4
+ if (a .ne. 9 .or. b .ne. -16) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/omp_atomic4.f90 b/libgomp/testsuite/libgomp.fortran/omp_atomic4.f90
new file mode 100644
index 0000000000..725a3bc24e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/omp_atomic4.f90
@@ -0,0 +1,37 @@
+! { dg-do run }
+ integer (kind = 4) :: a, a2
+ integer (kind = 2) :: b, b2
+ real :: c
+ double precision :: d, d2, c2
+ integer, dimension (10) :: e
+!$omp atomic write
+ a = 1
+!$omp atomic write
+ b = 2
+!$omp atomic write
+ c = 3
+!$omp atomic write
+ d = 4
+!$omp atomic capture
+ a2 = a
+ a = a + 4
+!$omp end atomic
+!$omp atomic capture
+ b = b - 18
+ b2 = b
+!$omp end atomic
+!$omp atomic capture
+ c2 = c
+ c = 2.0 * c
+!$omp end atomic
+!$omp atomic capture
+ d = d / 2.0
+ d2 = d
+!$omp end atomic
+ if (a2 .ne. 1 .or. b2 .ne. -16 .or. c2 .ne. 3 .or. d2 .ne. 2) call abort
+!$omp atomic read
+ a2 = a
+!$omp atomic read
+ c2 = c
+ if (a2 .ne. 5 .or. b2 .ne. -16 .or. c2 .ne. 6 .or. d2 .ne. 2) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/pointer1.f90 b/libgomp/testsuite/libgomp.fortran/pointer1.f90
new file mode 100644
index 0000000000..d55ef35f4a
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/pointer1.f90
@@ -0,0 +1,77 @@
+! { dg-do run }
+ integer, pointer :: a, c(:)
+ integer, target :: b, d(10)
+ b = 0
+ a => b
+ d = 0
+ c => d
+ call foo (a, c)
+ b = 0
+ d = 0
+ call bar (a, c)
+contains
+ subroutine foo (a, c)
+ integer, pointer :: a, c(:), b, d(:)
+ integer :: r, r2
+ r = 0
+ !$omp parallel firstprivate (a, c) reduction (+:r)
+ !$omp atomic
+ a = a + 1
+ !$omp atomic
+ c(1) = c(1) + 1
+ r = r + 1
+ !$omp end parallel
+ if (a.ne.r.or.c(1).ne.r) call abort
+ r2 = r
+ b => a
+ d => c
+ r = 0
+ !$omp parallel firstprivate (b, d) reduction (+:r)
+ !$omp atomic
+ b = b + 1
+ !$omp atomic
+ d(1) = d(1) + 1
+ r = r + 1
+ !$omp end parallel
+ if (b.ne.r+r2.or.d(1).ne.r+r2) call abort
+ end subroutine foo
+ subroutine bar (a, c)
+ integer, pointer :: a, c(:), b, d(:)
+ integer, target :: q, r(5)
+ integer :: i
+ q = 17
+ r = 21
+ b => a
+ d => c
+ !$omp parallel do firstprivate (a, c) lastprivate (a, c)
+ do i = 1, 100
+ !$omp atomic
+ a = a + 1
+ !$omp atomic
+ c((i+9)/10) = c((i+9)/10) + 1
+ if (i.eq.100) then
+ a => q
+ c => r
+ end if
+ end do
+ !$omp end parallel do
+ if (b.ne.100.or.any(d.ne.10)) call abort
+ if (a.ne.17.or.any(c.ne.21)) call abort
+ a => b
+ c => d
+ !$omp parallel do firstprivate (b, d) lastprivate (b, d)
+ do i = 1, 100
+ !$omp atomic
+ b = b + 1
+ !$omp atomic
+ d((i+9)/10) = d((i+9)/10) + 1
+ if (i.eq.100) then
+ b => q
+ d => r
+ end if
+ end do
+ !$omp end parallel do
+ if (a.ne.200.or.any(c.ne.20)) call abort
+ if (b.ne.17.or.any(d.ne.21)) call abort
+ end subroutine bar
+end
diff --git a/libgomp/testsuite/libgomp.fortran/pointer2.f90 b/libgomp/testsuite/libgomp.fortran/pointer2.f90
new file mode 100644
index 0000000000..f172aed4b1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/pointer2.f90
@@ -0,0 +1,28 @@
+! { dg-do run }
+! { dg-require-effective-target tls_runtime }
+ integer, pointer, save :: thr(:)
+!$omp threadprivate (thr)
+ integer, target :: s(3), t(3), u(3)
+ integer :: i
+ logical :: l
+ s = 2
+ t = 7
+ u = 13
+ thr => t
+ l = .false.
+ i = 0
+!$omp parallel copyin (thr) reduction(.or.:l) reduction(+:i)
+ if (any (thr.ne.7)) l = .true.
+ thr => s
+!$omp master
+ thr => u
+!$omp end master
+!$omp atomic
+ thr(1) = thr(1) + 1
+ i = i + 1
+!$omp end parallel
+ if (l) call abort
+ if (thr(1).ne.14) call abort
+ if (s(1).ne.1+i) call abort
+ if (u(1).ne.14) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/task4.f90 b/libgomp/testsuite/libgomp.fortran/task4.f90
new file mode 100644
index 0000000000..9fa67d95ba
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/task4.f90
@@ -0,0 +1,45 @@
+! { dg-do run }
+
+ use omp_lib
+ integer :: err, e
+
+!$omp atomic write
+ err = 0
+!$omp parallel shared(err) private(e)
+ if (omp_in_final ()) then
+!$omp atomic write
+ err = 1
+ endif
+!$omp task if (.false.) shared(err)
+ if (omp_in_final ()) then
+!$omp atomic write
+ err = 1
+ endif
+!$omp task if (.false.) shared(err)
+ if (omp_in_final ()) then
+!$omp atomic write
+ err = 1
+ endif
+!$omp end task
+!$omp end task
+!$omp atomic read
+ e = err
+!$omp task final (e .eq. 0) shared(err)
+ if (.not.omp_in_final ()) then
+!$omp atomic write
+ err = 1
+ endif
+!$omp taskyield
+!$omp taskwait
+!$omp task shared(err)
+ if (.not.omp_in_final ()) then
+!$omp atomic write
+ err = 1
+ endif
+!$omp end task
+!$omp end task
+!$omp end parallel
+!$omp atomic read
+ e = err
+ if (e .ne. 0) call abort
+end
diff --git a/libgomp/testsuite/libgomp.fortran/threadprivate4.f90 b/libgomp/testsuite/libgomp.fortran/threadprivate4.f90
new file mode 100644
index 0000000000..b5fb10bfee
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/threadprivate4.f90
@@ -0,0 +1,78 @@
+! { dg-do run }
+! { dg-require-effective-target tls_runtime }
+
+module threadprivate4
+ integer :: vi
+ procedure(), pointer :: foo
+!$omp threadprivate (foo, vi)
+
+contains
+ subroutine fn0
+ vi = 0
+ end subroutine fn0
+ subroutine fn1
+ vi = 1
+ end subroutine fn1
+ subroutine fn2
+ vi = 2
+ end subroutine fn2
+ subroutine fn3
+ vi = 3
+ end subroutine fn3
+end module threadprivate4
+
+ use omp_lib
+ use threadprivate4
+
+ integer :: i
+ logical :: l
+
+ procedure(), pointer :: bar1
+ common /thrc/ bar1
+!$omp threadprivate (/thrc/)
+
+ procedure(), pointer, save :: bar2
+!$omp threadprivate (bar2)
+
+ l = .false.
+ call omp_set_dynamic (.false.)
+ call omp_set_num_threads (4)
+
+!$omp parallel num_threads (4) reduction (.or.:l) private (i)
+ i = omp_get_thread_num ()
+ if (i.eq.0) then
+ foo => fn0
+ bar1 => fn0
+ bar2 => fn0
+ elseif (i.eq.1) then
+ foo => fn1
+ bar1 => fn1
+ bar2 => fn1
+ elseif (i.eq.2) then
+ foo => fn2
+ bar1 => fn2
+ bar2 => fn2
+ else
+ foo => fn3
+ bar1 => fn3
+ bar2 => fn3
+ end if
+ vi = -1
+!$omp barrier
+ vi = -1
+ call foo ()
+ l=l.or.(vi.ne.i)
+ vi = -2
+ call bar1 ()
+ l=l.or.(vi.ne.i)
+ vi = -3
+ call bar2 ()
+ l=l.or.(vi.ne.i)
+ vi = -1
+!$omp end parallel
+
+ if (l) call abort
+
+end
+
+! { dg-final { cleanup-modules "threadprivate4" } }
diff --git a/libgomp/testsuite/libgomp.fortran/vla4.f90 b/libgomp/testsuite/libgomp.fortran/vla4.f90
index cdd4849b6a..0bee30cf81 100644
--- a/libgomp/testsuite/libgomp.fortran/vla4.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla4.f90
@@ -10,6 +10,10 @@ contains
subroutine foo (c, d, e, f, g, h, i, j, k, n)
use omp_lib
+ interface
+ subroutine GOMP_barrier () bind(c, name="GOMP_barrier")
+ end subroutine
+ end interface
integer :: n
character (len = *) :: c
character (len = n) :: d
@@ -94,7 +98,7 @@ contains
forall (p = 1:2, q = 3:7, r = 1:7) u(p, q, r) = 30 - x - p + q - 2 * r
forall (p = 1:5, q = 3:7, p + q .le. 8) v(p, q) = w(1:7)
forall (p = 1:5, q = 3:7, p + q .gt. 8) v(p, q) = w(20:26)
-!$omp barrier ! { dg-warning "may not be closely nested" }
+ call GOMP_barrier
y = ''
if (x .eq. 0) y = '0'
if (x .eq. 1) y = '1'
diff --git a/libgomp/testsuite/libgomp.fortran/vla5.f90 b/libgomp/testsuite/libgomp.fortran/vla5.f90
index 9b61150521..cdd561d396 100644
--- a/libgomp/testsuite/libgomp.fortran/vla5.f90
+++ b/libgomp/testsuite/libgomp.fortran/vla5.f90
@@ -10,6 +10,10 @@ contains
subroutine foo (c, d, e, f, g, h, i, j, k, n)
use omp_lib
+ interface
+ subroutine GOMP_barrier () bind(c, name="GOMP_barrier")
+ end subroutine
+ end interface
integer :: n
character (len = *) :: c
character (len = n) :: d
@@ -66,7 +70,7 @@ contains
forall (p = 1:2, q = 3:7, r = 1:7) u(p, q, r) = 30 - x - p + q - 2 * r
forall (p = 1:5, q = 3:7, p + q .le. 8) v(p, q) = w(1:7)
forall (p = 1:5, q = 3:7, p + q .gt. 8) v(p, q) = w(20:26)
-!$omp barrier ! { dg-warning "may not be closely nested" }
+ call GOMP_barrier
y = ''
if (x .eq. 0) y = '0'
if (x .eq. 1) y = '1'
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-1.c b/libgomp/testsuite/libgomp.graphite/force-parallel-1.c
index 7f043d83d8..d168b43882 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-1.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-1.c
@@ -1,9 +1,10 @@
void abort (void);
+int x[10000000];
+
void parloop (int N)
{
int i;
- int x[10000000];
for (i = 0; i < N; i++)
x[i] = i + 3;
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-2.c b/libgomp/testsuite/libgomp.graphite/force-parallel-2.c
index 1ce0feb250..03d823653a 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-2.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-2.c
@@ -23,7 +23,7 @@ int main(void)
}
/* Check that parallel code generation part make the right answer. */
-/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "2 loops carried no dependency" 2 "graphite" } } */
/* { dg-final { cleanup-tree-dump "graphite" } } */
/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */
/* { dg-final { cleanup-tree-dump "parloops" } } */
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-3.c b/libgomp/testsuite/libgomp.graphite/force-parallel-3.c
index 81b356d5c2..ff8680bf03 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-3.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-3.c
@@ -2,12 +2,12 @@ void abort (void);
#define N 500
+int Z[2*N+2][2*N+2], B[2*N+2][2*N+2];
+
void foo(void)
{
int i,j;
- int Z[2*N+2][2*N+2], B[2*N+2][2*N+2];
-
for (i = 0; i < 2*N+2; i++)
for (j = 0; j < 2*N+2; j++)
B[i][j] = Z[i][j] = i + j;
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-6.c b/libgomp/testsuite/libgomp.graphite/force-parallel-6.c
index dcaaf4814b..995baa9c45 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-6.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-6.c
@@ -1,10 +1,11 @@
#define N 500
+int X[2*N], Y[2*N], B[2*N];
+int A[2*N][2*N], C[2*N][2*N];
+
int foo(void)
{
int i, j, k;
- int X[2*N], Y[2*N], B[2*N];
- int A[2*N][2*N], C[2*N][2*N];
for (i = 1; i <= N; i++)
{
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-7.c b/libgomp/testsuite/libgomp.graphite/force-parallel-7.c
index 9ba9007fe3..0191af085e 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-7.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-7.c
@@ -1,9 +1,10 @@
#define N 500
+int A[N+5][N+5][N+5];
+
int foo(void)
{
int i, j, k;
- int A[N+5][N+5][N+5];
/* Loop i: carried no dependency. */
for (i = 0; i < N; i++)
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-8.c b/libgomp/testsuite/libgomp.graphite/force-parallel-8.c
index 28b9a2a06b..dc553f53f1 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-8.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-8.c
@@ -1,9 +1,10 @@
#define N 1500
+int x[N][N], y[N];
+
int foo(void)
{
int i, j;
- int x[N][N], y[N];
for (i = 0; i < N; i++)
{
diff --git a/libgomp/testsuite/libgomp.graphite/force-parallel-9.c b/libgomp/testsuite/libgomp.graphite/force-parallel-9.c
index 36551905f0..1de43c3674 100644
--- a/libgomp/testsuite/libgomp.graphite/force-parallel-9.c
+++ b/libgomp/testsuite/libgomp.graphite/force-parallel-9.c
@@ -2,12 +2,12 @@ void abort (void);
#define N 500
+int Z[2*N+2][2*N+2], B[2*N+2][2*N+2];
+
void foo(void)
{
int i,j;
- int Z[2*N+2][2*N+2], B[2*N+2][2*N+2];
-
for (i = 0; i < 2*N+2; i++)
for (j = 0; j < 2*N+2; j++)
B[i][j] = Z[i][j] = i + j;