Compare commits

...
9 Commits
Author SHA1 Message Date
Tom Stellard 29b515e1e6 Merging r318848:
------------------------------------------------------------------------
r318848 | hahnfeld | 2017-11-22 09:15:20 -0800 (Wed, 22 Nov 2017) | 7 lines

Fix for OMP doacross implementation on Power

Power has a weak consistency model so we need memory barriers to
make writes (both from runtime and from user code) available for
all threads.

Differential Revision: https://reviews.llvm.org/D40175
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@319057 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-27 17:34:55 +00:00
Tom Stellard 4ef23db17c Merging r318658:
------------------------------------------------------------------------
r318658 | achurbanov | 2017-11-20 08:00:42 -0800 (Mon, 20 Nov 2017) | 4 lines

Fixed OMP doacross implementation on 32-bit platforms.

Differential Revision: https://reviews.llvm.org/D40171

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@319053 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-27 17:29:37 +00:00
Tom Stellard 37c72127e9 Merging r317115:
------------------------------------------------------------------------
r317115 | jlpeyton | 2017-11-01 12:44:42 -0700 (Wed, 01 Nov 2017) | 19 lines

[OpenMP] Fix race condition in omp_init_lock

This is a partial fix for bug 34050.

This prevents callers of omp_set_lock (which does not hold __kmp_global_lock)
from ever seeing an uninitialized version of __kmp_i_lock_table.table.

It does not solve a use-after-free race condition if omp_set_lock obtains a
pointer to __kmp_i_lock_table.table before it is updated and then attempts to
dereference afterwards. That race is far less likely and can be handled in a
separate patch.

The unit test usually segfaults on the current trunk revision. It passes with
the patch.

Patch by Adam Azarchs

Differential Revision: https://reviews.llvm.org/D39439

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318178 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:21:30 +00:00
Tom Stellard 11cf126119 Merging r316452:
------------------------------------------------------------------------
r316452 | jlpeyton | 2017-10-24 09:10:09 -0700 (Tue, 24 Oct 2017) | 9 lines

Disable threadprivate data cleanup if runtime is terminating

The problem is due to the runtime's threadprivate cleanup code which tries to
access data that was already destroyed by one of the root threads.
__kmp_init_gtid is used as a checker here since it is set to false before actual
resource cleanup is done in __kmp_cleanup().

Patch by Hansang Bae

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318176 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:19:10 +00:00
Tom Stellard 470366641d Merging r311269:
------------------------------------------------------------------------
r311269 | jlpeyton | 2017-08-19 16:53:36 -0700 (Sat, 19 Aug 2017) | 8 lines

Use va_copy instead of __va_copy to fix building libomp against musl libc

Fixes https://bugs.llvm.org/show_bug.cgi?id=34040

Patch by Peter Levine

Differential Revision: https://reviews.llvm.org/D36343

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318175 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:16:52 +00:00
Tom Stellard 08f2b9ce14 Merging r309875:
------------------------------------------------------------------------
r309875 | jlpeyton | 2017-08-02 13:06:32 -0700 (Wed, 02 Aug 2017) | 11 lines

Move lock acquire/release functions in task deque cleanup code

The original locations can be reached without initializing the lock variable
(td_deque_lock), so it is potentially unsafe.  It is guaranteed that the lock
is initialized if the deque (td_deque) is not NULL, and lock functions can be
safely called.

Patch by Hansang Bae

Differential Revision: https://reviews.llvm.org/D36017

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318171 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:11:04 +00:00
Tom Stellard 67512bb555 Merging r314513:
------------------------------------------------------------------------
r314513 | hahnfeld | 2017-09-29 06:53:03 -0700 (Fri, 29 Sep 2017) | 3 lines

[test] Fix uninitialized memory in omp_taskloop_grainsize.c

result was never initialized to zero which sometimes failed the test.
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@315353 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-10 19:57:45 +00:00
Hans Wennborg 6999fe680a Merging r309115:
------------------------------------------------------------------------
r309115 | hahnfeld | 2017-07-26 06:55:00 -0700 (Wed, 26 Jul 2017) | 15 lines

[CMake] Disable building libomptarget and add CMake switch

Introduce OPENMP_ENABLE_LIBOMPTARGET which defaults to OFF at the moment.

libomptarget is not yet ready for prime time:
 - Offloading to NVIDIA GPUs is not completed yet (compiler, device RTL)
 - The generic ELF plugin for offloading to the host (meant for testing)
   uses a single instance of the OpenMP runtime (libomp). That is why
   omp_is_initial_device() returns 1 which makes the tests fail.
Because of these reasons, we want to disable building (and testing!)
for release 5.0.

See https://bugs.llvm.org/show_bug.cgi?id=33859

Differential Revision: https://reviews.llvm.org/D35719
------------------------------------------------------------------------


