forked from OSchip/llvm-project
[OpenMP][Tools] clang-format Archer (NFC)
This commit is contained in:
parent
cf637a69e7
commit
eaed9e6b56
|
@ -1,15 +1,14 @@
|
|||
/*
|
||||
* ompt-tsan.cpp -- Archer runtime library, TSan annotations for Archer
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for details.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for details.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
@ -34,8 +33,8 @@
|
|||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include "omp-tools.h"
|
||||
#include <sys/resource.h>
|
||||
|
||||
static int runOnTsan;
|
||||
static int hasReductionCallback;
|
||||
|
@ -498,8 +497,7 @@ static void ompt_tsan_thread_end(ompt_data_t *thread_data) {
|
|||
static void ompt_tsan_parallel_begin(ompt_data_t *parent_task_data,
|
||||
const ompt_frame_t *parent_task_frame,
|
||||
ompt_data_t *parallel_data,
|
||||
uint32_t requested_team_size,
|
||||
int flag,
|
||||
uint32_t requested_team_size, int flag,
|
||||
const void *codeptr_ra) {
|
||||
ParallelData *Data = new ParallelData(codeptr_ra);
|
||||
parallel_data->ptr = Data;
|
||||
|
@ -508,8 +506,7 @@ static void ompt_tsan_parallel_begin(ompt_data_t *parent_task_data,
|
|||
}
|
||||
|
||||
static void ompt_tsan_parallel_end(ompt_data_t *parallel_data,
|
||||
ompt_data_t *task_data,
|
||||
int flag,
|
||||
ompt_data_t *task_data, int flag,
|
||||
const void *codeptr_ra) {
|
||||
ParallelData *Data = ToParallelData(parallel_data);
|
||||
TsanHappensAfter(Data->GetBarrierPtr(0));
|
||||
|
@ -523,15 +520,13 @@ static void ompt_tsan_parallel_end(ompt_data_t *parallel_data,
|
|||
__tsan_flush_memory();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void ompt_tsan_implicit_task(ompt_scope_endpoint_t endpoint,
|
||||
ompt_data_t *parallel_data,
|
||||
ompt_data_t *task_data,
|
||||
unsigned int team_size,
|
||||
unsigned int thread_num,
|
||||
int type) {
|
||||
unsigned int thread_num, int type) {
|
||||
switch (endpoint) {
|
||||
case ompt_scope_begin:
|
||||
if (type & ompt_task_initial) {
|
||||
|
@ -563,86 +558,86 @@ static void ompt_tsan_sync_region(ompt_sync_region_t kind,
|
|||
case ompt_scope_begin:
|
||||
TsanFuncEntry(codeptr_ra);
|
||||
switch (kind) {
|
||||
case ompt_sync_region_barrier_implementation:
|
||||
case ompt_sync_region_barrier_implicit:
|
||||
case ompt_sync_region_barrier_explicit:
|
||||
case ompt_sync_region_barrier: {
|
||||
char BarrierIndex = Data->BarrierIndex;
|
||||
TsanHappensBefore(Data->Team->GetBarrierPtr(BarrierIndex));
|
||||
case ompt_sync_region_barrier_implementation:
|
||||
case ompt_sync_region_barrier_implicit:
|
||||
case ompt_sync_region_barrier_explicit:
|
||||
case ompt_sync_region_barrier: {
|
||||
char BarrierIndex = Data->BarrierIndex;
|
||||
TsanHappensBefore(Data->Team->GetBarrierPtr(BarrierIndex));
|
||||
|
||||
if (hasReductionCallback < ompt_set_always) {
|
||||
// We ignore writes inside the barrier. These would either occur during
|
||||
// 1. reductions performed by the runtime which are guaranteed to be
|
||||
// race-free.
|
||||
// 2. execution of another task.
|
||||
// For the latter case we will re-enable tracking in task_switch.
|
||||
Data->InBarrier = true;
|
||||
TsanIgnoreWritesBegin();
|
||||
}
|
||||
|
||||
break;
|
||||
if (hasReductionCallback < ompt_set_always) {
|
||||
// We ignore writes inside the barrier. These would either occur during
|
||||
// 1. reductions performed by the runtime which are guaranteed to be
|
||||
// race-free.
|
||||
// 2. execution of another task.
|
||||
// For the latter case we will re-enable tracking in task_switch.
|
||||
Data->InBarrier = true;
|
||||
TsanIgnoreWritesBegin();
|
||||
}
|
||||
|
||||
case ompt_sync_region_taskwait:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case ompt_sync_region_taskgroup:
|
||||
Data->TaskGroup = new Taskgroup(Data->TaskGroup);
|
||||
break;
|
||||
case ompt_sync_region_taskwait:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case ompt_sync_region_taskgroup:
|
||||
Data->TaskGroup = new Taskgroup(Data->TaskGroup);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ompt_scope_end:
|
||||
TsanFuncExit();
|
||||
switch (kind) {
|
||||
case ompt_sync_region_barrier_implementation:
|
||||
case ompt_sync_region_barrier_implicit:
|
||||
case ompt_sync_region_barrier_explicit:
|
||||
case ompt_sync_region_barrier: {
|
||||
if (hasReductionCallback < ompt_set_always) {
|
||||
// We want to track writes after the barrier again.
|
||||
Data->InBarrier = false;
|
||||
TsanIgnoreWritesEnd();
|
||||
}
|
||||
|
||||
char BarrierIndex = Data->BarrierIndex;
|
||||
// Barrier will end after it has been entered by all threads.
|
||||
if (parallel_data)
|
||||
TsanHappensAfter(Data->Team->GetBarrierPtr(BarrierIndex));
|
||||
|
||||
// It is not guaranteed that all threads have exited this barrier before
|
||||
// we enter the next one. So we will use a different address.
|
||||
// We are however guaranteed that this current barrier is finished
|
||||
// by the time we exit the next one. So we can then reuse the first
|
||||
// address.
|
||||
Data->BarrierIndex = (BarrierIndex + 1) % 2;
|
||||
break;
|
||||
case ompt_sync_region_barrier_implementation:
|
||||
case ompt_sync_region_barrier_implicit:
|
||||
case ompt_sync_region_barrier_explicit:
|
||||
case ompt_sync_region_barrier: {
|
||||
if (hasReductionCallback < ompt_set_always) {
|
||||
// We want to track writes after the barrier again.
|
||||
Data->InBarrier = false;
|
||||
TsanIgnoreWritesEnd();
|
||||
}
|
||||
|
||||
case ompt_sync_region_taskwait: {
|
||||
if (Data->execution > 1)
|
||||
TsanHappensAfter(Data->GetTaskwaitPtr());
|
||||
break;
|
||||
}
|
||||
char BarrierIndex = Data->BarrierIndex;
|
||||
// Barrier will end after it has been entered by all threads.
|
||||
if (parallel_data)
|
||||
TsanHappensAfter(Data->Team->GetBarrierPtr(BarrierIndex));
|
||||
|
||||
case ompt_sync_region_taskgroup: {
|
||||
assert(Data->TaskGroup != nullptr &&
|
||||
"Should have at least one taskgroup!");
|
||||
// It is not guaranteed that all threads have exited this barrier before
|
||||
// we enter the next one. So we will use a different address.
|
||||
// We are however guaranteed that this current barrier is finished
|
||||
// by the time we exit the next one. So we can then reuse the first
|
||||
// address.
|
||||
Data->BarrierIndex = (BarrierIndex + 1) % 2;
|
||||
break;
|
||||
}
|
||||
|
||||
TsanHappensAfter(Data->TaskGroup->GetPtr());
|
||||
case ompt_sync_region_taskwait: {
|
||||
if (Data->execution > 1)
|
||||
TsanHappensAfter(Data->GetTaskwaitPtr());
|
||||
break;
|
||||
}
|
||||
|
||||
// Delete this allocated taskgroup, all descendent task are finished by
|
||||
// now.
|
||||
Taskgroup *Parent = Data->TaskGroup->Parent;
|
||||
delete Data->TaskGroup;
|
||||
Data->TaskGroup = Parent;
|
||||
break;
|
||||
}
|
||||
case ompt_sync_region_taskgroup: {
|
||||
assert(Data->TaskGroup != nullptr &&
|
||||
"Should have at least one taskgroup!");
|
||||
|
||||
default:
|
||||
break;
|
||||
TsanHappensAfter(Data->TaskGroup->GetPtr());
|
||||
|
||||
// Delete this allocated taskgroup, all descendent task are finished by
|
||||
// now.
|
||||
Taskgroup *Parent = Data->TaskGroup->Parent;
|
||||
delete Data->TaskGroup;
|
||||
Data->TaskGroup = Parent;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -656,20 +651,20 @@ static void ompt_tsan_reduction(ompt_sync_region_t kind,
|
|||
switch (endpoint) {
|
||||
case ompt_scope_begin:
|
||||
switch (kind) {
|
||||
case ompt_sync_region_reduction:
|
||||
TsanIgnoreWritesBegin();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case ompt_sync_region_reduction:
|
||||
TsanIgnoreWritesBegin();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ompt_scope_end:
|
||||
switch (kind) {
|
||||
case ompt_sync_region_reduction:
|
||||
TsanIgnoreWritesEnd();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case ompt_sync_region_reduction:
|
||||
TsanIgnoreWritesEnd();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -678,9 +673,9 @@ static void ompt_tsan_reduction(ompt_sync_region_t kind,
|
|||
/// OMPT event callbacks for handling tasks.
|
||||
|
||||
static void ompt_tsan_task_create(
|
||||
ompt_data_t *parent_task_data, /* id of parent task */
|
||||
ompt_data_t *parent_task_data, /* id of parent task */
|
||||
const ompt_frame_t *parent_frame, /* frame data for parent task */
|
||||
ompt_data_t *new_task_data, /* id of created task */
|
||||
ompt_data_t *new_task_data, /* id of created task */
|
||||
int type, int has_dependences,
|
||||
const void *codeptr_ra) /* pointer to outlined function */
|
||||
{
|
||||
|
@ -791,7 +786,8 @@ static void ompt_tsan_task_schedule(ompt_data_t *first_task_data,
|
|||
|
||||
// in dependencies block following inout and out dependencies!
|
||||
TsanHappensBefore(ToInAddr(Dependency->variable.ptr));
|
||||
if (Dependency->dependence_type == ompt_dependence_type_out || Dependency->dependence_type == ompt_dependence_type_inout) {
|
||||
if (Dependency->dependence_type == ompt_dependence_type_out ||
|
||||
Dependency->dependence_type == ompt_dependence_type_inout) {
|
||||
TsanHappensBefore(Dependency->variable.ptr);
|
||||
}
|
||||
}
|
||||
|
@ -842,14 +838,12 @@ static void ompt_tsan_task_schedule(ompt_data_t *first_task_data,
|
|||
}
|
||||
|
||||
static void ompt_tsan_dependences(ompt_data_t *task_data,
|
||||
const ompt_dependence_t *deps,
|
||||
int ndeps) {
|
||||
const ompt_dependence_t *deps, int ndeps) {
|
||||
if (ndeps > 0) {
|
||||
// Copy the data to use it in task_switch and task_end.
|
||||
TaskData *Data = ToTaskData(task_data);
|
||||
Data->Dependencies = new ompt_dependence_t[ndeps];
|
||||
std::memcpy(Data->Dependencies, deps,
|
||||
sizeof(ompt_dependence_t) * ndeps);
|
||||
std::memcpy(Data->Dependencies, deps, sizeof(ompt_dependence_t) * ndeps);
|
||||
Data->DependencyCount = ndeps;
|
||||
|
||||
// This callback is executed before this task is first started.
|
||||
|
@ -858,53 +852,51 @@ static void ompt_tsan_dependences(ompt_data_t *task_data,
|
|||
}
|
||||
|
||||
/// OMPT event callbacks for handling locking.
|
||||
static void ompt_tsan_mutex_acquired(ompt_mutex_t kind,
|
||||
ompt_wait_id_t wait_id,
|
||||
static void ompt_tsan_mutex_acquired(ompt_mutex_t kind, ompt_wait_id_t wait_id,
|
||||
const void *codeptr_ra) {
|
||||
|
||||
// Acquire our own lock to make sure that
|
||||
// 1. the previous release has finished.
|
||||
// 2. the next acquire doesn't start before we have finished our release.
|
||||
LocksMutex.lock();
|
||||
std::mutex &Lock = Locks[wait_id];
|
||||
LocksMutex.unlock();
|
||||
LocksMutex.lock();
|
||||
std::mutex &Lock = Locks[wait_id];
|
||||
LocksMutex.unlock();
|
||||
|
||||
Lock.lock();
|
||||
TsanHappensAfter(&Lock);
|
||||
Lock.lock();
|
||||
TsanHappensAfter(&Lock);
|
||||
}
|
||||
|
||||
static void ompt_tsan_mutex_released(ompt_mutex_t kind,
|
||||
ompt_wait_id_t wait_id,
|
||||
static void ompt_tsan_mutex_released(ompt_mutex_t kind, ompt_wait_id_t wait_id,
|
||||
const void *codeptr_ra) {
|
||||
LocksMutex.lock();
|
||||
std::mutex &Lock = Locks[wait_id];
|
||||
LocksMutex.unlock();
|
||||
TsanHappensBefore(&Lock);
|
||||
LocksMutex.lock();
|
||||
std::mutex &Lock = Locks[wait_id];
|
||||
LocksMutex.unlock();
|
||||
TsanHappensBefore(&Lock);
|
||||
|
||||
Lock.unlock();
|
||||
Lock.unlock();
|
||||
}
|
||||
|
||||
// callback , signature , variable to store result , required support level
|
||||
#define SET_OPTIONAL_CALLBACK_T(event, type, result, level) \
|
||||
do { \
|
||||
ompt_callback_##type##_t tsan_##event = &ompt_tsan_##event; \
|
||||
result = ompt_set_callback(ompt_callback_##event, \
|
||||
(ompt_callback_t)tsan_##event); \
|
||||
if (result < level) \
|
||||
printf("Registered callback '" #event "' is not supported at " #level " (%i)\n", \
|
||||
result); \
|
||||
#define SET_OPTIONAL_CALLBACK_T(event, type, result, level) \
|
||||
do { \
|
||||
ompt_callback_##type##_t tsan_##event = &ompt_tsan_##event; \
|
||||
result = ompt_set_callback(ompt_callback_##event, \
|
||||
(ompt_callback_t)tsan_##event); \
|
||||
if (result < level) \
|
||||
printf("Registered callback '" #event "' is not supported at " #level \
|
||||
" (%i)\n", \
|
||||
result); \
|
||||
} while (0)
|
||||
|
||||
#define SET_CALLBACK_T(event, type) \
|
||||
do { \
|
||||
int res; \
|
||||
SET_OPTIONAL_CALLBACK_T(event, type, res, ompt_set_always); \
|
||||
#define SET_CALLBACK_T(event, type) \
|
||||
do { \
|
||||
int res; \
|
||||
SET_OPTIONAL_CALLBACK_T(event, type, res, ompt_set_always); \
|
||||
} while (0)
|
||||
|
||||
#define SET_CALLBACK(event) SET_CALLBACK_T(event, event)
|
||||
|
||||
static int ompt_tsan_initialize(ompt_function_lookup_t lookup,
|
||||
int device_num,
|
||||
static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num,
|
||||
ompt_data_t *tool_data) {
|
||||
const char *options = getenv("TSAN_OPTIONS");
|
||||
TsanFlags tsan_flags(options);
|
||||
|
@ -938,13 +930,14 @@ static int ompt_tsan_initialize(ompt_function_lookup_t lookup,
|
|||
|
||||
SET_CALLBACK_T(mutex_acquired, mutex);
|
||||
SET_CALLBACK_T(mutex_released, mutex);
|
||||
SET_OPTIONAL_CALLBACK_T(reduction, sync_region, hasReductionCallback, ompt_set_never);
|
||||
SET_OPTIONAL_CALLBACK_T(reduction, sync_region, hasReductionCallback,
|
||||
ompt_set_never);
|
||||
|
||||
if (!tsan_flags.ignore_noninstrumented_modules)
|
||||
fprintf(
|
||||
stderr,
|
||||
"Warning: please export TSAN_OPTIONS='ignore_noninstrumented_modules=1' "
|
||||
"to avoid false positive reports from the OpenMP runtime!\n");
|
||||
fprintf(stderr,
|
||||
"Warning: please export "
|
||||
"TSAN_OPTIONS='ignore_noninstrumented_modules=1' "
|
||||
"to avoid false positive reports from the OpenMP runtime!\n");
|
||||
return 1; // success
|
||||
}
|
||||
|
||||
|
@ -959,26 +952,23 @@ static void ompt_tsan_finalize(ompt_data_t *tool_data) {
|
|||
delete archer_flags;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,
|
||||
const char *runtime_version) {
|
||||
extern "C" ompt_start_tool_result_t *
|
||||
ompt_start_tool(unsigned int omp_version, const char *runtime_version) {
|
||||
const char *options = getenv("ARCHER_OPTIONS");
|
||||
archer_flags = new ArcherFlags(options);
|
||||
if (!archer_flags->enabled)
|
||||
{
|
||||
if (!archer_flags->enabled) {
|
||||
if (archer_flags->verbose)
|
||||
std::cout << "Archer disabled, stopping operation"
|
||||
<< std::endl;
|
||||
std::cout << "Archer disabled, stopping operation" << std::endl;
|
||||
delete archer_flags;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static ompt_start_tool_result_t ompt_start_tool_result = {
|
||||
&ompt_tsan_initialize, &ompt_tsan_finalize, {0}};
|
||||
runOnTsan=1;
|
||||
runOnTsan = 1;
|
||||
RunningOnValgrind();
|
||||
if (!runOnTsan) // if we are not running on TSAN, give a different tool the
|
||||
// chance to be loaded
|
||||
// chance to be loaded
|
||||
{
|
||||
if (archer_flags->verbose)
|
||||
std::cout << "Archer detected OpenMP application without TSan "
|
||||
|
|
Loading…
Reference in New Issue