llvm/openmp/tools/archer/ompt-tsan.cpp

/*
 * 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
//
//===----------------------------------------------------------------------===//

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <dlfcn.h>
#include <inttypes.h>
#include <iostream>
#include <list>
#include <mutex>
#include <sstream>
#include <string>
#include <sys/resource.h>
#include <unistd.h>
#include <unordered_map>
#include <vector>

#include "omp-tools.h"

// Define attribute that indicates that the fall through from the previous
// case label is intentional and should not be diagnosed by a compiler
//   Code from libcxx/include/__config
// Use a function like macro to imply that it must be followed by a semicolon
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
#define KMP_FALLTHROUGH()
// icc cannot properly tell this attribute is absent so force off
#elif defined(__INTEL_COMPILER)
#define KMP_FALLTHROUGH
#elif __has_cpp_attribute(clang::fallthrough)
#define KMP_FALLTHROUGH
#elif __has_attribute(fallthrough) || __GNUC__ >= 7
#define KMP_FALLTHROUGH
#else
#define KMP_FALLTHROUGH
#endif

static int hasReductionCallback;

namespace {
class ArcherFlags {};

class TsanFlags {};
} // namespace

#if (LLVM_VERSION) >= 40
extern "C" {
int __attribute__((weak)) __archer_get_omp_status();
void __attribute__((weak)) __tsan_flush_memory() {}
}
#endif
static ArcherFlags *archer_flags;

#ifndef TsanHappensBefore

template <typename... Args> static void __ompt_tsan_func(Args...) {}

#define DECLARE_TSAN_FUNCTION(name, ...)

// Thread Sanitizer is a tool that finds races in code.
// See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
// tsan detects these exact functions by name.
extern

// This marker is used to define a happens-before arc. The race detector will
// infer an arc from the begin to the end when they share the same pointer
// argument.
#define TsanHappensBefore(cv)

// This marker defines the destination of a happens-before arc.
#define TsanHappensAfter(cv)

// Ignore any races on writes between here and the next TsanIgnoreWritesEnd.
#define TsanIgnoreWritesBegin()

// Resume checking for racy writes.
#define TsanIgnoreWritesEnd()

// We don't really delete the clock for now
#define TsanDeleteClock(cv)

// newMemory
#define TsanNewMemory(addr, size)
#define TsanFreeMemory(addr, size)
#endif

// Function entry/exit
#define TsanFuncEntry(pc)
#define TsanFuncExit()

/// Required OMPT inquiry functions.
static ompt_get_parallel_info_t ompt_get_parallel_info;
static ompt_get_thread_data_t ompt_get_thread_data;

ompt_tsan_clockid;

static uint64_t my_next_id() {}

static int pagesize{};

// Data structure to provide a threadsafe pool of reusable objects.
// DataPool<Type of objects>
namespace {
template <typename T> struct DataPool final {};

template <typename T> struct DataPoolEntry {};

struct DependencyData;
DependencyDataPool;
template <>
__thread DependencyDataPool *DependencyDataPool::ThreadDataPool =;

/// Data structure to store additional information for task dependency.
struct DependencyData final : DataPoolEntry<DependencyData> {};

struct TaskDependency {};

struct ParallelData;
ParallelDataPool;
template <>
__thread ParallelDataPool *ParallelDataPool::ThreadDataPool =;

/// Data structure to store additional information for parallel regions.
struct ParallelData final : DataPoolEntry<ParallelData> {};

static inline ParallelData *ToParallelData(ompt_data_t *parallel_data) {}

struct Taskgroup;
TaskgroupPool;
template <> __thread TaskgroupPool *TaskgroupPool::ThreadDataPool =;

/// Data structure to support stacking of taskgroups and allow synchronization.
struct Taskgroup final : DataPoolEntry<Taskgroup> {};

enum ArcherTaskFlag {};

struct TaskData;
TaskDataPool;
template <> __thread TaskDataPool *TaskDataPool::ThreadDataPool =;

/// Data structure to store additional information for tasks.
struct TaskData final : DataPoolEntry<TaskData> {};
} // namespace

static inline TaskData *ToTaskData(ompt_data_t *task_data) {}

/// Store a mutex for each wait_id to resolve race condition with callbacks.
static std::unordered_map<ompt_wait_id_t, std::mutex> Locks;
static std::mutex LocksMutex;

static void ompt_tsan_thread_begin(ompt_thread_t thread_type,
                                   ompt_data_t *thread_data) {}

static void ompt_tsan_thread_end(ompt_data_t *thread_data) {}

/// OMPT event callbacks for handling parallel regions.

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,
                                     const void *codeptr_ra) {}

static void ompt_tsan_parallel_end(ompt_data_t *parallel_data,
                                   ompt_data_t *task_data, int flag,
                                   const void *codeptr_ra) {}

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) {}

static void ompt_tsan_sync_region(ompt_sync_region_t kind,
                                  ompt_scope_endpoint_t endpoint,
                                  ompt_data_t *parallel_data,
                                  ompt_data_t *task_data,
                                  const void *codeptr_ra) {}

static void ompt_tsan_reduction(ompt_sync_region_t kind,
                                ompt_scope_endpoint_t endpoint,
                                ompt_data_t *parallel_data,
                                ompt_data_t *task_data,
                                const void *codeptr_ra) {}

/// OMPT event callbacks for handling tasks.

static void ompt_tsan_task_create(
    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           */
    int type, int has_dependences,
    const void *codeptr_ra) /* pointer to outlined function */
{}

static void freeTask(TaskData *task) {}

// LastAllMemoryPtr marks the beginning of an all_memory epoch
// NextAllMemoryPtr marks the end of an all_memory epoch
// All tasks with depend begin execution after LastAllMemoryPtr
// and end before NextAllMemoryPtr
static void releaseDependencies(TaskData *task) {}

static void acquireDependencies(TaskData *task) {}

static void completeTask(TaskData *FromTask) {}

static void suspendTask(TaskData *FromTask) {}

static void switchTasks(TaskData *FromTask, TaskData *ToTask) {}

static void endTask(TaskData *FromTask) {}

static void startTask(TaskData *ToTask) {}

static void ompt_tsan_task_schedule(ompt_data_t *first_task_data,
                                    ompt_task_status_t prior_task_status,
                                    ompt_data_t *second_task_data) {}

static void ompt_tsan_dependences(ompt_data_t *task_data,
                                  const ompt_dependence_t *deps, int ndeps) {}

/// OMPT event callbacks for handling locking.
static void ompt_tsan_mutex_acquired(ompt_mutex_t kind, ompt_wait_id_t wait_id,
                                     const void *codeptr_ra) {}

static void ompt_tsan_mutex_released(ompt_mutex_t kind, ompt_wait_id_t wait_id,
                                     const void *codeptr_ra) {}

// callback , signature , variable to store result , required support level
#define SET_OPTIONAL_CALLBACK_T(event, type, result, level)

#define SET_CALLBACK_T(event, type)

#define SET_CALLBACK(event)

#define findTsanFunction(f, fSig)

#define findTsanFunctionSilent(f, fSig)

static int ompt_tsan_initialize(ompt_function_lookup_t lookup, int device_num,
                                ompt_data_t *tool_data) {}

static void ompt_tsan_finalize(ompt_data_t *tool_data) {}

extern "C" ompt_start_tool_result_t *
ompt_start_tool(unsigned int omp_version, const char *runtime_version) {}