git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@309126 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-26 15:47:03 +00:00
Hans Wennborg 1333cd34fa Creating release_50 branch off revision 308441
git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@308453 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-19 12:20:58 +00:00
9 changed files with 94 additions and 19 deletions
+12 -1
View File
@@ -4,9 +4,20 @@ set(OPENMP_LLVM_TOOLS_DIR "" CACHE PATH "Path to LLVM tools for testing")
add_subdirectory(runtime)
# The tests currently don't pass if the generic ELF plugin is built.
# TODO: Fix the tests and enable libomptarget by default on supported
# architectures and platforms.
set(ENABLE_LIBOMPTARGET OFF)
# Currently libomptarget cannot be compiled on Windows or MacOS X.
# Since the device plugins are only supported on Linux anyway,
# there is no point in trying to compile libomptarget on other OSes.
if (NOT (WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin"))
if (WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(ENABLE_LIBOMPTARGET OFF)
endif()
option(OPENMP_ENABLE_LIBOMPTARGET "Enable building libomptarget for offloading."
${ENABLE_LIBOMPTARGET})
if (OPENMP_ENABLE_LIBOMPTARGET)
add_subdirectory(libomptarget)
endif()
+23 -9
View File
@@ -3095,23 +3095,35 @@ void __kmpc_doacross_init(ident_t *loc, int gtid, int num_dims,
__kmp_wait_yield_4((volatile kmp_uint32 *)&sh_buf->doacross_buf_idx, idx,
__kmp_eq_4, NULL);
}
#if KMP_32_BIT_ARCH
// Check if we are the first thread. After the CAS the first thread gets 0,
// others get 1 if initialization is in progress, allocated pointer otherwise.
// Treat pointer as volatile integer (value 0 or 1) until memory is allocated.
flags = (kmp_uint32 *)KMP_COMPARE_AND_STORE_RET32(
(volatile kmp_int32 *)&sh_buf->doacross_flags, NULL, 1);
#else
flags = (kmp_uint32 *)KMP_COMPARE_AND_STORE_RET64(
(kmp_int64 *)&sh_buf->doacross_flags, NULL, (kmp_int64)1);
(volatile kmp_int64 *)&sh_buf->doacross_flags, NULL, 1LL);
#endif
if (flags == NULL) {
// we are the first thread, allocate the array of flags
kmp_int64 size =
trace_count / 8 + 8; // in bytes, use single bit per iteration
sh_buf->doacross_flags = (kmp_uint32 *)__kmp_thread_calloc(th, size, 1);
} else if ((kmp_int64)flags == 1) {
size_t size = trace_count / 8 + 8; // in bytes, use single bit per iteration
flags = (kmp_uint32 *)__kmp_thread_calloc(th, size, 1);
KMP_MB();
sh_buf->doacross_flags = flags;
} else if (flags == (kmp_uint32 *)1) {
#if KMP_32_BIT_ARCH
// initialization is still in progress, need to wait
while ((volatile kmp_int64)sh_buf->doacross_flags == 1) {
while (*(volatile kmp_int32 *)&sh_buf->doacross_flags == 1)
#else
while (*(volatile kmp_int64 *)&sh_buf->doacross_flags == 1LL)
#endif
KMP_YIELD(TRUE);
}
KMP_MB();
} else {
KMP_MB();
}
KMP_DEBUG_ASSERT((kmp_int64)sh_buf->doacross_flags >
1); // check value of pointer
KMP_DEBUG_ASSERT(sh_buf->doacross_flags > (kmp_uint32 *)1); // check ptr value
pr_buf->th_doacross_flags =
sh_buf->doacross_flags; // save private copy in order to not
// touch shared buffer on each iteration
@@ -3205,6 +3217,7 @@ void __kmpc_doacross_wait(ident_t *loc, int gtid, long long *vec) {
while ((flag & pr_buf->th_doacross_flags[iter_number]) == 0) {
KMP_YIELD(TRUE);
}
KMP_MB();
KA_TRACE(20,
("__kmpc_doacross_wait() exit: T#%d wait for iter %lld completed\n",
gtid, (iter_number << 5) + shft));
@@ -3257,6 +3270,7 @@ void __kmpc_doacross_post(ident_t *loc, int gtid, long long *vec) {
shft = iter_number % 32; // use 32-bit granularity
iter_number >>= 5; // divided by 32
flag = 1 << shft;
KMP_MB();
if ((flag & pr_buf->th_doacross_flags[iter_number]) == 0)
KMP_TEST_THEN_OR32(&pr_buf->th_doacross_flags[iter_number], flag);
KA_TRACE(20, ("__kmpc_doacross_post() exit: T#%d iter %lld posted\n", gtid,
+4 -3
View File
@@ -3061,11 +3061,12 @@ kmp_indirect_lock_t *__kmp_allocate_indirect_lock(void **user_lock,
if (idx == __kmp_i_lock_table.size) {
// Double up the space for block pointers
int row = __kmp_i_lock_table.size / KMP_I_LOCK_CHUNK;
kmp_indirect_lock_t **old_table = __kmp_i_lock_table.table;
__kmp_i_lock_table.table = (kmp_indirect_lock_t **)__kmp_allocate(
kmp_indirect_lock_t **new_table = (kmp_indirect_lock_t **)__kmp_allocate(
2 * row * sizeof(kmp_indirect_lock_t *));
KMP_MEMCPY(__kmp_i_lock_table.table, old_table,
KMP_MEMCPY(new_table, __kmp_i_lock_table.table,
row * sizeof(kmp_indirect_lock_t *));
kmp_indirect_lock_t **old_table = __kmp_i_lock_table.table;
__kmp_i_lock_table.table = new_table;
__kmp_free(old_table);
// Allocate new objects in the new blocks
for (int i = row; i < 2 * row; ++i)
+1 -1
View File
@@ -168,7 +168,7 @@ void __kmp_str_buf_vprint(kmp_str_buf_t *buffer, char const *format,
#if !KMP_OS_WINDOWS
va_list _args;
__va_copy(_args, args); // Make copy of args.
va_copy(_args, args); // Make copy of args.
#define args _args // Substitute args with its copy, _args.
#endif // KMP_OS_WINDOWS
rc = KMP_VSNPRINTF(buffer->str + buffer->used, free, format, args);
+2 -3
View File
@@ -2504,14 +2504,13 @@ static void __kmp_realloc_task_deque(kmp_info_t *thread,
// Deallocates a task deque for a particular thread. Happens at library
// deallocation so don't need to reset all thread data fields.
static void __kmp_free_task_deque(kmp_thread_data_t *thread_data) {
__kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
if (thread_data->td.td_deque != NULL) {
__kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
TCW_4(thread_data->td.td_deque_ntasks, 0);
__kmp_free(thread_data->td.td_deque);
thread_data->td.td_deque = NULL;
__kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
}
__kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
#ifdef BUILD_TIED_TASK_STACK
// GEH: Figure out what to do here for td_susp_tied_tasks
+7
View File
@@ -228,6 +228,13 @@ void __kmp_common_destroy_gtid(int gtid) {
struct private_common *tn;
struct shared_common *d_tn;
if (!TCR_4(__kmp_init_gtid)) {
// This is possible when one of multiple roots initiates early library
// termination in a sequential region while other teams are active, and its
// child threads are about to end.
return;
}
KC_TRACE(10, ("__kmp_common_destroy_gtid: T#%d called\n", gtid));
if ((__kmp_foreign_tp) ? (!KMP_INITIAL_GTID(gtid)) : (!KMP_UBER_GTID(gtid))) {
+42
View File
@@ -0,0 +1,42 @@
// RUN: %libomp-compile-and-run
#include "omp_testsuite.h"
#include <stdio.h>
// This should be slightly less than KMP_I_LOCK_CHUNK, which is 1024
#define LOCKS_PER_ITER 1000
#define ITERATIONS (REPETITIONS + 1)
// This tests concurrently using locks on one thread while initializing new
// ones on another thread. This exercises the global lock pool.
int test_omp_init_lock() {
int i;
omp_lock_t lcks[ITERATIONS * LOCKS_PER_ITER];
#pragma omp parallel for schedule(static) num_threads(NUM_TASKS)
for (i = 0; i < ITERATIONS; i++) {
int j;
omp_lock_t *my_lcks = &lcks[i * LOCKS_PER_ITER];
for (j = 0; j < LOCKS_PER_ITER; j++) {
omp_init_lock(&my_lcks[j]);
}
for (j = 0; j < LOCKS_PER_ITER * 100; j++) {
omp_set_lock(&my_lcks[j % LOCKS_PER_ITER]);
omp_unset_lock(&my_lcks[j % LOCKS_PER_ITER]);
}
}
// Wait until all repititions are done. The test is exercising growth of
// the global lock pool, which does not shrink when no locks are allocated.
{
int j;
for (j = 0; j < ITERATIONS * LOCKS_PER_ITER; j++) {
omp_destroy_lock(&lcks[j]);
}
}
return 0;
}
int main() {
// No use repeating this test, since it's exercising a private global pool
// which is not reset between test iterations.
return test_omp_init_lock();
}
@@ -17,7 +17,8 @@
int test_omp_taskloop_grainsize()
{
int i, grainsize, count, tmp_count, result, num_off;
int result = 0;
int i, grainsize, count, tmp_count, num_off;
int *tmp, *tids, *tidsArray;
tidsArray = (int *)malloc(sizeof(int) * CFDMAX_SIZE);
@@ -24,7 +24,7 @@ int main()
dims.lo = 1;
dims.up = N-1;
dims.st = 1;
#pragma omp parallel
#pragma omp parallel num_threads(4)
{
int i, gtid;
long long vec;