llvm/openmp/runtime/src/kmp.h

/*! \file */
/*
 * kmp.h -- KPTS runtime header file.
 */

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef KMP_H
#define KMP_H

#include "kmp_config.h"

/* #define BUILD_PARALLEL_ORDERED 1 */

/* This fix replaces gettimeofday with clock_gettime for better scalability on
   the Altix.  Requires user code to be linked with -lrt. */
//#define FIX_SGI_CLOCK

/* Defines for OpenMP 3.0 tasking and auto scheduling */

#ifndef KMP_STATIC_STEAL_ENABLED
#define KMP_STATIC_STEAL_ENABLED
#endif
#define KMP_WEIGHTED_ITERATIONS_SUPPORTED

#define TASK_CURRENT_NOT_QUEUED
#define TASK_CURRENT_QUEUED

#ifdef BUILD_TIED_TASK_STACK
#define TASK_STACK_EMPTY
#define TASK_STACK_BLOCK_BITS
// Number of entries in each task stack array
#define TASK_STACK_BLOCK_SIZE
// Mask for determining index into stack block
#define TASK_STACK_INDEX_MASK
#endif // BUILD_TIED_TASK_STACK

#define TASK_NOT_PUSHED
#define TASK_SUCCESSFULLY_PUSHED
#define TASK_TIED
#define TASK_UNTIED
#define TASK_EXPLICIT
#define TASK_IMPLICIT
#define TASK_PROXY
#define TASK_FULL
#define TASK_DETACHABLE
#define TASK_UNDETACHABLE

#define KMP_CANCEL_THREADS
#define KMP_THREAD_ATTR

// Android does not have pthread_cancel.  Undefine KMP_CANCEL_THREADS if being
// built on Android
#if defined(__ANDROID__)
#undef KMP_CANCEL_THREADS
#endif

// Some WASI targets (e.g., wasm32-wasi-threads) do not support thread
// cancellation.
#if KMP_OS_WASI
#undef KMP_CANCEL_THREADS
#endif

#if !KMP_OS_WASI
#include <signal.h>
#endif
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits>
#include <type_traits>
/* include <ctype.h> don't use; problems with /MD on Windows* OS NT due to bad
   Microsoft library. Some macros provided below to replace these functions  */
#ifndef __ABSOFT_WIN
#include <sys/types.h>
#endif
#include <limits.h>
#include <time.h>

#include <errno.h>

#include "kmp_os.h"

#include "kmp_safe_c_api.h"

#if KMP_STATS_ENABLED
class kmp_stats_list;
#endif

#if KMP_USE_HIER_SCHED
// Only include hierarchical scheduling if affinity is supported
#undef KMP_USE_HIER_SCHED
#define KMP_USE_HIER_SCHED
#endif

// OMPD_SKIP_HWLOC used in libompd/omp-icv.cpp to avoid OMPD depending on hwloc
#if KMP_USE_HWLOC && KMP_AFFINITY_SUPPORTED && !defined(OMPD_SKIP_HWLOC)
#include "hwloc.h"
#ifndef HWLOC_OBJ_NUMANODE
#define HWLOC_OBJ_NUMANODE
#endif
#ifndef HWLOC_OBJ_PACKAGE
#define HWLOC_OBJ_PACKAGE
#endif
#endif

#if KMP_ARCH_X86 || KMP_ARCH_X86_64
#include <xmmintrin.h>
#endif

// The below has to be defined before including "kmp_barrier.h".
#define KMP_INTERNAL_MALLOC(sz)
#define KMP_INTERNAL_FREE(p)
#define KMP_INTERNAL_REALLOC(p, sz)
#define KMP_INTERNAL_CALLOC(n, sz)

#include "kmp_debug.h"
#include "kmp_lock.h"
#include "kmp_version.h"
#include "kmp_barrier.h"
#if USE_DEBUGGER
#include "kmp_debugger.h"
#endif
#include "kmp_i18n.h"

#define KMP_HANDLE_SIGNALS

#include "kmp_wrapper_malloc.h"
#if KMP_OS_UNIX
#include <unistd.h>
#if !defined NSIG && defined _NSIG
#define NSIG
#endif
#endif

#if KMP_OS_LINUX
#pragma weak clock_gettime
#endif

#if OMPT_SUPPORT
#include "ompt-internal.h"
#endif

#if OMPD_SUPPORT
#include "ompd-specific.h"
#endif

#ifndef UNLIKELY
#define UNLIKELY
#endif

// Affinity format function
#include "kmp_str.h"

// 0 - no fast memory allocation, alignment: 8-byte on x86, 16-byte on x64.
// 3 - fast allocation using sync, non-sync free lists of any size, non-self
// free lists of limited size.
#ifndef USE_FAST_MEMORY
#define USE_FAST_MEMORY
#endif

#ifndef KMP_NESTED_HOT_TEAMS
#define KMP_NESTED_HOT_TEAMS
#define USE_NESTED_HOT_ARG
#else
#if KMP_NESTED_HOT_TEAMS
#define USE_NESTED_HOT_ARG(x)
#else
#define USE_NESTED_HOT_ARG
#endif
#endif

// Assume using BGET compare_exchange instruction instead of lock by default.
#ifndef USE_CMP_XCHG_FOR_BGET
#define USE_CMP_XCHG_FOR_BGET
#endif

// Test to see if queuing lock is better than bootstrap lock for bget
// #ifndef USE_QUEUING_LOCK_FOR_BGET
// #define USE_QUEUING_LOCK_FOR_BGET
// #endif

#define KMP_NSEC_PER_SEC
#define KMP_USEC_PER_SEC
#define KMP_NSEC_PER_USEC

/*!
@ingroup BASIC_TYPES
@{
*/

/*!
Values for bit flags used in the ident_t to describe the fields.
*/
enum {};

/*!
 * The ident structure that describes a source location.
 */
ident_t;
/*!
@}
*/

// Some forward declarations.
kmp_team_t;
kmp_taskdata_t;
kmp_task_team_t;
kmp_team_p;
kmp_info_p;
kmp_root_p;

template <bool C = false, bool S = true> class kmp_flag_32;
template <bool C = false, bool S = true> class kmp_flag_64;
template <bool C = false, bool S = true> class kmp_atomic_flag_64;
class kmp_flag_oncore;

#ifdef __cplusplus
extern
#endif

template <bool C, bool S>
extern void __kmp_suspend_32(int th_gtid, kmp_flag_32<C, S> *flag);
template <bool C, bool S>
extern void __kmp_suspend_64(int th_gtid, kmp_flag_64<C, S> *flag);
template <bool C, bool S>
extern void __kmp_atomic_suspend_64(int th_gtid,
                                    kmp_atomic_flag_64<C, S> *flag);
extern void __kmp_suspend_oncore(int th_gtid, kmp_flag_oncore *flag);
#if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
template <bool C, bool S>
extern void __kmp_mwait_32(int th_gtid, kmp_flag_32<C, S> *flag);
template <bool C, bool S>
extern void __kmp_mwait_64(int th_gtid, kmp_flag_64<C, S> *flag);
template <bool C, bool S>
extern void __kmp_atomic_mwait_64(int th_gtid, kmp_atomic_flag_64<C, S> *flag);
extern void __kmp_mwait_oncore(int th_gtid, kmp_flag_oncore *flag);
#endif
template <bool C, bool S>
extern void __kmp_resume_32(int target_gtid, kmp_flag_32<C, S> *flag);
template <bool C, bool S>
extern void __kmp_resume_64(int target_gtid, kmp_flag_64<C, S> *flag);
template <bool C, bool S>
extern void __kmp_atomic_resume_64(int target_gtid,
                                   kmp_atomic_flag_64<C, S> *flag);
extern void __kmp_resume_oncore(int target_gtid, kmp_flag_oncore *flag);

template <bool C, bool S>
int __kmp_execute_tasks_32(kmp_info_t *thread, kmp_int32 gtid,
                           kmp_flag_32<C, S> *flag, int final_spin,
                           int *thread_finished,
#if USE_ITT_BUILD
                           void *itt_sync_obj,
#endif /* USE_ITT_BUILD */
                           kmp_int32 is_constrained);
template <bool C, bool S>
int __kmp_execute_tasks_64(kmp_info_t *thread, kmp_int32 gtid,
                           kmp_flag_64<C, S> *flag, int final_spin,
                           int *thread_finished,
#if USE_ITT_BUILD
                           void *itt_sync_obj,
#endif /* USE_ITT_BUILD */
                           kmp_int32 is_constrained);
template <bool C, bool S>
int __kmp_atomic_execute_tasks_64(kmp_info_t *thread, kmp_int32 gtid,
                                  kmp_atomic_flag_64<C, S> *flag,
                                  int final_spin, int *thread_finished,
#if USE_ITT_BUILD
                                  void *itt_sync_obj,
#endif /* USE_ITT_BUILD */
                                  kmp_int32 is_constrained);
int __kmp_execute_tasks_oncore(kmp_info_t *thread, kmp_int32 gtid,
                               kmp_flag_oncore *flag, int final_spin,
                               int *thread_finished,
#if USE_ITT_BUILD
                               void *itt_sync_obj,
#endif /* USE_ITT_BUILD */
                               kmp_int32 is_constrained);

extern int __kmp_nesting_mode;
extern int __kmp_nesting_mode_nlevels;
extern int *__kmp_nesting_nth_level;
extern void __kmp_init_nesting_mode();
extern void __kmp_set_nesting_mode_threads();

/// This class safely opens and closes a C-style FILE* object using RAII
/// semantics. There are also methods which allow using stdout or stderr as
/// the underlying FILE* object. With the implicit conversion operator to
/// FILE*, an object with this type can be used in any function which takes
/// a FILE* object e.g., fprintf().
/// No close method is needed at use sites.
class kmp_safe_raii_file_t {};

template <typename SourceType, typename TargetType,
          bool isSourceSmaller = (sizeof(SourceType) < sizeof(TargetType)),
          bool isSourceEqual = (sizeof(SourceType) == sizeof(TargetType)),
          bool isSourceSigned = std::is_signed<SourceType>::value,
          bool isTargetSigned = std::is_signed<TargetType>::value>
struct kmp_convert {};

// Both types are signed; Source smaller
kmp_convert<SourceType, TargetType, true, false, true, true>;
// Source equal
kmp_convert<SourceType, TargetType, false, true, true, true>;
// Source bigger
kmp_convert<SourceType, TargetType, false, false, true, true>;

// Source signed, Target unsigned
// Source smaller
kmp_convert<SourceType, TargetType, true, false, true, false>;
// Source equal
kmp_convert<SourceType, TargetType, false, true, true, false>;
// Source bigger
kmp_convert<SourceType, TargetType, false, false, true, false>;

// Source unsigned, Target signed
// Source smaller
kmp_convert<SourceType, TargetType, true, false, false, true>;
// Source equal
kmp_convert<SourceType, TargetType, false, true, false, true>;
// Source bigger
kmp_convert<SourceType, TargetType, false, false, false, true>;

// Source unsigned, Target unsigned
// Source smaller
kmp_convert<SourceType, TargetType, true, false, false, false>;
// Source equal
kmp_convert<SourceType, TargetType, false, true, false, false>;
// Source bigger
kmp_convert<SourceType, TargetType, false, false, false, false>;

template <typename T1, typename T2>
static inline void __kmp_type_convert(T1 src, T2 *dest) {}

#endif /* KMP_H */