mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-06 18:00:28 +00:00
Merge branch 'master' of github.com:solisoft/cosmopolitan into feature/OnErrorHook
This commit is contained in:
commit
6a76293c4f
795 changed files with 95733 additions and 1673 deletions
6
Makefile
6
Makefile
|
@ -116,7 +116,7 @@ ZIPCOPY = build/bootstrap/zipcopy.com
|
|||
PECHECK = build/bootstrap/pecheck.com
|
||||
FIXUPOBJ = build/bootstrap/fixupobj.com
|
||||
MKDIR = build/bootstrap/mkdir.com -p
|
||||
COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
|
||||
COMPILE = build/bootstrap/compile.com -V9 -M2048m -P8192 $(QUOTA)
|
||||
|
||||
IGNORE := $(shell $(MKDIR) $(TMPDIR))
|
||||
|
||||
|
@ -286,6 +286,7 @@ include third_party/readline/BUILD.mk # │
|
|||
include third_party/libunwind/BUILD.mk # |
|
||||
include third_party/libcxxabi/BUILD.mk # |
|
||||
include third_party/libcxx/BUILD.mk # │
|
||||
include third_party/openmp/BUILD.mk # │
|
||||
include third_party/double-conversion/BUILD.mk # │
|
||||
include third_party/pcre/BUILD.mk # │
|
||||
include third_party/less/BUILD.mk # │
|
||||
|
@ -441,6 +442,7 @@ COSMOPOLITAN_OBJECTS = \
|
|||
THIRD_PARTY_GETOPT \
|
||||
LIBC_LOG \
|
||||
LIBC_TIME \
|
||||
THIRD_PARTY_OPENMP \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_ZLIB_GZ \
|
||||
THIRD_PARTY_LIBCXXABI \
|
||||
|
@ -522,6 +524,8 @@ COSMOCC_PKGS = \
|
|||
THIRD_PARTY_AARCH64 \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_LIBCXXABI \
|
||||
THIRD_PARTY_LIBUNWIND \
|
||||
THIRD_PARTY_OPENMP \
|
||||
THIRD_PARTY_INTEL
|
||||
|
||||
o/$(MODE)/cosmopolitan.a: \
|
||||
|
|
10
ape/BUILD.mk
10
ape/BUILD.mk
|
@ -173,8 +173,6 @@ o/$(MODE)/ape/ape-no-modify-self.o: \
|
|||
libc/runtime/mman.internal.h \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/sysv/consts/prot.h \
|
||||
ape/blink-linux-aarch64.gz \
|
||||
ape/blink-xnu-aarch64.gz \
|
||||
o/$(MODE)/ape/ape.elf
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
|
@ -202,9 +200,7 @@ o/$(MODE)/ape/ape-copy-self.o: \
|
|||
libc/runtime/e820.internal.h \
|
||||
libc/runtime/mman.internal.h \
|
||||
libc/runtime/pc.internal.h \
|
||||
libc/sysv/consts/prot.h \
|
||||
ape/blink-linux-aarch64.gz \
|
||||
ape/blink-xnu-aarch64.gz
|
||||
libc/sysv/consts/prot.h
|
||||
@$(COMPILE) \
|
||||
-AOBJECTIFY.S \
|
||||
$(OBJECTIFY.S) \
|
||||
|
@ -263,10 +259,6 @@ endif
|
|||
o/$(MODE)/ape/ape.o: ape/ape.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
o/$(MODE)/ape/ape.o: \
|
||||
ape/blink-linux-aarch64.gz \
|
||||
ape/blink-xnu-aarch64.gz
|
||||
|
||||
o/$(MODE)/ape/ape.lds: \
|
||||
ape/ape.lds \
|
||||
ape/macros.internal.h \
|
||||
|
|
31
ape/ape.S
31
ape/ape.S
|
@ -700,36 +700,9 @@ apesh: .ascii "\n@\n#'\"\n" // sixth edition shebang
|
|||
#endif /* APE_NO_MODIFY_SELF */
|
||||
.ascii "exit $?\n"
|
||||
.ascii "fi\n" // x86_64
|
||||
// ...
|
||||
// decentralized section (.apesh)
|
||||
// ...
|
||||
.ascii "PHDRS='' <<'@'\n"
|
||||
.endobj apesh
|
||||
|
||||
// elf program headers get inserted here
|
||||
// because they need to be in the first 4096 bytes
|
||||
.section .emushprologue,"a",@progbits
|
||||
emush: .ascii "\n@\n#'\"\n"
|
||||
.ascii "s=$(uname -s 2>/dev/null) || s=Darwin\n"
|
||||
// our script is running on a non-x86_64 architecture
|
||||
// 1. `dd` out the appropriate blink vm blob
|
||||
// 2. gunzip the blink virtual machine executable
|
||||
// 3. relaunch this program inside the blink vm
|
||||
.ascii "o=\"$(command -v \"$0\")\"\n"
|
||||
.ascii "e=\"${TMPDIR:-${HOME:-.}}/.ape-blink-1.0.0\"\n"
|
||||
.previous
|
||||
// ...
|
||||
// decentralized section (.emush)
|
||||
// - __static_yoink("blink_linux_aarch64"); // for raspberry pi
|
||||
// - __static_yoink("blink_xnu_aarch64"); // is apple silicon
|
||||
// ...
|
||||
.section .emushepilogue,"a",@progbits
|
||||
.ascii "echo \"$0: this ape binary lacks $m support\" >&2\n"
|
||||
.rept 16
|
||||
.ascii "exit 127\n"
|
||||
.endr
|
||||
.ascii "echo error: this ape binary only supports x86_64 >&2\n"
|
||||
.ascii "exit 1\n"
|
||||
.previous
|
||||
.endobj apesh
|
||||
|
||||
#ifdef APE_LOADER
|
||||
.section .ape.loader,"a",@progbits
|
||||
|
|
29
ape/ape.lds
29
ape/ape.lds
|
@ -229,7 +229,6 @@ SECTIONS {
|
|||
|
||||
/* Real Mode */
|
||||
KEEP(*(.head))
|
||||
KEEP(*(.apesh))
|
||||
KEEP(*(.text.head))
|
||||
|
||||
/* Executable & Linkable Format */
|
||||
|
@ -238,10 +237,6 @@ SECTIONS {
|
|||
KEEP(*(.elf.phdrs))
|
||||
ape_phdrs_end = .;
|
||||
|
||||
KEEP(*(.emushprologue))
|
||||
KEEP(*(.emush))
|
||||
KEEP(*(.emushepilogue))
|
||||
|
||||
/* OpenBSD */
|
||||
. = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0);
|
||||
ape_note = .;
|
||||
|
@ -301,7 +296,6 @@ SECTIONS {
|
|||
KEEP(*(.textwindowsprologue))
|
||||
*(.text.windows)
|
||||
KEEP(*(.textwindowsepilogue))
|
||||
KEEP(*(.blink))
|
||||
*(SORT_BY_ALIGNMENT(.text.modernity))
|
||||
*(SORT_BY_ALIGNMENT(.text.modernity.*))
|
||||
*(SORT_BY_ALIGNMENT(.text.hot))
|
||||
|
@ -613,29 +607,6 @@ SHSTUB2(ape_loader_dd_count,
|
|||
? ROUNDUP(ape_loader_end - ape_loader, CONSTANT(COMMONPAGESIZE)) / 64
|
||||
: 0);
|
||||
|
||||
#if defined(APE_IS_SHELL_SCRIPT) && !IsTiny()
|
||||
|
||||
#define IDENTITY(X) X
|
||||
|
||||
#define APE_DECLARE_FIXED_DECIMAL(F, X) \
|
||||
X##_quad = DEFINED(X) ? ((F(X) < 1000000000 ? 32 : F(X) / 1000000000 % 10 + 48) << 000 | \
|
||||
(F(X) < 100000000 ? 32 : F(X) / 100000000 % 10 + 48) << 010 | \
|
||||
(F(X) < 10000000 ? 32 : F(X) / 10000000 % 10 + 48) << 020 | \
|
||||
(F(X) < 1000000 ? 32 : F(X) / 1000000 % 10 + 48) << 030 | \
|
||||
(F(X) < 100000 ? 32 : F(X) / 100000 % 10 + 48) << 040 | \
|
||||
(F(X) < 10000 ? 32 : F(X) / 10000 % 10 + 48) << 050 | \
|
||||
(F(X) < 1000 ? 32 : F(X) / 1000 % 10 + 48) << 060 | \
|
||||
(F(X) < 100 ? 32 : F(X) / 100 % 10 + 48) << 070) : 0; \
|
||||
X##_short = DEFINED(X) ? ((F(X) < 10 ? 32 : F(X) / 10 % 10 + 48) << 000 | \
|
||||
(F(X) % 10 + 48) << 010) : 0
|
||||
|
||||
APE_DECLARE_FIXED_DECIMAL(RVA, blink_linux_aarch64);
|
||||
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_linux_aarch64_size);
|
||||
APE_DECLARE_FIXED_DECIMAL(RVA, blink_xnu_aarch64);
|
||||
APE_DECLARE_FIXED_DECIMAL(IDENTITY, blink_xnu_aarch64_size);
|
||||
|
||||
#endif /* APE_IS_SHELL_SCRIPT */
|
||||
|
||||
#if SupportsMetal()
|
||||
v_ape_realsectors = MIN(0x70000 - IMAGE_BASE_REAL, ROUNDUP(RVA(_ezip), 512)) / 512;
|
||||
v_ape_realbytes = v_ape_realsectors * 512;
|
||||
|
|
|
@ -59,9 +59,7 @@ for x in .ape \
|
|||
.ape-1.7 \
|
||||
.ape-1.8 \
|
||||
.ape-1.9 \
|
||||
.ape-1.10 \
|
||||
.ape-blink-0.9.2 \
|
||||
.ape-blink-1.0.0; do
|
||||
.ape-1.10; do
|
||||
rm -f \
|
||||
~/$x \
|
||||
/tmp/$x \
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -40,6 +40,9 @@ o/$(MODE)/%.h: %.c
|
|||
o/$(MODE)/%.o: %.cc
|
||||
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%.o: %.cpp
|
||||
@$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
|
||||
|
||||
o/$(MODE)/%.lds: %.lds
|
||||
@$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
|
||||
|
||||
|
|
|
@ -152,7 +152,6 @@ o/$(MODE)/examples/picol.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/nesemu1.o: private QUOTA += -M512m
|
||||
o/$(MODE)/usr/share/dict/words.zip.o: private ZIPOBJ_FLAGS += -C2
|
||||
|
||||
$(EXAMPLES_OBJS): examples/BUILD.mk
|
||||
|
|
|
@ -142,6 +142,9 @@ libc/isystem/nsync_once.h \
|
|||
libc/isystem/nsync_time.h \
|
||||
libc/isystem/nsync_waiter.h \
|
||||
libc/isystem/numeric \
|
||||
libc/isystem/omp-tools.h \
|
||||
libc/isystem/omp.h \
|
||||
libc/isystem/ompx.h \
|
||||
libc/isystem/optional \
|
||||
libc/isystem/ostream \
|
||||
libc/isystem/paths.h \
|
||||
|
@ -251,6 +254,7 @@ libc/isystem/uio.h \
|
|||
libc/isystem/unistd.h \
|
||||
libc/isystem/unordered_map \
|
||||
libc/isystem/unordered_set \
|
||||
libc/isystem/unwind.h \
|
||||
libc/isystem/utility \
|
||||
libc/isystem/utime.h \
|
||||
libc/isystem/utmp.h \
|
||||
|
@ -273,6 +277,8 @@ LIBC_INCS = $(filter %.inc,$(LIBC_FILES))
|
|||
LIBC_CHECKS = $(LIBC_HDRS_H:%=o/$(MODE)/%.ok)
|
||||
LIBC_FILES := $(wildcard libc/*)
|
||||
|
||||
o/$(MODE)/libc/isystem/ompx.h.ok: private CPPFLAGS += -Wno-unknown-pragmas
|
||||
|
||||
.PHONY: o/$(MODE)/libc
|
||||
o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
||||
o/$(MODE)/libc/crt \
|
||||
|
|
|
@ -24,11 +24,15 @@
|
|||
/**
|
||||
* Returns true if process is running under qemu-x86_64 or qemu-aarch64.
|
||||
*/
|
||||
int IsQemu(void) {
|
||||
int IsQemuUser(void) {
|
||||
static char rplus1;
|
||||
if (!rplus1) {
|
||||
// qemu doesn't validate the advice argument
|
||||
// we could also check if __getcwd(0, 0) raises efault
|
||||
int e = errno;
|
||||
int r = !sys_madvise(__executable_start, 16384, 127);
|
||||
errno = e;
|
||||
return r;
|
||||
rplus1 = r + 1;
|
||||
}
|
||||
return rplus1 - 1;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2024 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
|
@ -16,43 +16,32 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/cpuset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/rdtscp.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/nt/struct/processornumber.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
|
||||
// Blink Virtual Machine for Apple Silicon
|
||||
//
|
||||
// If you want to support Apple M1 by embedding an emulator in
|
||||
// your APE binary that runs automatically, then put this:
|
||||
//
|
||||
// __static_yoink("blink_xnu_aarch64");
|
||||
//
|
||||
// In your main.c file, to pull it into linkage from the static
|
||||
// archive. Alternatively, you may simply add blink_xnu_aarch64.o
|
||||
// as an explicit linker argument.
|
||||
int sys_getcpu(unsigned *opt_cpu, unsigned *opt_node, void *tcache);
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_xnu_aarch64_size
|
||||
blink_xnu_aarch64:
|
||||
.incbin "ape/blink-xnu-aarch64.gz"
|
||||
.endobj blink_xnu_aarch64,globl
|
||||
blink_xnu_aarch64_size = . - blink_xnu_aarch64
|
||||
|
||||
.section .emush,"a",@progbits
|
||||
.ascii "if [ \"$s\" = Darwin ] && [ \"$m\" = arm64 ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-darwin-aarch64 to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.weak blink_xnu_aarch64_quad
|
||||
.quad blink_xnu_aarch64_quad
|
||||
.weak blink_xnu_aarch64_short
|
||||
.short blink_xnu_aarch64_short
|
||||
.ascii ")) count=$(("
|
||||
.weak blink_xnu_aarch64_size_quad
|
||||
.quad blink_xnu_aarch64_size_quad
|
||||
.weak blink_xnu_aarch64_size_short
|
||||
.short blink_xnu_aarch64_size_short
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
/**
|
||||
* Returns ID of CPU on which thread is currently scheduled.
|
||||
*/
|
||||
int sched_getcpu(void) {
|
||||
if (X86_HAVE(RDTSCP)) {
|
||||
unsigned tsc_aux;
|
||||
rdtscp(&tsc_aux);
|
||||
return TSC_AUX_CORE(tsc_aux);
|
||||
} else if (IsWindows()) {
|
||||
struct NtProcessorNumber pn;
|
||||
GetCurrentProcessorNumberEx(&pn);
|
||||
return 64 * pn.Group + pn.Number;
|
||||
} else {
|
||||
unsigned cpu = 0;
|
||||
int rc = sys_getcpu(&cpu, 0, 0);
|
||||
if (rc == -1) return -1;
|
||||
return cpu;
|
||||
}
|
||||
}
|
|
@ -53,5 +53,7 @@ int CPU_COUNT_S(size_t, const cpu_set_t *) libcesque;
|
|||
#define CPU_CLR_S(i, size, set) _CPU_S(i, size, set, &= ~)
|
||||
#define CPU_ISSET_S(i, size, set) _CPU_S(i, size, set, &)
|
||||
|
||||
typedef cpu_set_t cpuset_t; /* for freebsd compatibility */
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_CPUSET_H_ */
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace __cxxabiv1 {
|
|||
|
||||
char *__cxa_demangle(const char *, char *, size_t *, int *);
|
||||
int __cxa_atexit(void (*)(void *), void *, void *) paramsnonnull((1)) dontthrow;
|
||||
int __cxa_thread_atexit(void *, void *, void *) dontthrow;
|
||||
int __cxa_thread_atexit(void (*)(void *), void *, void *) dontthrow;
|
||||
void __cxa_finalize(void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -121,7 +121,7 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
extern const int __hostos;
|
||||
|
||||
int IsQemu(void);
|
||||
int IsQemuUser(void);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -649,8 +649,9 @@ void abort(void) wontreturn;
|
|||
#pragma GCC diagnostic ignored "-Wformat-extra-args" /* todo: patch gcc */
|
||||
#pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce */
|
||||
#pragma GCC diagnostic ignored "-Wunused-const-variable" /* sooo ridiculous */
|
||||
#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
|
||||
#ifndef __cplusplus
|
||||
#pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bulls */
|
||||
#pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bullsh */
|
||||
#endif
|
||||
|
||||
#ifndef __STRICT_ANSI__
|
||||
|
|
|
@ -103,7 +103,7 @@ void __get_main_stack(void **out_addr, size_t *out_size, int *out_guardsize) {
|
|||
if (IsWindows()) {
|
||||
*out_addr = (void *)GetStaticStackAddr(0);
|
||||
*out_size = GetStaticStackSize();
|
||||
*out_guardsize = GetGuardSize();
|
||||
*out_guardsize = getauxval(AT_PAGESZ);
|
||||
return;
|
||||
}
|
||||
int pagesz = getauxval(AT_PAGESZ);
|
||||
|
|
|
@ -45,7 +45,7 @@ int gettid(void) {
|
|||
}
|
||||
}
|
||||
if (IsXnuSilicon()) {
|
||||
return enosys();
|
||||
return enosys(); // can only happen if we can't access thread local storage
|
||||
} else {
|
||||
return sys_gettid();
|
||||
}
|
||||
|
|
|
@ -112,6 +112,13 @@ struct UbsanOverflowData {
|
|||
struct UbsanTypeDescriptor *type;
|
||||
};
|
||||
|
||||
struct UbsanDynamicTypeCacheMissData {
|
||||
struct UbsanSourceLocation location;
|
||||
struct UbsanTypeDescriptor *type;
|
||||
void *TypeInfo;
|
||||
unsigned char TypeCheckKind;
|
||||
};
|
||||
|
||||
struct UbsanFloatCastOverflowData {
|
||||
#if __GNUC__ + 0 >= 6
|
||||
struct UbsanSourceLocation location;
|
||||
|
@ -145,6 +152,8 @@ upcast of\0\
|
|||
cast to virtual base of\0\
|
||||
\0";
|
||||
|
||||
uintptr_t __ubsan_vptr_type_cache[128];
|
||||
|
||||
static int __ubsan_bits(struct UbsanTypeDescriptor *t) {
|
||||
return 1 << (t->info >> 1);
|
||||
}
|
||||
|
@ -439,15 +448,22 @@ void __ubsan_handle_divrem_overflow_abort(
|
|||
__ubsan_handle_divrem_overflow(loc);
|
||||
}
|
||||
|
||||
static bool HandleDynamicTypeCacheMiss(
|
||||
struct UbsanDynamicTypeCacheMissData *data, uintptr_t ptr, uintptr_t hash) {
|
||||
return false; // TODO: implement me
|
||||
}
|
||||
|
||||
void __ubsan_handle_dynamic_type_cache_miss(
|
||||
const struct UbsanSourceLocation *loc) {
|
||||
__ubsan_abort(loc, "dynamic type cache miss")();
|
||||
__ubsan_unreachable();
|
||||
struct UbsanDynamicTypeCacheMissData *data, uintptr_t ptr, uintptr_t hash) {
|
||||
HandleDynamicTypeCacheMiss(data, ptr, hash);
|
||||
}
|
||||
|
||||
void __ubsan_handle_dynamic_type_cache_miss_abort(
|
||||
const struct UbsanSourceLocation *loc) {
|
||||
__ubsan_handle_dynamic_type_cache_miss(loc);
|
||||
struct UbsanDynamicTypeCacheMissData *data, uintptr_t ptr, uintptr_t hash) {
|
||||
if (HandleDynamicTypeCacheMiss(data, ptr, hash)) {
|
||||
__ubsan_abort(&data->location, "dynamic type cache miss")();
|
||||
__ubsan_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void __ubsan_handle_function_type_mismatch(
|
||||
|
|
3
libc/isystem/omp-tools.h
Normal file
3
libc/isystem/omp-tools.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#ifndef _OMP_TOOLS_H
|
||||
#include "third_party/openmp/omp-tools.h"
|
||||
#endif /* _OMP_TOOLS_H */
|
3
libc/isystem/omp.h
Normal file
3
libc/isystem/omp.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#ifndef _OMP_H
|
||||
#include "third_party/openmp/omp.h"
|
||||
#endif /* _OMP_H */
|
3
libc/isystem/ompx.h
Normal file
3
libc/isystem/ompx.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
#ifndef _OMPX_H
|
||||
#include "third_party/openmp/ompx.h"
|
||||
#endif /* _OMPX_H */
|
4
libc/isystem/unwind.h
Normal file
4
libc/isystem/unwind.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef _UNWIND_H
|
||||
#define _UNWIND_H
|
||||
#include "third_party/libunwind/include/unwind.h"
|
||||
#endif /* _UNWIND_H */
|
|
@ -1,60 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│ vi: set noet ft=asm ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2023 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
// Blink Virtual Machine for Linux Arm64
|
||||
//
|
||||
// If you want to support Raspberry Pi by embedding an emulator
|
||||
// in your APE binary that runs automatically, then put this:
|
||||
//
|
||||
// __static_yoink("blink_linux_aarch64");
|
||||
//
|
||||
// In your main.c file, to pull it into linkage from the static
|
||||
// archive. Alternatively, you may simply add blink_linux_aarch64.o
|
||||
// as an explicit linker argument.
|
||||
|
||||
.section .blink,"a",@progbits
|
||||
.globl blink_linux_aarch64_size
|
||||
blink_linux_aarch64:
|
||||
.incbin "ape/blink-linux-aarch64.gz"
|
||||
.endobj blink_linux_aarch64,globl
|
||||
blink_linux_aarch64_size = . - blink_linux_aarch64
|
||||
|
||||
.section .emush,"a",@progbits
|
||||
.ascii "if [ \"$s\" = Linux ]; then\n"
|
||||
.ascii "if [ \"$m\" = aarch64 ] || [ \"$m\" = arm64 ]; then\n"
|
||||
.ascii "if ! [ -x \"$e\" ]; then\n"
|
||||
.ascii "echo \"extracting blink-linux-aarch64 to ${e}\" >&2\n"
|
||||
.ascii "dd if=\"$o\" bs=1 skip=$(("
|
||||
.weak blink_linux_aarch64_quad
|
||||
.quad blink_linux_aarch64_quad
|
||||
.weak blink_linux_aarch64_short
|
||||
.short blink_linux_aarch64_short
|
||||
.ascii ")) count=$(("
|
||||
.weak blink_linux_aarch64_size_quad
|
||||
.quad blink_linux_aarch64_size_quad
|
||||
.weak blink_linux_aarch64_size_short
|
||||
.short blink_linux_aarch64_size_short
|
||||
.ascii ")) conv=notrunc 2>/dev/null | gunzip >\"$e.$$\"\n"
|
||||
.ascii "mv -f \"$e.$$\" \"$e\"\n"
|
||||
.ascii "chmod +x \"$e\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "exec \"$e\" \"$o\" \"$@\"\n"
|
||||
.ascii "fi\n"
|
||||
.ascii "fi\n"
|
|
@ -31,28 +31,38 @@
|
|||
// are quite toilsome.
|
||||
//
|
||||
// @see www.felixcloutier.com/x86/cpuid
|
||||
kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info)
|
||||
.long 0,0,0,0 # EAX=1 (Processor Info)
|
||||
.long 0,0,0,0 # EAX=2
|
||||
.long 0,0,0,0 # EAX=7 (Extended Features)
|
||||
.long 0,0,0,0 # EAX=0x80000001 (NexGen32e)
|
||||
.long 0,0,0,0 # EAX=0x80000007 (APM)
|
||||
.long 0,0,0,0 # EAX=16h (CPU Frequency)
|
||||
kCpuids:.long 0,0,0,0 // EAX=0 (Basic Processor Info)
|
||||
.long 0,0,0,0 // EAX=1 (Processor Info)
|
||||
.long 0,0,0,0 // EAX=2
|
||||
.long 0,0,0,0 // EAX=7 (Extended Features)
|
||||
.long 0,0,0,0 // EAX=0x80000001 (NexGen32e)
|
||||
.long 0,0,0,0 // EAX=0x80000007 (APM)
|
||||
.long 0,0,0,0 // EAX=16h (CPU Frequency)
|
||||
.long 0,0,0,0 // EAX=7 ECX=1 (Extended Feats)
|
||||
.endobj kCpuids,globl
|
||||
.previous
|
||||
|
||||
.init.start 201,_init_kCpuids
|
||||
push %rbx
|
||||
push $0
|
||||
push $0x16
|
||||
push $0xffffffff80000007
|
||||
push $0xffffffff80000001
|
||||
push $1
|
||||
push $7
|
||||
push $0
|
||||
push $0x16
|
||||
push $0
|
||||
push $0xffffffff80000007
|
||||
push $0
|
||||
push $0xffffffff80000001
|
||||
push $0
|
||||
push $7
|
||||
push $0
|
||||
push $2
|
||||
push $0
|
||||
push $1
|
||||
mov %rdi,%r8
|
||||
xor %eax,%eax
|
||||
1: xor %ecx,%ecx
|
||||
xor %ecx,%ecx
|
||||
1: nop
|
||||
#ifdef FEATURELESS
|
||||
// It's been reported that GDB reverse debugging doesn't
|
||||
// understand VEX encoding. The workaround is to put:
|
||||
|
@ -62,6 +72,7 @@ kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info)
|
|||
// Inside your ~/.cosmo.mk file.
|
||||
xor %eax,%eax
|
||||
xor %ebx,%ebx
|
||||
xor %ecx,%ecx
|
||||
xor %edx,%edx
|
||||
#else
|
||||
cpuid
|
||||
|
@ -74,10 +85,11 @@ kCpuids:.long 0,0,0,0 # EAX=0 (Basic Processor Info)
|
|||
xchg %eax,%edx
|
||||
stosl
|
||||
2: pop %rax
|
||||
test %eax,%eax # EAX = stacklist->pop()
|
||||
jz 3f # EAX ≠ 0 (EOL sentinel)
|
||||
cmp KCPUIDS(0H,EAX)(%r8),%al # EAX ≤ CPUID.0 max leaf
|
||||
jbe 1b # CPUID too new to probe
|
||||
test %eax,%eax // EAX = stacklist->pop()
|
||||
jz 3f // EAX ≠ 0 (EOL sentinel)
|
||||
pop %rcx // HERE WE GO AGAIN CPUID
|
||||
cmp KCPUIDS(0H,EAX)(%r8),%al // EAX ≤ CPUID.0 max leaf
|
||||
jbe 1b // CPUID too new to probe
|
||||
add $4*4,%rdi
|
||||
jmp 2b
|
||||
3: nop
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
#define KCPUIDS_80000001H 4
|
||||
#define KCPUIDS_80000007H 5
|
||||
#define KCPUIDS_16H 6
|
||||
#define KCPUIDS_LEN 7
|
||||
#define KCPUIDS_7H_1H 7
|
||||
#define KCPUIDS_LEN 8
|
||||
#define KCPUIDS_6H -1 /* TBD: Thermal and Power Management */
|
||||
#define KCPUIDS_DH -1 /* TBD: Extended state features */
|
||||
#define KCPUIDS_80000008H -1 /* TBD: AMD Miscellaneous */
|
||||
|
|
|
@ -18,8 +18,8 @@ COSMOPOLITAN_C_START_
|
|||
*/
|
||||
#define rdtscp(OPT_OUT_IA32_TSC_AUX) \
|
||||
({ \
|
||||
uint64_t Rax, Rdx; \
|
||||
uint32_t Ecx, *EcxOut; \
|
||||
uint64_t Rax, Rcx, Rdx; \
|
||||
asm volatile("rdtscp" \
|
||||
: "=a"(Rax), "=c"(Ecx), "=d"(Rdx) \
|
||||
: /* no inputs */ \
|
||||
|
|
|
@ -37,6 +37,18 @@
|
|||
#define _X86_CC_AVXVNNI 0
|
||||
#endif
|
||||
|
||||
#ifdef __AVXVNNIINT8__
|
||||
#define _X86_CC_AVXVNNIINT8 1
|
||||
#else
|
||||
#define _X86_CC_AVXVNNIINT8 0
|
||||
#endif
|
||||
|
||||
#ifdef __AVXVNNIINT16__
|
||||
#define _X86_CC_AVXVNNIINT16 1
|
||||
#else
|
||||
#define _X86_CC_AVXVNNIINT16 0
|
||||
#endif
|
||||
|
||||
#ifdef __AVX512F__
|
||||
#define _X86_CC_AVX512F 1
|
||||
#else
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#define X86_ARCH_CAPABILITIES 7H, EDX, 29, 0
|
||||
#define X86_AVX 1H, ECX, 28, _X86_CC_AVX /* sandybridge c. 2012 */
|
||||
#define X86_AVX2 7H, EBX, 5, _X86_CC_AVX2 /* haswell c. 2013 */
|
||||
#define X86_AVXVNNI 7H, EAX, 4, _X86_CC_AVXVNNI
|
||||
#define X86_AVXVNNI 7H_1H, EAX, 4, _X86_CC_AVXVNNI
|
||||
#define X86_AVXVNNIINT8 7H_1H, EDX, 4, _X86_CC_AVXVNNIINT8
|
||||
#define X86_AVXVNNIINT16 7H_1H, EDX, 10, _X86_CC_AVXVNNIINT16
|
||||
#define X86_AVX512BW 7H, EBX, 30, 0
|
||||
#define X86_AVX512CD 7H, EBX, 28, 0
|
||||
#define X86_AVX512DQ 7H, EBX, 17, 0
|
||||
|
|
20
libc/nt/kernel32/GetCurrentProcessorNumberEx.S
Normal file
20
libc/nt/kernel32/GetCurrentProcessorNumberEx.S
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "libc/nt/codegen.h"
|
||||
.imp kernel32,__imp_GetCurrentProcessorNumberEx,GetCurrentProcessorNumberEx
|
||||
|
||||
.text.windows
|
||||
.ftrace1
|
||||
GetCurrentProcessorNumberEx:
|
||||
.ftrace2
|
||||
#ifdef __x86_64__
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
mov %rdi,%rcx
|
||||
sub $32,%rsp
|
||||
call *__imp_GetCurrentProcessorNumberEx(%rip)
|
||||
leave
|
||||
#elif defined(__aarch64__)
|
||||
mov x0,#0
|
||||
#endif
|
||||
ret
|
||||
.endfn GetCurrentProcessorNumberEx,globl
|
||||
.previous
|
|
@ -109,6 +109,7 @@ imp 'GetConsoleTitle' GetConsoleTitleW kernel32 2
|
|||
imp 'GetConsoleWindow' GetConsoleWindow kernel32 0
|
||||
imp 'GetCurrentDirectory' GetCurrentDirectoryW kernel32 2
|
||||
imp 'GetCurrentProcessId' GetCurrentProcessId kernel32 0
|
||||
imp 'GetCurrentProcessorNumberEx' GetCurrentProcessorNumberEx kernel32 1
|
||||
imp 'GetCurrentThread' GetCurrentThread kernel32 0
|
||||
imp 'GetCurrentThreadId' GetCurrentThreadId kernel32 0
|
||||
imp 'GetEnvironmentStrings' GetEnvironmentStringsW kernel32 1
|
||||
|
|
12
libc/nt/struct/processornumber.h
Normal file
12
libc/nt/struct/processornumber.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSORNUMBER_H_
|
||||
#define COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSORNUMBER_H_
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct NtProcessorNumber {
|
||||
uint16_t Group;
|
||||
uint8_t Number;
|
||||
uint8_t Reserved;
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PROCESSORNUMBER_H_ */
|
|
@ -4,6 +4,7 @@
|
|||
#include "libc/nt/struct/criticalsection.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/nt/struct/linkedlist.h"
|
||||
#include "libc/nt/struct/processornumber.h"
|
||||
#include "libc/nt/struct/securityattributes.h"
|
||||
#include "libc/nt/struct/systemtime.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
|
@ -115,6 +116,8 @@ bool32 GetSystemTimeAdjustment(uint32_t *lpTimeAdjustment,
|
|||
uint32_t *lpTimeIncrement,
|
||||
bool32 *lpTimeAdjustmentDisabled);
|
||||
|
||||
void GetCurrentProcessorNumberEx(struct NtProcessorNumber *out_ProcNumber);
|
||||
|
||||
#if ShouldUseMsabiAttribute()
|
||||
#include "libc/nt/thunk/synchronization.inc"
|
||||
#endif /* ShouldUseMsabiAttribute() */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
|
@ -42,10 +43,13 @@
|
|||
void *NewCosmoStack(void) {
|
||||
char *p;
|
||||
if ((p = mmap(0, GetStackSize(), PROT_READ | PROT_WRITE,
|
||||
MAP_STACK | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) {
|
||||
MAP_ANONYMOUS |
|
||||
(IsAarch64() && IsLinux() && IsQemuUser() ? MAP_PRIVATE
|
||||
: MAP_STACK),
|
||||
-1, 0)) != MAP_FAILED) {
|
||||
if (IsAsan()) {
|
||||
__asan_poison(p + GetStackSize() - 16, 16, kAsanStackOverflow);
|
||||
__asan_poison(p, GetGuardSize(), kAsanStackOverflow);
|
||||
__asan_poison(p, getauxval(AT_PAGESZ), kAsanStackOverflow);
|
||||
}
|
||||
return p;
|
||||
} else {
|
||||
|
|
|
@ -96,7 +96,7 @@ static void __zipos_generate_index(struct Zipos *zipos) {
|
|||
zipos->index[i] = c;
|
||||
}
|
||||
// smoothsort() isn't the fastest algorithm, but it guarantees
|
||||
// o(logn), won't smash the stack and doesn't depend on malloc
|
||||
// o(nlogn) won't smash the stack and doesn't depend on malloc
|
||||
smoothsort_r(zipos->index, zipos->records, sizeof(size_t),
|
||||
__zipos_compare_names, zipos);
|
||||
}
|
||||
|
|
22
libc/sock/in6addr_any.c
Normal file
22
libc/sock/in6addr_any.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2024 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/sock/struct/sockaddr6.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
|
||||
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
22
libc/sock/in6addr_loopback.c
Normal file
22
libc/sock/in6addr_loopback.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2024 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/sock/struct/sockaddr6.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
|
||||
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
|
|
@ -17,4 +17,7 @@ struct sockaddr_in6 { /* Linux+NT ABI */
|
|||
uint32_t sin6_scope_id; /* rfc2553 */
|
||||
};
|
||||
|
||||
extern const struct in6_addr in6addr_any;
|
||||
extern const struct in6_addr in6addr_loopback;
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SOCKADDR6_H_ */
|
||||
|
|
|
@ -237,7 +237,8 @@ int __vcscanf(int callback(void *), //
|
|||
case 'F':
|
||||
case 'g':
|
||||
case 'G': // floating point number
|
||||
if (!(charbytes == sizeof(char) || charbytes == sizeof(wchar_t))) {
|
||||
if (!(charbytes == sizeof(char) ||
|
||||
charbytes == sizeof(wchar_t))) {
|
||||
items = -1;
|
||||
goto Done;
|
||||
}
|
||||
|
@ -361,7 +362,8 @@ int __vcscanf(int callback(void *), //
|
|||
c = BUFFER;
|
||||
do {
|
||||
bool isdigit = c >= '0' && c <= '9';
|
||||
bool isletter = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
bool isletter =
|
||||
(c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
if (!(c == '_' || isdigit || isletter)) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -485,7 +487,11 @@ int __vcscanf(int callback(void *), //
|
|||
continue;
|
||||
ReportConsumed:
|
||||
n_ptr = va_arg(va, int *);
|
||||
if (c != -1) {
|
||||
*n_ptr = consumed - 1; // minus lookahead
|
||||
} else {
|
||||
*n_ptr = consumed;
|
||||
}
|
||||
continue;
|
||||
DecodeString:
|
||||
bufsize = !width ? 32 : rawmode ? width : width + 1;
|
||||
|
|
|
@ -9,9 +9,9 @@ COSMOPOLITAN_C_START_
|
|||
typedef int nl_item;
|
||||
typedef void *nl_catd;
|
||||
|
||||
nl_catd catopen(const char *, int) libcesque;
|
||||
char *catgets(nl_catd, int, int, const char *) libcesque;
|
||||
int catclose(nl_catd) libcesque;
|
||||
nl_catd catopen(const char *, int);
|
||||
char *catgets(nl_catd, int, int, const char *);
|
||||
int catclose(nl_catd);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_NLTYPES_H_ */
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
│ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS │
|
||||
│ IN THE SOFTWARE. │
|
||||
└─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/bsf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/mem/alg.h"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
errno_t pthread_attr_init(pthread_attr_t *attr) {
|
||||
*attr = (pthread_attr_t){
|
||||
.__stacksize = GetStackSize(),
|
||||
.__guardsize = GetGuardSize(),
|
||||
.__guardsize = getauxval(AT_PAGESZ),
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -175,6 +175,7 @@ static errno_t pthread_create_impl(pthread_t *thread,
|
|||
errno = e;
|
||||
return EAGAIN;
|
||||
}
|
||||
dll_init(&pt->list);
|
||||
pt->pt_start = start_routine;
|
||||
pt->pt_arg = arg;
|
||||
|
||||
|
@ -215,7 +216,9 @@ static errno_t pthread_create_impl(pthread_t *thread,
|
|||
_pthread_free(pt, false);
|
||||
return EINVAL;
|
||||
}
|
||||
if (pt->pt_attr.__guardsize == pagesize) {
|
||||
if (pt->pt_attr.__guardsize == pagesize &&
|
||||
!(IsAarch64() && IsLinux() && IsQemuUser())) {
|
||||
// MAP_GROWSDOWN doesn't work very well on qemu-aarch64
|
||||
pt->pt_attr.__stackaddr =
|
||||
mmap(0, pt->pt_attr.__stacksize, PROT_READ | PROT_WRITE,
|
||||
MAP_STACK | MAP_ANONYMOUS, -1, 0);
|
||||
|
@ -289,7 +292,6 @@ static errno_t pthread_create_impl(pthread_t *thread,
|
|||
|
||||
// add thread to global list
|
||||
// we add it to the beginning since zombies go at the end
|
||||
dll_init(&pt->list);
|
||||
_pthread_lock();
|
||||
dll_make_first(&_pthread_list, &pt->list);
|
||||
_pthread_unlock();
|
||||
|
|
|
@ -38,6 +38,7 @@ static const char *DescribeReturnValue(char buf[30], int err, void **value) {
|
|||
*p++ = '[';
|
||||
p = FormatHex64(p, (uintptr_t)*value, 1);
|
||||
*p++ = ']';
|
||||
*p = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ void SetUpOnce(void) {
|
|||
}
|
||||
|
||||
TEST(__getcwd, zero) {
|
||||
if (IsQemu()) return;
|
||||
if (IsQemuUser()) return;
|
||||
ASSERT_SYS(ERANGE, -1, __getcwd(0, 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ TEST(GetProramExecutableName, weirdArgv0NullEnv) {
|
|||
|
||||
TEST(GetProgramExecutableName, movedSelf) {
|
||||
if (skiptests) return;
|
||||
if (IsAarch64() && IsQemu()) {
|
||||
if (IsAarch64() && IsQemuUser()) {
|
||||
// clang-format off
|
||||
// TODO(mrdomino): fix: make -j8 m=aarch64 o/aarch64/test/libc/calls/getprogramexecutablename_test.com.ok
|
||||
// possibly related to the intersection of binfmt_misc and qemu-aarch64
|
||||
|
|
|
@ -70,7 +70,7 @@ TEST(madvise, subPages) {
|
|||
TEST(madvise, misalign) {
|
||||
char *p;
|
||||
if (!IsLinux()) return; // most platforms don't care
|
||||
if (IsQemu()) return; // qemu claims to be linux but doesn't care
|
||||
if (IsQemuUser()) return; // qemu claims to be linux but doesn't care
|
||||
ASSERT_NE(MAP_FAILED, (p = mmap(0, FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
|
||||
ASSERT_SYS(EINVAL, -1, madvise(p + 1, FRAMESIZE - 1, MADV_WILLNEED));
|
||||
|
@ -79,7 +79,7 @@ TEST(madvise, misalign) {
|
|||
|
||||
TEST(madvise, badAdvice) {
|
||||
char *p;
|
||||
if (IsAarch64() && IsQemu()) return; // qemu doesn't validate advice
|
||||
if (IsAarch64() && IsQemuUser()) return; // qemu doesn't validate advice
|
||||
ASSERT_NE(MAP_FAILED, (p = mmap(0, FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
|
||||
ASSERT_SYS(EINVAL, -1, madvise(p, FRAMESIZE, 127));
|
||||
|
@ -88,7 +88,7 @@ TEST(madvise, badAdvice) {
|
|||
|
||||
TEST(madvise, missingMemory) {
|
||||
if (!IsLinux()) return; // most platforms don't care
|
||||
if (IsQemu()) return; // qemu claims to be linux but doesn't care
|
||||
if (IsQemuUser()) return; // qemu claims to be linux but doesn't care
|
||||
ASSERT_SYS(ENOMEM, -1,
|
||||
madvise((char *)0x83483838000, FRAMESIZE, MADV_WILLNEED));
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/struct/ucontext.internal.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/mem/gc.h"
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
|
@ -126,7 +125,7 @@ TEST(writev, empty_stillPerformsIoOperation) {
|
|||
ASSERT_NE(-1, (fd = open("file", O_RDONLY)));
|
||||
errno = 0;
|
||||
EXPECT_SYS(EBADF, -1, writev(fd, iov, ARRAYLEN(iov)));
|
||||
if (!(IsAarch64() && IsQemu())) {
|
||||
if (!(IsAarch64() && IsQemuUser())) {
|
||||
EXPECT_EQ(-1, writev(fd, NULL, 0));
|
||||
}
|
||||
EXPECT_NE(-1, close(fd));
|
||||
|
|
|
@ -383,7 +383,8 @@ TEST(sscanf, floating_point_infinity) {
|
|||
TEST(sscanf, floating_point_infinity_double_precision) {
|
||||
double a = 666.666, b = a, c = b, d = c, e = d, f = e, g = f;
|
||||
EXPECT_EQ(4, sscanf("inf +INF -iNf InF", "%lf %lf %lf %lf", &a, &b, &c, &d));
|
||||
EXPECT_EQ(3, sscanf("+infinity -INFINITY iNfInItY", "%lf %lf %lf", &e, &f, &g));
|
||||
EXPECT_EQ(3,
|
||||
sscanf("+infinity -INFINITY iNfInItY", "%lf %lf %lf", &e, &f, &g));
|
||||
EXPECT_TRUE(isinf(a));
|
||||
EXPECT_TRUE(isinf(b));
|
||||
EXPECT_TRUE(isinf(c));
|
||||
|
@ -394,11 +395,14 @@ TEST(sscanf, floating_point_infinity_double_precision) {
|
|||
}
|
||||
|
||||
TEST(sscanf, floating_point_documentation_examples) {
|
||||
float a = 666.666f, b = a, c = b, d = c, e = d, f = e, g = f, h = g, i = h, j = i;
|
||||
float a = 666.666f, b = a, c = b, d = c, e = d, f = e, g = f, h = g, i = h,
|
||||
j = i;
|
||||
|
||||
EXPECT_EQ(2, sscanf("111.11 -2.22", "%f %f", &a, &b));
|
||||
EXPECT_EQ(3, sscanf("Nan nan(2) inF", "%f %f %f", &c, &d, &e));
|
||||
EXPECT_EQ(5, sscanf("0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz -0.0000000123junk junk", "%f %f %f %f %f", &f, &g, &h, &i, &j));
|
||||
EXPECT_EQ(
|
||||
5, sscanf("0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz -0.0000000123junk junk",
|
||||
"%f %f %f %f %f", &f, &g, &h, &i, &j));
|
||||
|
||||
EXPECT_EQ(111.11f, a);
|
||||
EXPECT_EQ(-2.22f, b);
|
||||
|
@ -413,11 +417,14 @@ TEST(sscanf, floating_point_documentation_examples) {
|
|||
}
|
||||
|
||||
TEST(sscanf, floating_point_documentation_examples_double_precision) {
|
||||
double a = 666.666, b = a, c = b, d = c, e = d, f = e, g = f, h = g, i = h, j = i;
|
||||
double a = 666.666, b = a, c = b, d = c, e = d, f = e, g = f, h = g, i = h,
|
||||
j = i;
|
||||
|
||||
EXPECT_EQ(2, sscanf("111.11 -2.22", "%lf %lf", &a, &b));
|
||||
EXPECT_EQ(3, sscanf("Nan nan(2) inF", "%lf %lf %lf", &c, &d, &e));
|
||||
EXPECT_EQ(5, sscanf("0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz -0.0000000123junk junk", "%lf %lf %lf %lf %lf", &f, &g, &h, &i, &j));
|
||||
EXPECT_EQ(
|
||||
5, sscanf("0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz -0.0000000123junk junk",
|
||||
"%lf %lf %lf %lf %lf", &f, &g, &h, &i, &j));
|
||||
|
||||
EXPECT_EQ(111.11, a);
|
||||
EXPECT_EQ(-2.22, b);
|
||||
|
@ -470,3 +477,16 @@ TEST(fscanf, wantDecimalButGotLetter_returnsZeroMatches) {
|
|||
EXPECT_EQ(666, x);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
TEST(scanf, n) {
|
||||
int rc;
|
||||
unsigned int a, b, c, d, port, len;
|
||||
rc = sscanf("1.2.3.4:1848", "%u.%u.%u.%u:%u%n", &a, &b, &c, &d, &port, &len);
|
||||
ASSERT_EQ(5, rc);
|
||||
ASSERT_EQ(1, a);
|
||||
ASSERT_EQ(2, b);
|
||||
ASSERT_EQ(3, c);
|
||||
ASSERT_EQ(4, d);
|
||||
ASSERT_EQ(1848, port);
|
||||
ASSERT_EQ(12, len);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
|
|
|
@ -12,10 +12,13 @@ TEST_LIBCXX_CHECKS = $(TEST_LIBCXX_COMS:%=%.runs)
|
|||
TEST_LIBCXX_TESTS = $(TEST_LIBCXX_COMS:%=%.ok)
|
||||
|
||||
TEST_LIBCXX_DIRECTDEPS = \
|
||||
LIBC_CALLS \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RUNTIME \
|
||||
THIRD_PARTY_LIBCXX
|
||||
LIBC_STDIO \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_OPENMP
|
||||
|
||||
TEST_LIBCXX_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_LIBCXX_DIRECTDEPS),$($(x))))
|
||||
|
@ -34,6 +37,8 @@ o/$(MODE)/test/libcxx/%.com.dbg: \
|
|||
|
||||
$(TEST_LIBCXX_OBJS): private CCFLAGS += -fexceptions -frtti
|
||||
|
||||
o/$(MODE)/test/libcxx/openmp_test.o: private CXXFLAGS += -fopenmp -O3
|
||||
|
||||
.PHONY: o/$(MODE)/test/libcxx
|
||||
o/$(MODE)/test/libcxx: \
|
||||
$(TEST_LIBCXX_BINS) \
|
||||
|
|
236
test/libcxx/openmp_test.cc
Normal file
236
test/libcxx/openmp_test.cc
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
|
||||
│ vi: set et ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2024 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/inttypes.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "third_party/double-conversion/double-to-string.h"
|
||||
#include "third_party/double-conversion/utils.h"
|
||||
#include "third_party/openmp/omp.h"
|
||||
|
||||
#ifndef __FAST_MATH__
|
||||
#define FLAWLESS 0
|
||||
#else
|
||||
#define FLAWLESS 1e-05
|
||||
#endif
|
||||
|
||||
#if defined(__OPTIMIZE__) && !defined(__SANITIZE_ADDRESS__)
|
||||
#define ITERATIONS 10
|
||||
#else
|
||||
#define ITERATIONS 1
|
||||
#endif
|
||||
|
||||
// m×n → (m×n)ᵀ
|
||||
template <typename T>
|
||||
void transpose(long m, long n, const T *A, long sa, T *B, long sb) {
|
||||
#pragma omp parallel for collapse(2)
|
||||
for (long i = 0; i < m; ++i) {
|
||||
for (long j = 0; j < n; ++j) {
|
||||
B[sb * j + i] = A[sa * i + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// m×k * k×n → m×n
|
||||
template <typename T>
|
||||
void matmul(long m, long n, long k, const T *A, long sa, const T *B, long sb,
|
||||
T *C, long sc) {
|
||||
#pragma omp parallel for collapse(2)
|
||||
for (long i = 0; i < m; ++i) {
|
||||
for (long j = 0; j < n; ++j) {
|
||||
T sum = 0;
|
||||
for (long l = 0; l < k; ++l) {
|
||||
sum += A[sa * i + l] * B[sb * l + j];
|
||||
}
|
||||
C[sc * i + j] = sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <long BM, long BN, typename T>
|
||||
void gemmk(long k, const T *A, long sa, const T *B, long sb, T *C, long sc) {
|
||||
T S[BM][BN] = {0};
|
||||
for (long l = 0; l < k; ++l) {
|
||||
for (long i = 0; i < BM; ++i) {
|
||||
for (long j = 0; j < BN; ++j) {
|
||||
S[i][j] += A[sa * l + i] * B[sb * l + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (long i = 0; i < BM; ++i) {
|
||||
for (long j = 0; j < BN; ++j) {
|
||||
C[sc * i + j] = S[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (m×k)ᵀ * k×n → m×n
|
||||
template <long BM, long BN, typename T>
|
||||
void gemm(long m, long n, long k, const T *A, long sa, const T *B, long sb,
|
||||
T *C, long sc) {
|
||||
#pragma omp parallel for collapse(2)
|
||||
for (long i = 0; i < m; i += BM) {
|
||||
for (long j = 0; j < n; j += BN) {
|
||||
gemmk<BM, BN>(k, A + i, sa, B + j, sb, C + sc * i + j, sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void show(long m, long n, const T *A, long sa) {
|
||||
long max = 4;
|
||||
printf("{");
|
||||
for (long i = 0; i < m; ++i) {
|
||||
if (i) {
|
||||
if (i == max) {
|
||||
printf(", ...");
|
||||
break;
|
||||
} else {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
printf("{");
|
||||
for (long j = 0; j < n; ++j) {
|
||||
if (j) {
|
||||
if (j == max) {
|
||||
printf(", ...");
|
||||
break;
|
||||
} else {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
printf("%g", static_cast<double>(A[j + i * sa]));
|
||||
}
|
||||
printf("}");
|
||||
}
|
||||
printf("}");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
double diff(long m, long n, const T *A, long sa, const T *B, long sb) {
|
||||
double s = 0;
|
||||
for (long i = 0; i < m; ++i) {
|
||||
for (long j = 0; j < n; ++j) {
|
||||
s += fabs(A[sa * i + j] - B[sb * i + j]);
|
||||
}
|
||||
}
|
||||
return s / m / n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void check(double tol, long m, long n, const T *A, long sa, const T *B, long sb,
|
||||
const char *file, long line) {
|
||||
double sad = diff(m, n, A, sa, B, sb);
|
||||
if (sad > tol) {
|
||||
printf("%s:%d: sad %g exceeds %g\n\twant ", file, line, sad, tol);
|
||||
show(m, n, A, sa);
|
||||
printf("\n\t got ");
|
||||
show(m, n, B, sb);
|
||||
printf("\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#define check(tol, m, n, A, sa, B, sb) \
|
||||
check(tol, m, n, A, sa, B, sb, __FILE__, __LINE__)
|
||||
|
||||
long micros(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return ts.tv_sec * 1000000 + (ts.tv_nsec + 999) / 1000;
|
||||
}
|
||||
|
||||
#define bench(x) \
|
||||
do { \
|
||||
long t1 = micros(); \
|
||||
for (long i = 0; i < ITERATIONS; ++i) { \
|
||||
asm volatile("" ::: "memory"); \
|
||||
x; \
|
||||
asm volatile("" ::: "memory"); \
|
||||
} \
|
||||
long t2 = micros(); \
|
||||
printf("%8" PRId64 " µs %s\n", (t2 - t1 + ITERATIONS - 1) / ITERATIONS, \
|
||||
#x); \
|
||||
} while (0)
|
||||
|
||||
unsigned long rando(void) {
|
||||
static unsigned long s;
|
||||
unsigned long z = (s += 0x9e3779b97f4a7c15);
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
double real01(unsigned long x) { // (0,1)
|
||||
return 1. / 4503599627370496. * ((x >> 12) + .5);
|
||||
}
|
||||
|
||||
double numba(void) { // (-1,1)
|
||||
return real01(rando()) * 2 - 1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fill(T *A, long n) {
|
||||
for (long i = 0; i < n; ++i) {
|
||||
A[i] = numba();
|
||||
}
|
||||
}
|
||||
|
||||
void check_reference_gemm_is_ok(void) {
|
||||
constexpr long m = 2;
|
||||
constexpr long n = 2;
|
||||
constexpr long k = 2;
|
||||
float A[m][k] = {{1, 2}, {3, 4}};
|
||||
float B[k][n] = {{5, 6}, {7, 8}};
|
||||
float C[m][n] = {{666, 666}, {666, 666}};
|
||||
float G[m][n] = {{19, 22}, {43, 50}};
|
||||
bench(matmul(m, n, k, (float *)A, k, (float *)B, n, (float *)C, n));
|
||||
check(FLAWLESS, m, n, (float *)G, n, (float *)C, n);
|
||||
}
|
||||
|
||||
void check_transposed_blocking_gemm_is_ok(void) {
|
||||
long m = 1024;
|
||||
long k = 512;
|
||||
long n = 80;
|
||||
float *A = new float[m * k];
|
||||
float *B = new float[k * n];
|
||||
float *C = new float[m * n];
|
||||
float *D = new float[m * n];
|
||||
fill(A, m * k);
|
||||
fill(B, k * n);
|
||||
bench(matmul(m, n, k, A, k, B, n, C, n));
|
||||
float *At = new float[k * m];
|
||||
bench(transpose(m, k, A, k, At, m));
|
||||
bench((gemm<8, 4>(m, n, k, At, m, B, n, D, n)));
|
||||
check(FLAWLESS, m, n, C, n, D, n);
|
||||
delete[] At;
|
||||
delete[] D;
|
||||
delete[] C;
|
||||
delete[] B;
|
||||
delete[] A;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
check_reference_gemm_is_ok();
|
||||
check_transposed_blocking_gemm_is_ok();
|
||||
}
|
32
test/tool/net/curve25519_test.lua
Normal file
32
test/tool/net/curve25519_test.lua
Normal file
|
@ -0,0 +1,32 @@
|
|||
-- Copyright 2022 Justine Alexandra Roberts Tunney
|
||||
--
|
||||
-- Permission to use, copy, modify, and/or distribute this software for
|
||||
-- any purpose with or without fee is hereby granted, provided that the
|
||||
-- above copyright notice and this permission notice appear in all copies.
|
||||
--
|
||||
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
-- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
-- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
-- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
-- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
-- PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
-- TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
-- PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
local secret1 = GetRandomBytes(32)
|
||||
local public1 = Curve25519(secret1, "\9")
|
||||
local secret2 = GetRandomBytes(32)
|
||||
local public2 = Curve25519(secret2, "\9")
|
||||
local secret3 = GetRandomBytes(32)
|
||||
local public3 = Curve25519(secret3, "\9")
|
||||
|
||||
local shared_key1 = Curve25519(secret1, public2)
|
||||
local shared_key2 = Curve25519(secret2, public1)
|
||||
|
||||
local shared_key3 = Curve25519(secret2, public3)
|
||||
local shared_key4 = Curve25519(secret3, public2)
|
||||
|
||||
assert(shared_key1 == shared_key2)
|
||||
assert(shared_key1 ~= shared_key3)
|
||||
assert(shared_key2 ~= shared_key3)
|
||||
assert(shared_key4 == shared_key3)
|
1
third_party/BUILD.mk
vendored
1
third_party/BUILD.mk
vendored
|
@ -28,6 +28,7 @@ o/$(MODE)/third_party: \
|
|||
o/$(MODE)/third_party/musl \
|
||||
o/$(MODE)/third_party/ncurses \
|
||||
o/$(MODE)/third_party/nsync \
|
||||
o/$(MODE)/third_party/openmp \
|
||||
o/$(MODE)/third_party/pcre \
|
||||
o/$(MODE)/third_party/puff \
|
||||
o/$(MODE)/third_party/python \
|
||||
|
|
2
third_party/chibicc/test/BUILD.mk
vendored
2
third_party/chibicc/test/BUILD.mk
vendored
|
@ -74,8 +74,6 @@ o/$(MODE)/third_party/chibicc/test/%.o: \
|
|||
$(CHIBICC)
|
||||
@$(COMPILE) -wAOBJECTIFY.c $(CHIBICC) $(CHIBICC_FLAGS) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
o/$(MODE)/third_party/chibicc/test/int128_test.o: private QUOTA = -M1024m
|
||||
|
||||
endif
|
||||
|
||||
.PHONY: o/$(MODE)/third_party/chibicc/test
|
||||
|
|
119
third_party/compiler_rt/fp_compare_impl.inc
vendored
Normal file
119
third_party/compiler_rt/fp_compare_impl.inc
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
//===-- lib/fp_compare_impl.inc - Floating-point comparison -------*- C -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "fp_lib.inc"
|
||||
|
||||
// GCC uses long (at least for x86_64) as the return type of the comparison
|
||||
// functions. We need to ensure that the return value is sign-extended in the
|
||||
// same way as GCC expects (since otherwise GCC-generated __builtin_isinf
|
||||
// returns true for finite 128-bit floating-point numbers).
|
||||
#ifdef __aarch64__
|
||||
// AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
|
||||
typedef int CMP_RESULT;
|
||||
#elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
|
||||
// LLP64 ABIs use long long instead of long.
|
||||
typedef long long CMP_RESULT;
|
||||
#elif __AVR__
|
||||
// AVR uses a single byte for the return value.
|
||||
typedef char CMP_RESULT;
|
||||
#else
|
||||
// Otherwise the comparison functions return long.
|
||||
typedef long CMP_RESULT;
|
||||
#endif
|
||||
|
||||
#if !defined(__clang__) && defined(__GNUC__)
|
||||
// GCC uses a special __libgcc_cmp_return__ mode to define the return type, so
|
||||
// check that we are ABI-compatible when compiling the builtins with GCC.
|
||||
typedef int GCC_CMP_RESULT __attribute__((__mode__(__libgcc_cmp_return__)));
|
||||
_Static_assert(sizeof(GCC_CMP_RESULT) == sizeof(CMP_RESULT),
|
||||
"SOFTFP ABI not compatible with GCC");
|
||||
#endif
|
||||
|
||||
enum {
|
||||
LE_LESS = -1,
|
||||
LE_EQUAL = 0,
|
||||
LE_GREATER = 1,
|
||||
LE_UNORDERED = 1,
|
||||
};
|
||||
|
||||
static inline CMP_RESULT __leXf2__(fp_t a, fp_t b) {
|
||||
const srep_t aInt = toRep(a);
|
||||
const srep_t bInt = toRep(b);
|
||||
const rep_t aAbs = aInt & absMask;
|
||||
const rep_t bAbs = bInt & absMask;
|
||||
|
||||
// If either a or b is NaN, they are unordered.
|
||||
if (aAbs > infRep || bAbs > infRep)
|
||||
return LE_UNORDERED;
|
||||
|
||||
// If a and b are both zeros, they are equal.
|
||||
if ((aAbs | bAbs) == 0)
|
||||
return LE_EQUAL;
|
||||
|
||||
// If at least one of a and b is positive, we get the same result comparing
|
||||
// a and b as signed integers as we would with a floating-point compare.
|
||||
if ((aInt & bInt) >= 0) {
|
||||
if (aInt < bInt)
|
||||
return LE_LESS;
|
||||
else if (aInt == bInt)
|
||||
return LE_EQUAL;
|
||||
else
|
||||
return LE_GREATER;
|
||||
} else {
|
||||
// Otherwise, both are negative, so we need to flip the sense of the
|
||||
// comparison to get the correct result. (This assumes a twos- or ones-
|
||||
// complement integer representation; if integers are represented in a
|
||||
// sign-magnitude representation, then this flip is incorrect).
|
||||
if (aInt > bInt)
|
||||
return LE_LESS;
|
||||
else if (aInt == bInt)
|
||||
return LE_EQUAL;
|
||||
else
|
||||
return LE_GREATER;
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
GE_LESS = -1,
|
||||
GE_EQUAL = 0,
|
||||
GE_GREATER = 1,
|
||||
GE_UNORDERED = -1 // Note: different from LE_UNORDERED
|
||||
};
|
||||
|
||||
static inline CMP_RESULT __geXf2__(fp_t a, fp_t b) {
|
||||
const srep_t aInt = toRep(a);
|
||||
const srep_t bInt = toRep(b);
|
||||
const rep_t aAbs = aInt & absMask;
|
||||
const rep_t bAbs = bInt & absMask;
|
||||
|
||||
if (aAbs > infRep || bAbs > infRep)
|
||||
return GE_UNORDERED;
|
||||
if ((aAbs | bAbs) == 0)
|
||||
return GE_EQUAL;
|
||||
if ((aInt & bInt) >= 0) {
|
||||
if (aInt < bInt)
|
||||
return GE_LESS;
|
||||
else if (aInt == bInt)
|
||||
return GE_EQUAL;
|
||||
else
|
||||
return GE_GREATER;
|
||||
} else {
|
||||
if (aInt > bInt)
|
||||
return GE_LESS;
|
||||
else if (aInt == bInt)
|
||||
return GE_EQUAL;
|
||||
else
|
||||
return GE_GREATER;
|
||||
}
|
||||
}
|
||||
|
||||
static inline CMP_RESULT __unordXf2__(fp_t a, fp_t b) {
|
||||
const rep_t aAbs = toRep(a) & absMask;
|
||||
const rep_t bAbs = toRep(b) & absMask;
|
||||
return aAbs > infRep || bAbs > infRep;
|
||||
}
|
6
third_party/libcxx/ctime
vendored
6
third_party/libcxx/ctime
vendored
|
@ -11,10 +11,14 @@
|
|||
#define _LIBCPP_CTIME
|
||||
|
||||
#include "third_party/libcxx/__config"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
#include "libc/sysv/consts/timer.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/time/struct/tm.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
|
1
third_party/libcxxabi/BUILD.mk
vendored
1
third_party/libcxxabi/BUILD.mk
vendored
|
@ -83,6 +83,7 @@ $(THIRD_PARTY_LIBCXXABI_A).pkg: \
|
|||
# TODO: Remove constinit hacks when we have C++20
|
||||
$(THIRD_PARTY_LIBCXXABI_A_OBJS): private \
|
||||
CXXFLAGS += \
|
||||
-fno-sanitize=all \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fexceptions \
|
||||
|
|
13
third_party/libunwind/BUILD.mk
vendored
13
third_party/libunwind/BUILD.mk
vendored
|
@ -37,7 +37,8 @@ THIRD_PARTY_LIBUNWIND_A_SRCS_CC = \
|
|||
THIRD_PARTY_LIBUNWIND_A_SRCS_C = \
|
||||
third_party/libunwind/Unwind-sjlj.c \
|
||||
third_party/libunwind/UnwindLevel1-gcc-ext.c \
|
||||
third_party/libunwind/UnwindLevel1.c
|
||||
third_party/libunwind/UnwindLevel1.c \
|
||||
third_party/libunwind/gcc_personality_v0.c
|
||||
|
||||
THIRD_PARTY_LIBUNWIND_A_SRCS = \
|
||||
$(THIRD_PARTY_LIBUNWIND_A_SRCS_C) \
|
||||
|
@ -68,8 +69,18 @@ $(THIRD_PARTY_LIBUNWIND_A).pkg: \
|
|||
$(THIRD_PARTY_LIBUNWIND_A_OBJS) \
|
||||
$(foreach x,$(THIRD_PARTY_LIBUNWIND_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
$(THIRD_PARTY_LIBUNWIND_A_OBJS): private \
|
||||
CFLAGS += \
|
||||
-fexceptions \
|
||||
-fno-sanitize=all \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-D_LIBUNWIND_USE_DLADDR=0
|
||||
|
||||
$(THIRD_PARTY_LIBUNWIND_A_OBJS): private \
|
||||
CXXFLAGS += \
|
||||
-fexceptions \
|
||||
-fno-sanitize=all \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-D_LIBUNWIND_USE_DLADDR=0
|
||||
|
|
5
third_party/libunwind/README.cosmo
vendored
5
third_party/libunwind/README.cosmo
vendored
|
@ -12,5 +12,6 @@ ORIGIN
|
|||
Date: Tue, 28 Nov 2023 09:52:28 +0100
|
||||
|
||||
LOCAL CHANGES
|
||||
- Fixed `_Unwind_FunctionContext` struct to be ABI-compatible with code
|
||||
generated by GCC.
|
||||
|
||||
- Fixed `_Unwind_FunctionContext` struct to be ABI-compatible with
|
||||
code generated by GCC.
|
||||
|
|
236
third_party/libunwind/gcc_personality_v0.c
vendored
Normal file
236
third_party/libunwind/gcc_personality_v0.c
vendored
Normal file
|
@ -0,0 +1,236 @@
|
|||
//===-- gcc_personality_v0.c - Implement __gcc_personality_v0 -------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "third_party/libunwind/include/unwind.h"
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
// Pointer encodings documented at:
|
||||
// http://refspecs.freestandards.org/LSB_1.3.0/gLSB/gLSB/ehframehdr.html
|
||||
|
||||
#define DW_EH_PE_omit 0xff // no data follows
|
||||
|
||||
#define DW_EH_PE_absptr 0x00
|
||||
#define DW_EH_PE_uleb128 0x01
|
||||
#define DW_EH_PE_udata2 0x02
|
||||
#define DW_EH_PE_udata4 0x03
|
||||
#define DW_EH_PE_udata8 0x04
|
||||
#define DW_EH_PE_sleb128 0x09
|
||||
#define DW_EH_PE_sdata2 0x0A
|
||||
#define DW_EH_PE_sdata4 0x0B
|
||||
#define DW_EH_PE_sdata8 0x0C
|
||||
|
||||
#define DW_EH_PE_pcrel 0x10
|
||||
#define DW_EH_PE_textrel 0x20
|
||||
#define DW_EH_PE_datarel 0x30
|
||||
#define DW_EH_PE_funcrel 0x40
|
||||
#define DW_EH_PE_aligned 0x50
|
||||
#define DW_EH_PE_indirect 0x80 // gcc extension
|
||||
|
||||
// read a uleb128 encoded value and advance pointer
|
||||
static size_t readULEB128(const uint8_t **data) {
|
||||
size_t result = 0;
|
||||
size_t shift = 0;
|
||||
unsigned char byte;
|
||||
const uint8_t *p = *data;
|
||||
do {
|
||||
byte = *p++;
|
||||
result |= (byte & 0x7f) << shift;
|
||||
shift += 7;
|
||||
} while (byte & 0x80);
|
||||
*data = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
// read a pointer encoded value and advance pointer
|
||||
static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) {
|
||||
const uint8_t *p = *data;
|
||||
uintptr_t result = 0;
|
||||
|
||||
if (encoding == DW_EH_PE_omit)
|
||||
return 0;
|
||||
|
||||
// first get value
|
||||
switch (encoding & 0x0F) {
|
||||
case DW_EH_PE_absptr:
|
||||
result = *((const uintptr_t *)p);
|
||||
p += sizeof(uintptr_t);
|
||||
break;
|
||||
case DW_EH_PE_uleb128:
|
||||
result = readULEB128(&p);
|
||||
break;
|
||||
case DW_EH_PE_udata2:
|
||||
result = *((const uint16_t *)p);
|
||||
p += sizeof(uint16_t);
|
||||
break;
|
||||
case DW_EH_PE_udata4:
|
||||
result = *((const uint32_t *)p);
|
||||
p += sizeof(uint32_t);
|
||||
break;
|
||||
case DW_EH_PE_udata8:
|
||||
result = *((const uint64_t *)p);
|
||||
p += sizeof(uint64_t);
|
||||
break;
|
||||
case DW_EH_PE_sdata2:
|
||||
result = *((const int16_t *)p);
|
||||
p += sizeof(int16_t);
|
||||
break;
|
||||
case DW_EH_PE_sdata4:
|
||||
result = *((const int32_t *)p);
|
||||
p += sizeof(int32_t);
|
||||
break;
|
||||
case DW_EH_PE_sdata8:
|
||||
result = *((const int64_t *)p);
|
||||
p += sizeof(int64_t);
|
||||
break;
|
||||
case DW_EH_PE_sleb128:
|
||||
default:
|
||||
// not supported
|
||||
compilerrt_abort();
|
||||
break;
|
||||
}
|
||||
|
||||
// then add relative offset
|
||||
switch (encoding & 0x70) {
|
||||
case DW_EH_PE_absptr:
|
||||
// do nothing
|
||||
break;
|
||||
case DW_EH_PE_pcrel:
|
||||
result += (uintptr_t)(*data);
|
||||
break;
|
||||
case DW_EH_PE_textrel:
|
||||
case DW_EH_PE_datarel:
|
||||
case DW_EH_PE_funcrel:
|
||||
case DW_EH_PE_aligned:
|
||||
default:
|
||||
// not supported
|
||||
compilerrt_abort();
|
||||
break;
|
||||
}
|
||||
|
||||
// then apply indirection
|
||||
if (encoding & DW_EH_PE_indirect) {
|
||||
result = *((const uintptr_t *)result);
|
||||
}
|
||||
|
||||
*data = p;
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
|
||||
!defined(__ARM_DWARF_EH__) && !defined(__SEH__)
|
||||
#define USING_ARM_EHABI 1
|
||||
_Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *,
|
||||
struct _Unwind_Context *);
|
||||
#endif
|
||||
|
||||
static inline _Unwind_Reason_Code
|
||||
continueUnwind(struct _Unwind_Exception *exceptionObject,
|
||||
struct _Unwind_Context *context) {
|
||||
#if USING_ARM_EHABI
|
||||
// On ARM EHABI the personality routine is responsible for actually
|
||||
// unwinding a single stack frame before returning (ARM EHABI Sec. 6.1).
|
||||
if (__gnu_unwind_frame(exceptionObject, context) != _URC_OK)
|
||||
return _URC_FAILURE;
|
||||
#endif
|
||||
return _URC_CONTINUE_UNWIND;
|
||||
}
|
||||
|
||||
// The C compiler makes references to __gcc_personality_v0 in
|
||||
// the dwarf unwind information for translation units that use
|
||||
// __attribute__((cleanup(xx))) on local variables.
|
||||
// This personality routine is called by the system unwinder
|
||||
// on each frame as the stack is unwound during a C++ exception
|
||||
// throw through a C function compiled with -fexceptions.
|
||||
#if __USING_SJLJ_EXCEPTIONS__
|
||||
// the setjump-longjump based exceptions personality routine has a
|
||||
// different name
|
||||
COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_sj0(
|
||||
int version, _Unwind_Action actions, uint64_t exceptionClass,
|
||||
struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context)
|
||||
#elif USING_ARM_EHABI
|
||||
// The ARM EHABI personality routine has a different signature.
|
||||
COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
|
||||
_Unwind_State state, struct _Unwind_Exception *exceptionObject,
|
||||
struct _Unwind_Context *context)
|
||||
#elif defined(__SEH__)
|
||||
static _Unwind_Reason_Code __gcc_personality_imp(
|
||||
int version, _Unwind_Action actions, uint64_t exceptionClass,
|
||||
struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context)
|
||||
#else
|
||||
COMPILER_RT_ABI _Unwind_Reason_Code __gcc_personality_v0(
|
||||
int version, _Unwind_Action actions, uint64_t exceptionClass,
|
||||
struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context)
|
||||
#endif
|
||||
{
|
||||
// Since C does not have catch clauses, there is nothing to do during
|
||||
// phase 1 (the search phase).
|
||||
#if USING_ARM_EHABI
|
||||
// After resuming from a cleanup we should also continue on to the next
|
||||
// frame straight away.
|
||||
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
|
||||
#else
|
||||
if (actions & _UA_SEARCH_PHASE)
|
||||
#endif
|
||||
return continueUnwind(exceptionObject, context);
|
||||
|
||||
// There is nothing to do if there is no LSDA for this frame.
|
||||
const uint8_t *lsda = (uint8_t *)_Unwind_GetLanguageSpecificData(context);
|
||||
if (lsda == (uint8_t *)0)
|
||||
return continueUnwind(exceptionObject, context);
|
||||
|
||||
uintptr_t pc = (uintptr_t)_Unwind_GetIP(context) - 1;
|
||||
uintptr_t funcStart = (uintptr_t)_Unwind_GetRegionStart(context);
|
||||
uintptr_t pcOffset = pc - funcStart;
|
||||
|
||||
// Parse LSDA header.
|
||||
uint8_t lpStartEncoding = *lsda++;
|
||||
if (lpStartEncoding != DW_EH_PE_omit) {
|
||||
readEncodedPointer(&lsda, lpStartEncoding);
|
||||
}
|
||||
uint8_t ttypeEncoding = *lsda++;
|
||||
if (ttypeEncoding != DW_EH_PE_omit) {
|
||||
readULEB128(&lsda);
|
||||
}
|
||||
// Walk call-site table looking for range that includes current PC.
|
||||
uint8_t callSiteEncoding = *lsda++;
|
||||
size_t callSiteTableLength = readULEB128(&lsda);
|
||||
const uint8_t *callSiteTableStart = lsda;
|
||||
const uint8_t *callSiteTableEnd = callSiteTableStart + callSiteTableLength;
|
||||
const uint8_t *p = callSiteTableStart;
|
||||
while (p < callSiteTableEnd) {
|
||||
uintptr_t start = readEncodedPointer(&p, callSiteEncoding);
|
||||
size_t length = readEncodedPointer(&p, callSiteEncoding);
|
||||
size_t landingPad = readEncodedPointer(&p, callSiteEncoding);
|
||||
readULEB128(&p); // action value not used for C code
|
||||
if (landingPad == 0)
|
||||
continue; // no landing pad for this entry
|
||||
if ((start <= pcOffset) && (pcOffset < (start + length))) {
|
||||
// Found landing pad for the PC.
|
||||
// Set Instruction Pointer to so we re-enter function
|
||||
// at landing pad. The landing pad is created by the compiler
|
||||
// to take two parameters in registers.
|
||||
_Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
|
||||
(uintptr_t)exceptionObject);
|
||||
_Unwind_SetGR(context, __builtin_eh_return_data_regno(1), 0);
|
||||
_Unwind_SetIP(context, (funcStart + landingPad));
|
||||
return _URC_INSTALL_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
// No landing pad found, continue unwinding.
|
||||
return continueUnwind(exceptionObject, context);
|
||||
}
|
||||
|
||||
#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
|
||||
COMPILER_RT_ABI EXCEPTION_DISPOSITION
|
||||
__gcc_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
|
||||
PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp) {
|
||||
return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context, ms_disp,
|
||||
__gcc_personality_imp);
|
||||
}
|
||||
#endif
|
2
third_party/mbedtls/test/BUILD.mk
vendored
2
third_party/mbedtls/test/BUILD.mk
vendored
|
@ -1358,8 +1358,6 @@ o/$(MODE)/third_party/mbedtls/test/secp384r1_test.com.dbg: \
|
|||
$(APE_NO_MODIFY_SELF)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/third_party/mbedtls/test/test_suite_asn1parse.com.runs: private QUOTA = -M512m
|
||||
|
||||
# these need to be explictly defined because landlock make won't sandbox
|
||||
# prerequisites with a trailing slash.
|
||||
o/$(MODE)/third_party/mbedtls/test/data/.zip.o: \
|
||||
|
|
14
third_party/musl/catclose.c
vendored
Normal file
14
third_party/musl/catclose.c
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
#define _BSD_SOURCE
|
||||
#include <nl_types.h>
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define V(p) be32toh(*(uint32_t *)(p))
|
||||
|
||||
int catclose (nl_catd catd)
|
||||
{
|
||||
char *map = (char *)catd;
|
||||
munmap(map, V(map+8)+20);
|
||||
return 0;
|
||||
}
|
38
third_party/musl/catgets.c
vendored
Normal file
38
third_party/musl/catgets.c
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
#define _BSD_SOURCE
|
||||
#include <nl_types.h>
|
||||
#include <endian.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define V(p) be32toh(*(uint32_t *)(p))
|
||||
|
||||
static int cmp(const void *a, const void *b)
|
||||
{
|
||||
uint32_t x = V(a), y = V(b);
|
||||
return x<y ? -1 : x>y ? 1 : 0;
|
||||
}
|
||||
|
||||
char *catgets (nl_catd catd, int set_id, int msg_id, const char *s)
|
||||
{
|
||||
const char *map = (const char *)catd;
|
||||
uint32_t nsets = V(map+4);
|
||||
const char *sets = map+20;
|
||||
const char *msgs = map+20+V(map+12);
|
||||
const char *strings = map+20+V(map+16);
|
||||
uint32_t set_id_be = htobe32(set_id);
|
||||
uint32_t msg_id_be = htobe32(msg_id);
|
||||
const char *set = bsearch(&set_id_be, sets, nsets, 12, cmp);
|
||||
if (!set) {
|
||||
errno = ENOMSG;
|
||||
return (char *)s;
|
||||
}
|
||||
uint32_t nmsgs = V(set+4);
|
||||
msgs += 12*V(set+8);
|
||||
const char *msg = bsearch(&msg_id_be, msgs, nmsgs, 12, cmp);
|
||||
if (!msg) {
|
||||
errno = ENOMSG;
|
||||
return (char *)s;
|
||||
}
|
||||
return (char *)(strings + V(msg+8));
|
||||
}
|
79
third_party/musl/catopen.c
vendored
Normal file
79
third_party/musl/catopen.c
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
#define _BSD_SOURCE
|
||||
#include <nl_types.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include <errno.h>
|
||||
#include <langinfo.h>
|
||||
#include <locale.h>
|
||||
#include "third_party/musl/mapfile.internal.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define V(p) be32toh(*(uint32_t *)(p))
|
||||
|
||||
static nl_catd do_catopen(const char *name)
|
||||
{
|
||||
size_t size;
|
||||
const unsigned char *map = __map_file(name, &size);
|
||||
/* Size recorded in the file must match file size; otherwise
|
||||
* the information needed to unmap the file will be lost. */
|
||||
if (!map || V(map) != 0xff88ff89 || 20+V(map+8) != size) {
|
||||
if(map) munmap((void *)map, size);
|
||||
errno = ENOENT;
|
||||
return (nl_catd)-1;
|
||||
}
|
||||
return (nl_catd)map;
|
||||
}
|
||||
|
||||
nl_catd catopen(const char *name, int oflag)
|
||||
{
|
||||
nl_catd catd;
|
||||
|
||||
if (strchr(name, '/')) return do_catopen(name);
|
||||
|
||||
char buf[PATH_MAX];
|
||||
size_t i;
|
||||
const char *path, *lang, *p, *z;
|
||||
if (issetugid() || !(path = getenv("NLSPATH"))) {
|
||||
errno = ENOENT;
|
||||
return (nl_catd)-1;
|
||||
}
|
||||
lang = oflag ? nl_langinfo(_NL_LOCALE_NAME(LC_MESSAGES)) : getenv("LANG");
|
||||
if (!lang) lang = "";
|
||||
for (p=path; *p; p=z) {
|
||||
i = 0;
|
||||
z = strchrnul(p, ':');
|
||||
for (; p<z; p++) {
|
||||
const char *v;
|
||||
size_t l;
|
||||
if (*p!='%') v=p, l=1;
|
||||
else switch (*++p) {
|
||||
case 'N': v=name; l=strlen(v); break;
|
||||
case 'L': v=lang; l=strlen(v); break;
|
||||
case 'l': v=lang; l=strcspn(v,"_.@"); break;
|
||||
case 't':
|
||||
v=strchrnul(lang,'_');
|
||||
if (*v) v++;
|
||||
l=strcspn(v,".@");
|
||||
break;
|
||||
case 'c': v="UTF-8"; l=5; break;
|
||||
case '%': v="%"; l=1; break;
|
||||
default: v=0;
|
||||
}
|
||||
if (!v || l >= sizeof buf - i) {
|
||||
break;
|
||||
}
|
||||
memcpy(buf+i, v, l);
|
||||
i += l;
|
||||
}
|
||||
if (!*z && (p<z || !i)) break;
|
||||
if (p<z) continue;
|
||||
if (*z) z++;
|
||||
buf[i] = 0;
|
||||
/* Leading : or :: in NLSPATH is same as %N */
|
||||
catd = do_catopen(i ? buf : name);
|
||||
if (catd != (nl_catd)-1) return catd;
|
||||
}
|
||||
errno = ENOENT;
|
||||
return (nl_catd)-1;
|
||||
}
|
17
third_party/musl/mapfile.c
vendored
Normal file
17
third_party/musl/mapfile.c
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
const char unsigned *__map_file(const char *pathname, size_t *size)
|
||||
{
|
||||
struct stat st;
|
||||
const unsigned char *map = MAP_FAILED;
|
||||
int fd = open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
|
||||
if (fd < 0) return 0;
|
||||
if (!fstat(fd, &st)) {
|
||||
map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
*size = st.st_size;
|
||||
}
|
||||
close(fd);
|
||||
return map == MAP_FAILED ? 0 : map;
|
||||
}
|
8
third_party/musl/mapfile.internal.h
vendored
Normal file
8
third_party/musl/mapfile.internal.h
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_MUSL_MAPFILE_INTERNAL_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_MUSL_MAPFILE_INTERNAL_H_
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
const char unsigned *__map_file(const char *, size_t *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_MUSL_MAPFILE_INTERNAL_H_ */
|
5
third_party/musl/netdb.h
vendored
5
third_party/musl/netdb.h
vendored
|
@ -99,6 +99,9 @@ struct protoent *getprotoent (void);
|
|||
struct protoent *getprotobyname (const char *);
|
||||
struct protoent *getprotobynumber (int);
|
||||
|
||||
#define NI_MAXHOST 255
|
||||
#define NI_MAXSERV 32
|
||||
|
||||
#if defined(_COSMO_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
|
||||
|| (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
|
||||
|| (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
|
||||
|
@ -130,8 +133,6 @@ int getservbyname_r(const char *, const char *, struct servent *, char *, size_t
|
|||
#define EAI_ALLDONE -103
|
||||
#define EAI_INTR -104
|
||||
#define EAI_IDN_ENCODE -105
|
||||
#define NI_MAXHOST 255
|
||||
#define NI_MAXSERV 32
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
26
third_party/nsync/README.md
vendored
26
third_party/nsync/README.md
vendored
|
@ -1,26 +0,0 @@
|
|||
# *NSYNC
|
||||
|
||||
*NSYNC is a library providing scalable synchronization primitives. The
|
||||
following packages are provided:
|
||||
|
||||
- `THIRD_PARTY_NSYNC` has `nsync_mu` which doesn't depend on malloc().
|
||||
- `THIRD_PARTY_NSYNC_MEM` has the rest of *NSYNC, e.g. `nsync_cv`.
|
||||
|
||||
The origin of this code is here:
|
||||
|
||||
git@github.com:google/nsync
|
||||
ac5489682760393fe21bd2a8e038b528442412a7 (1.25.0)
|
||||
Author: Mike Burrows <m3b@google.com>
|
||||
Date: Wed Jun 1 16:47:52 2022 -0700
|
||||
|
||||
NSYNC uses the Apache 2.0 license. We made the following local changes:
|
||||
|
||||
- Write custom `nsync_malloc_()` so `malloc()` can use *NSYNC.
|
||||
|
||||
- Rewrite `futex()` wrapper to support old Linux kernels and OpenBSD.
|
||||
|
||||
- Normalize sources to Cosmopolitan style conventions; *NSYNC upstream
|
||||
supports dozens of compilers and operating systems, at compile-time.
|
||||
Since Cosmo solves portability at runtime instead, most of the build
|
||||
config toil has been removed, in order to help the NSYNC source code
|
||||
be more readable and hackable.
|
83
third_party/openmp/BUILD.mk
vendored
Normal file
83
third_party/openmp/BUILD.mk
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#── vi: set noet ft=make ts=8 sw=8 fenc=utf-8 :vi ────────────────────┘
|
||||
|
||||
PKGS += THIRD_PARTY_OPENMP
|
||||
|
||||
THIRD_PARTY_OPENMP_ARTIFACTS += THIRD_PARTY_OPENMP_A
|
||||
THIRD_PARTY_OPENMP = $(THIRD_PARTY_OPENMP_A_DEPS) $(THIRD_PARTY_OPENMP_A)
|
||||
THIRD_PARTY_OPENMP_A = o/$(MODE)/third_party/openmp/openmp.a
|
||||
THIRD_PARTY_OPENMP_A_FILES := $(wildcard third_party/openmp/*)
|
||||
THIRD_PARTY_OPENMP_A_HDRS = $(filter %.h,$(THIRD_PARTY_OPENMP_A_FILES))
|
||||
THIRD_PARTY_OPENMP_A_INCS = $(filter %.inc,$(THIRD_PARTY_OPENMP_A_FILES))
|
||||
THIRD_PARTY_OPENMP_A_SRCS_CPP = $(filter %.cpp,$(THIRD_PARTY_OPENMP_A_FILES))
|
||||
THIRD_PARTY_OPENMP_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_OPENMP_A_FILES))
|
||||
THIRD_PARTY_OPENMP_A_SRCS = $(THIRD_PARTY_OPENMP_A_SRCS_CPP) $(THIRD_PARTY_OPENMP_A_SRCS_S)
|
||||
THIRD_PARTY_OPENMP_A_OBJS_CPP = $(THIRD_PARTY_OPENMP_A_SRCS_CPP:%.cpp=o/$(MODE)/%.o)
|
||||
THIRD_PARTY_OPENMP_A_OBJS_S = $(THIRD_PARTY_OPENMP_A_SRCS_S:%.S=o/$(MODE)/%.o)
|
||||
THIRD_PARTY_OPENMP_A_OBJS = $(THIRD_PARTY_OPENMP_A_OBJS_CPP) $(THIRD_PARTY_OPENMP_A_OBJS_S)
|
||||
|
||||
THIRD_PARTY_OPENMP_A_DIRECTDEPS = \
|
||||
LIBC_CALLS \
|
||||
LIBC_DLOPEN \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_PROC \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_THREAD \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_LIBCXX \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_MUSL
|
||||
|
||||
THIRD_PARTY_OPENMP_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(THIRD_PARTY_OPENMP_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
THIRD_PARTY_OPENMP_A_CHECKS = \
|
||||
$(THIRD_PARTY_OPENMP_A).pkg
|
||||
|
||||
$(THIRD_PARTY_OPENMP_A): \
|
||||
third_party/openmp/ \
|
||||
$(THIRD_PARTY_OPENMP_A).pkg \
|
||||
$(THIRD_PARTY_OPENMP_A_OBJS)
|
||||
|
||||
$(THIRD_PARTY_OPENMP_A).pkg: \
|
||||
$(THIRD_PARTY_OPENMP_A_OBJS) \
|
||||
$(foreach x,$(THIRD_PARTY_OPENMP_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
$(THIRD_PARTY_OPENMP_A_OBJS): private \
|
||||
COPTS += \
|
||||
-fno-sanitize=all \
|
||||
-fdata-sections \
|
||||
-ffunction-sections \
|
||||
-Wno-maybe-uninitialized \
|
||||
-Wno-stringop-truncation \
|
||||
-Wno-unused-but-set-variable \
|
||||
-Wno-class-memaccess \
|
||||
-fno-strict-aliasing \
|
||||
-Wno-frame-address \
|
||||
-Wno-sign-compare
|
||||
|
||||
o/$(MODE)/third_party/openmp/util1.o: private COPTS += -fportcosmo
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/third_party/openmp/util2.o: third_party/openmp/util2.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
THIRD_PARTY_OPENMP_LIBS = $(foreach x,$(THIRD_PARTY_OPENMP_ARTIFACTS),$($(x)))
|
||||
THIRD_PARTY_OPENMP_SRCS = $(foreach x,$(THIRD_PARTY_OPENMP_ARTIFACTS),$($(x)_SRCS))
|
||||
THIRD_PARTY_OPENMP_HDRS = $(foreach x,$(THIRD_PARTY_OPENMP_ARTIFACTS),$($(x)_HDRS))
|
||||
THIRD_PARTY_OPENMP_INCS = $(foreach x,$(THIRD_PARTY_OPENMP_ARTIFACTS),$($(x)_INCS))
|
||||
THIRD_PARTY_OPENMP_CHECKS = $(foreach x,$(THIRD_PARTY_OPENMP_ARTIFACTS),$($(x)_CHECKS))
|
||||
THIRD_PARTY_OPENMP_OBJS = $(foreach x,$(THIRD_PARTY_OPENMP_ARTIFACTS),$($(x)_OBJS))
|
||||
$(THIRD_PARTY_OPENMP_OBJS): third_party/openmp/BUILD.mk
|
||||
|
||||
.PHONY: o/$(MODE)/third_party/openmp
|
||||
o/$(MODE)/third_party/openmp: \
|
||||
$(THIRD_PARTY_OPENMP_CHECKS)
|
20
third_party/openmp/README.cosmo
vendored
Normal file
20
third_party/openmp/README.cosmo
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
DESCRIPTION
|
||||
|
||||
libomp - LLVM's Compiler Runtime for Multiprocessing
|
||||
|
||||
ORIGIN
|
||||
|
||||
https://github.com/llvm/llvm-project/
|
||||
commit 70c3e30e01bd123e87824e36b6e38a39451ac28d
|
||||
date Mon Jan 29 09:54:34 2024 +0800
|
||||
|
||||
LOCAL CHANGES
|
||||
|
||||
- Use Cosmo's gettid() function
|
||||
- Ran third_party/openmp/generate.sh
|
||||
- Removed usage of syscall() function
|
||||
- Only enable hidden helper on GNU/Systemd
|
||||
- Made __kmp_get_load_balance() portable at runtime
|
||||
- Made __kmp_affinity_get_offline_cpus() portable at runtime
|
||||
- Turned off quad floating point support (why does openmp have it?)
|
||||
- Remove bloat for checking if multiple OpenMP libraries are linked
|
9
third_party/openmp/generate.sh
vendored
Executable file
9
third_party/openmp/generate.sh
vendored
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
perl ~/vendor/llvm-project/openmp/runtime/tools/message-converter.pl \
|
||||
--os=lin --prefix=kmp_i18n --enum=third_party/openmp/kmp_i18n_id.inc \
|
||||
~/vendor/llvm-project/openmp/runtime/src/i18n/en_US.txt || exit
|
||||
|
||||
perl ~/vendor/llvm-project/openmp/runtime/tools/message-converter.pl \
|
||||
--os=lin --prefix=kmp_i18n --default=third_party/openmp/kmp_i18n_default.inc \
|
||||
~/vendor/llvm-project/openmp/runtime/src/i18n/en_US.txt
|
4835
third_party/openmp/kmp.h
vendored
Normal file
4835
third_party/openmp/kmp.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
5597
third_party/openmp/kmp_affinity.cpp
vendored
Normal file
5597
third_party/openmp/kmp_affinity.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
1321
third_party/openmp/kmp_affinity.h
vendored
Normal file
1321
third_party/openmp/kmp_affinity.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
2324
third_party/openmp/kmp_alloc.cpp
vendored
Normal file
2324
third_party/openmp/kmp_alloc.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
3877
third_party/openmp/kmp_atomic.cpp
vendored
Normal file
3877
third_party/openmp/kmp_atomic.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
1855
third_party/openmp/kmp_atomic.h
vendored
Normal file
1855
third_party/openmp/kmp_atomic.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
2670
third_party/openmp/kmp_barrier.cpp
vendored
Normal file
2670
third_party/openmp/kmp_barrier.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
144
third_party/openmp/kmp_barrier.h
vendored
Normal file
144
third_party/openmp/kmp_barrier.h
vendored
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* kmp_barrier.h
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_BARRIER_H
|
||||
#define KMP_BARRIER_H
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_i18n.h"
|
||||
|
||||
#if KMP_HAVE_XMMINTRIN_H && KMP_HAVE__MM_MALLOC
|
||||
#include <xmmintrin.h>
|
||||
#define KMP_ALIGNED_ALLOCATE(size, alignment) _mm_malloc(size, alignment)
|
||||
#define KMP_ALIGNED_FREE(ptr) _mm_free(ptr)
|
||||
#elif KMP_HAVE_ALIGNED_ALLOC
|
||||
#define KMP_ALGIN_UP(val, alignment) \
|
||||
(((val) + (alignment)-1) / (alignment) * (alignment))
|
||||
#define KMP_ALIGNED_ALLOCATE(size, alignment) \
|
||||
aligned_alloc(alignment, KMP_ALGIN_UP(size, alignment))
|
||||
#define KMP_ALIGNED_FREE(ptr) free(ptr)
|
||||
#elif KMP_HAVE_POSIX_MEMALIGN
|
||||
static inline void *KMP_ALIGNED_ALLOCATE(size_t size, size_t alignment) {
|
||||
void *ptr;
|
||||
int n = posix_memalign(&ptr, alignment, size);
|
||||
if (n != 0) {
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
return nullptr;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
#define KMP_ALIGNED_FREE(ptr) free(ptr)
|
||||
#elif KMP_HAVE__ALIGNED_MALLOC
|
||||
#include <malloc.h>
|
||||
#define KMP_ALIGNED_ALLOCATE(size, alignment) _aligned_malloc(size, alignment)
|
||||
#define KMP_ALIGNED_FREE(ptr) _aligned_free(ptr)
|
||||
#else
|
||||
#define KMP_ALIGNED_ALLOCATE(size, alignment) KMP_INTERNAL_MALLOC(size)
|
||||
#define KMP_ALIGNED_FREE(ptr) KMP_INTERNAL_FREE(ptr)
|
||||
#endif
|
||||
|
||||
// Use four cache lines: MLC tends to prefetch the next or previous cache line
|
||||
// creating a possible fake conflict between cores, so this is the only way to
|
||||
// guarantee that no such prefetch can happen.
|
||||
#ifndef KMP_FOURLINE_ALIGN_CACHE
|
||||
#define KMP_FOURLINE_ALIGN_CACHE KMP_ALIGN(4 * CACHE_LINE)
|
||||
#endif
|
||||
|
||||
#define KMP_OPTIMIZE_FOR_REDUCTIONS 0
|
||||
|
||||
class distributedBarrier {
|
||||
struct flags_s {
|
||||
kmp_uint32 volatile KMP_FOURLINE_ALIGN_CACHE stillNeed;
|
||||
};
|
||||
|
||||
struct go_s {
|
||||
std::atomic<kmp_uint64> KMP_FOURLINE_ALIGN_CACHE go;
|
||||
};
|
||||
|
||||
struct iter_s {
|
||||
kmp_uint64 volatile KMP_FOURLINE_ALIGN_CACHE iter;
|
||||
};
|
||||
|
||||
struct sleep_s {
|
||||
std::atomic<bool> KMP_FOURLINE_ALIGN_CACHE sleep;
|
||||
};
|
||||
|
||||
void init(size_t nthr);
|
||||
void resize(size_t nthr);
|
||||
void computeGo(size_t n);
|
||||
void computeVarsForN(size_t n);
|
||||
|
||||
public:
|
||||
enum {
|
||||
MAX_ITERS = 3,
|
||||
MAX_GOS = 8,
|
||||
IDEAL_GOS = 4,
|
||||
IDEAL_CONTENTION = 16,
|
||||
};
|
||||
|
||||
flags_s *flags[MAX_ITERS];
|
||||
go_s *go;
|
||||
iter_s *iter;
|
||||
sleep_s *sleep;
|
||||
|
||||
size_t KMP_ALIGN_CACHE num_threads; // number of threads in barrier
|
||||
size_t KMP_ALIGN_CACHE max_threads; // size of arrays in data structure
|
||||
// number of go signals each requiring one write per iteration
|
||||
size_t KMP_ALIGN_CACHE num_gos;
|
||||
// number of groups of gos
|
||||
size_t KMP_ALIGN_CACHE num_groups;
|
||||
// threads per go signal
|
||||
size_t KMP_ALIGN_CACHE threads_per_go;
|
||||
bool KMP_ALIGN_CACHE fix_threads_per_go;
|
||||
// threads per group
|
||||
size_t KMP_ALIGN_CACHE threads_per_group;
|
||||
// number of go signals in a group
|
||||
size_t KMP_ALIGN_CACHE gos_per_group;
|
||||
void *team_icvs;
|
||||
|
||||
distributedBarrier() = delete;
|
||||
~distributedBarrier() = delete;
|
||||
|
||||
// Used instead of constructor to create aligned data
|
||||
static distributedBarrier *allocate(int nThreads) {
|
||||
distributedBarrier *d = (distributedBarrier *)KMP_ALIGNED_ALLOCATE(
|
||||
sizeof(distributedBarrier), 4 * CACHE_LINE);
|
||||
if (!d) {
|
||||
KMP_FATAL(MemoryAllocFailed);
|
||||
}
|
||||
d->num_threads = 0;
|
||||
d->max_threads = 0;
|
||||
for (int i = 0; i < MAX_ITERS; ++i)
|
||||
d->flags[i] = NULL;
|
||||
d->go = NULL;
|
||||
d->iter = NULL;
|
||||
d->sleep = NULL;
|
||||
d->team_icvs = NULL;
|
||||
d->fix_threads_per_go = false;
|
||||
// calculate gos and groups ONCE on base size
|
||||
d->computeGo(nThreads);
|
||||
d->init(nThreads);
|
||||
return d;
|
||||
}
|
||||
|
||||
static void deallocate(distributedBarrier *db) { KMP_ALIGNED_FREE(db); }
|
||||
|
||||
void update_num_threads(size_t nthr) { init(nthr); }
|
||||
|
||||
bool need_resize(size_t new_nthr) { return (new_nthr > max_threads); }
|
||||
size_t get_num_threads() { return num_threads; }
|
||||
kmp_uint64 go_release();
|
||||
void go_reset();
|
||||
};
|
||||
|
||||
#endif // KMP_BARRIER_H
|
331
third_party/openmp/kmp_cancel.cpp
vendored
Normal file
331
third_party/openmp/kmp_cancel.cpp
vendored
Normal file
|
@ -0,0 +1,331 @@
|
|||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_io.h"
|
||||
#include "kmp_str.h"
|
||||
#if OMPT_SUPPORT
|
||||
#include "ompt-specific.h"
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@ingroup CANCELLATION
|
||||
@param loc_ref location of the original task directive
|
||||
@param gtid Global thread ID of encountering thread
|
||||
@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
|
||||
|
||||
@return returns true if the cancellation request has been activated and the
|
||||
execution thread needs to proceed to the end of the canceled region.
|
||||
|
||||
Request cancellation of the binding OpenMP region.
|
||||
*/
|
||||
kmp_int32 __kmpc_cancel(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
|
||||
kmp_info_t *this_thr = __kmp_threads[gtid];
|
||||
|
||||
KC_TRACE(10, ("__kmpc_cancel: T#%d request %d OMP_CANCELLATION=%d\n", gtid,
|
||||
cncl_kind, __kmp_omp_cancellation));
|
||||
|
||||
KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
|
||||
KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
|
||||
cncl_kind == cancel_sections ||
|
||||
cncl_kind == cancel_taskgroup);
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
|
||||
if (__kmp_omp_cancellation) {
|
||||
switch (cncl_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
// cancellation requests for parallel and worksharing constructs
|
||||
// are handled through the team structure
|
||||
{
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
KMP_DEBUG_ASSERT(this_team);
|
||||
kmp_int32 old = cancel_noreq;
|
||||
this_team->t.t_cancel_request.compare_exchange_strong(old, cncl_kind);
|
||||
if (old == cancel_noreq || old == cncl_kind) {
|
||||
// we do not have a cancellation request in this team or we do have
|
||||
// one that matches the current request -> cancel
|
||||
#if OMPT_SUPPORT && OMPT_OPTIONAL
|
||||
if (ompt_enabled.ompt_callback_cancel) {
|
||||
ompt_data_t *task_data;
|
||||
__ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
|
||||
NULL);
|
||||
ompt_cancel_flag_t type = ompt_cancel_parallel;
|
||||
if (cncl_kind == cancel_parallel)
|
||||
type = ompt_cancel_parallel;
|
||||
else if (cncl_kind == cancel_loop)
|
||||
type = ompt_cancel_loop;
|
||||
else if (cncl_kind == cancel_sections)
|
||||
type = ompt_cancel_sections;
|
||||
ompt_callbacks.ompt_callback(ompt_callback_cancel)(
|
||||
task_data, type | ompt_cancel_activated,
|
||||
OMPT_GET_RETURN_ADDRESS(0));
|
||||
}
|
||||
#endif // OMPT_SUPPORT && OMPT_OPTIONAL
|
||||
return 1 /* true */;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cancel_taskgroup:
|
||||
// cancellation requests for a task group
|
||||
// are handled through the taskgroup structure
|
||||
{
|
||||
kmp_taskdata_t *task;
|
||||
kmp_taskgroup_t *taskgroup;
|
||||
|
||||
task = this_thr->th.th_current_task;
|
||||
KMP_DEBUG_ASSERT(task);
|
||||
|
||||
taskgroup = task->td_taskgroup;
|
||||
if (taskgroup) {
|
||||
kmp_int32 old = cancel_noreq;
|
||||
taskgroup->cancel_request.compare_exchange_strong(old, cncl_kind);
|
||||
if (old == cancel_noreq || old == cncl_kind) {
|
||||
// we do not have a cancellation request in this taskgroup or we do
|
||||
// have one that matches the current request -> cancel
|
||||
#if OMPT_SUPPORT && OMPT_OPTIONAL
|
||||
if (ompt_enabled.ompt_callback_cancel) {
|
||||
ompt_data_t *task_data;
|
||||
__ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
|
||||
NULL);
|
||||
ompt_callbacks.ompt_callback(ompt_callback_cancel)(
|
||||
task_data, ompt_cancel_taskgroup | ompt_cancel_activated,
|
||||
OMPT_GET_RETURN_ADDRESS(0));
|
||||
}
|
||||
#endif
|
||||
return 1 /* true */;
|
||||
}
|
||||
} else {
|
||||
// TODO: what needs to happen here?
|
||||
// the specification disallows cancellation w/o taskgroups
|
||||
// so we might do anything here, let's abort for now
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
|
||||
// ICV OMP_CANCELLATION=false, so we ignored this cancel request
|
||||
KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
|
||||
return 0 /* false */;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ingroup CANCELLATION
|
||||
@param loc_ref location of the original task directive
|
||||
@param gtid Global thread ID of encountering thread
|
||||
@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
|
||||
|
||||
@return returns true if a matching cancellation request has been flagged in the
|
||||
RTL and the encountering thread has to cancel..
|
||||
|
||||
Cancellation point for the encountering thread.
|
||||
*/
|
||||
kmp_int32 __kmpc_cancellationpoint(ident_t *loc_ref, kmp_int32 gtid,
|
||||
kmp_int32 cncl_kind) {
|
||||
kmp_info_t *this_thr = __kmp_threads[gtid];
|
||||
|
||||
KC_TRACE(10,
|
||||
("__kmpc_cancellationpoint: T#%d request %d OMP_CANCELLATION=%d\n",
|
||||
gtid, cncl_kind, __kmp_omp_cancellation));
|
||||
|
||||
KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
|
||||
KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
|
||||
cncl_kind == cancel_sections ||
|
||||
cncl_kind == cancel_taskgroup);
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
|
||||
if (__kmp_omp_cancellation) {
|
||||
switch (cncl_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
// cancellation requests for parallel and worksharing constructs
|
||||
// are handled through the team structure
|
||||
{
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
KMP_DEBUG_ASSERT(this_team);
|
||||
if (this_team->t.t_cancel_request) {
|
||||
if (cncl_kind == this_team->t.t_cancel_request) {
|
||||
// the request in the team structure matches the type of
|
||||
// cancellation point so we can cancel
|
||||
#if OMPT_SUPPORT && OMPT_OPTIONAL
|
||||
if (ompt_enabled.ompt_callback_cancel) {
|
||||
ompt_data_t *task_data;
|
||||
__ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
|
||||
NULL);
|
||||
ompt_cancel_flag_t type = ompt_cancel_parallel;
|
||||
if (cncl_kind == cancel_parallel)
|
||||
type = ompt_cancel_parallel;
|
||||
else if (cncl_kind == cancel_loop)
|
||||
type = ompt_cancel_loop;
|
||||
else if (cncl_kind == cancel_sections)
|
||||
type = ompt_cancel_sections;
|
||||
ompt_callbacks.ompt_callback(ompt_callback_cancel)(
|
||||
task_data, type | ompt_cancel_detected,
|
||||
OMPT_GET_RETURN_ADDRESS(0));
|
||||
}
|
||||
#endif
|
||||
return 1 /* true */;
|
||||
}
|
||||
KMP_ASSERT(0 /* false */);
|
||||
} else {
|
||||
// we do not have a cancellation request pending, so we just
|
||||
// ignore this cancellation point
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cancel_taskgroup:
|
||||
// cancellation requests for a task group
|
||||
// are handled through the taskgroup structure
|
||||
{
|
||||
kmp_taskdata_t *task;
|
||||
kmp_taskgroup_t *taskgroup;
|
||||
|
||||
task = this_thr->th.th_current_task;
|
||||
KMP_DEBUG_ASSERT(task);
|
||||
|
||||
taskgroup = task->td_taskgroup;
|
||||
if (taskgroup) {
|
||||
// return the current status of cancellation for the taskgroup
|
||||
#if OMPT_SUPPORT && OMPT_OPTIONAL
|
||||
if (ompt_enabled.ompt_callback_cancel &&
|
||||
!!taskgroup->cancel_request) {
|
||||
ompt_data_t *task_data;
|
||||
__ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL,
|
||||
NULL);
|
||||
ompt_callbacks.ompt_callback(ompt_callback_cancel)(
|
||||
task_data, ompt_cancel_taskgroup | ompt_cancel_detected,
|
||||
OMPT_GET_RETURN_ADDRESS(0));
|
||||
}
|
||||
#endif
|
||||
return !!taskgroup->cancel_request;
|
||||
} else {
|
||||
// if a cancellation point is encountered by a task that does not
|
||||
// belong to a taskgroup, it is OK to ignore it
|
||||
return 0 /* false */;
|
||||
}
|
||||
}
|
||||
default:
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
|
||||
// ICV OMP_CANCELLATION=false, so we ignore the cancellation point
|
||||
KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
|
||||
return 0 /* false */;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ingroup CANCELLATION
|
||||
@param loc_ref location of the original task directive
|
||||
@param gtid Global thread ID of encountering thread
|
||||
|
||||
@return returns true if a matching cancellation request has been flagged in the
|
||||
RTL and the encountering thread has to cancel..
|
||||
|
||||
Barrier with cancellation point to send threads from the barrier to the
|
||||
end of the parallel region. Needs a special code pattern as documented
|
||||
in the design document for the cancellation feature.
|
||||
*/
|
||||
kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid) {
|
||||
int ret = 0 /* false */;
|
||||
kmp_info_t *this_thr = __kmp_threads[gtid];
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
|
||||
// call into the standard barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
|
||||
// if cancellation is active, check cancellation flag
|
||||
if (__kmp_omp_cancellation) {
|
||||
// depending on which construct to cancel, check the flag and
|
||||
// reset the flag
|
||||
switch (KMP_ATOMIC_LD_RLX(&(this_team->t.t_cancel_request))) {
|
||||
case cancel_parallel:
|
||||
ret = 1;
|
||||
// ensure that threads have checked the flag, when
|
||||
// leaving the above barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
this_team->t.t_cancel_request = cancel_noreq;
|
||||
// the next barrier is the fork/join barrier, which
|
||||
// synchronizes the threads leaving here
|
||||
break;
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
ret = 1;
|
||||
// ensure that threads have checked the flag, when
|
||||
// leaving the above barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
this_team->t.t_cancel_request = cancel_noreq;
|
||||
// synchronize the threads again to make sure we do not have any run-away
|
||||
// threads that cause a race on the cancellation flag
|
||||
__kmpc_barrier(loc, gtid);
|
||||
break;
|
||||
case cancel_taskgroup:
|
||||
// this case should not occur
|
||||
KMP_ASSERT(0 /* false */);
|
||||
break;
|
||||
case cancel_noreq:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ingroup CANCELLATION
|
||||
@param loc_ref location of the original task directive
|
||||
@param gtid Global thread ID of encountering thread
|
||||
|
||||
@return returns true if a matching cancellation request has been flagged in the
|
||||
RTL and the encountering thread has to cancel..
|
||||
|
||||
Query function to query the current status of cancellation requests.
|
||||
Can be used to implement the following pattern:
|
||||
|
||||
if (kmp_get_cancellation_status(kmp_cancel_parallel)) {
|
||||
perform_cleanup();
|
||||
#pragma omp cancellation point parallel
|
||||
}
|
||||
*/
|
||||
int __kmp_get_cancellation_status(int cancel_kind) {
|
||||
if (__kmp_omp_cancellation) {
|
||||
kmp_info_t *this_thr = __kmp_entry_thread();
|
||||
|
||||
switch (cancel_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections: {
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
return this_team->t.t_cancel_request == cancel_kind;
|
||||
}
|
||||
case cancel_taskgroup: {
|
||||
kmp_taskdata_t *task;
|
||||
kmp_taskgroup_t *taskgroup;
|
||||
task = this_thr->th.th_current_task;
|
||||
taskgroup = task->td_taskgroup;
|
||||
return taskgroup && taskgroup->cancel_request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0 /* false */;
|
||||
}
|
1475
third_party/openmp/kmp_collapse.cpp
vendored
Normal file
1475
third_party/openmp/kmp_collapse.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
240
third_party/openmp/kmp_collapse.h
vendored
Normal file
240
third_party/openmp/kmp_collapse.h
vendored
Normal file
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* kmp_collapse.h -- header for loop collapse feature
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_COLLAPSE_H
|
||||
#define KMP_COLLAPSE_H
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// Type of the index into the loop nest structures
|
||||
// (with values from 0 to less than n from collapse(n))
|
||||
typedef kmp_int32 kmp_index_t;
|
||||
|
||||
// Type for combined loop nest space IV:
|
||||
typedef kmp_uint64 kmp_loop_nest_iv_t;
|
||||
|
||||
// Loop has <, <=, etc. as a comparison:
|
||||
enum comparison_t : kmp_int32 {
|
||||
comp_less_or_eq = 0,
|
||||
comp_greater_or_eq = 1,
|
||||
comp_not_eq = 2,
|
||||
comp_less = 3,
|
||||
comp_greater = 4
|
||||
};
|
||||
|
||||
// Type of loop IV.
|
||||
// Type of bounds and step, after usual promotions
|
||||
// are a subset of these types (32 & 64 only):
|
||||
enum loop_type_t : kmp_int32 {
|
||||
loop_type_uint8 = 0,
|
||||
loop_type_int8 = 1,
|
||||
loop_type_uint16 = 2,
|
||||
loop_type_int16 = 3,
|
||||
loop_type_uint32 = 4,
|
||||
loop_type_int32 = 5,
|
||||
loop_type_uint64 = 6,
|
||||
loop_type_int64 = 7
|
||||
};
|
||||
|
||||
/*!
|
||||
@ingroup WORK_SHARING
|
||||
* Describes the structure for rectangular nested loops.
|
||||
*/
|
||||
template <typename T> struct bounds_infoXX_template {
|
||||
|
||||
// typedef typename traits_t<T>::unsigned_t UT;
|
||||
typedef typename traits_t<T>::signed_t ST;
|
||||
|
||||
loop_type_t loop_type; // The differentiator
|
||||
loop_type_t loop_iv_type;
|
||||
comparison_t comparison;
|
||||
// outer_iv should be 0 (or any other less then number of dimentions)
|
||||
// if loop doesn't depend on it (lb1 and ub1 will be 0).
|
||||
// This way we can do multiplication without a check.
|
||||
kmp_index_t outer_iv;
|
||||
|
||||
// unions to keep the size constant:
|
||||
union {
|
||||
T lb0;
|
||||
kmp_uint64 lb0_u64; // real type can be signed
|
||||
};
|
||||
|
||||
union {
|
||||
T lb1;
|
||||
kmp_uint64 lb1_u64; // real type can be signed
|
||||
};
|
||||
|
||||
union {
|
||||
T ub0;
|
||||
kmp_uint64 ub0_u64; // real type can be signed
|
||||
};
|
||||
|
||||
union {
|
||||
T ub1;
|
||||
kmp_uint64 ub1_u64; // real type can be signed
|
||||
};
|
||||
|
||||
union {
|
||||
ST step; // signed even if bounds type is unsigned
|
||||
kmp_int64 step_64; // signed
|
||||
};
|
||||
|
||||
kmp_loop_nest_iv_t trip_count;
|
||||
};
|
||||
|
||||
/*!
|
||||
@ingroup WORK_SHARING
|
||||
* Interface struct for rectangular nested loops.
|
||||
* Same size as bounds_infoXX_template.
|
||||
*/
|
||||
struct bounds_info_t {
|
||||
|
||||
loop_type_t loop_type; // The differentiator
|
||||
loop_type_t loop_iv_type;
|
||||
comparison_t comparison;
|
||||
// outer_iv should be 0 (or any other less then number of dimentions)
|
||||
// if loop doesn't depend on it (lb1 and ub1 will be 0).
|
||||
// This way we can do multiplication without a check.
|
||||
kmp_index_t outer_iv;
|
||||
|
||||
kmp_uint64 lb0_u64; // real type can be signed
|
||||
kmp_uint64 lb1_u64; // real type can be signed
|
||||
kmp_uint64 ub0_u64; // real type can be signed
|
||||
kmp_uint64 ub1_u64; // real type can be signed
|
||||
kmp_int64 step_64; // signed
|
||||
|
||||
// This is internal, but it's the only internal thing we need
|
||||
// in rectangular case, so let's expose it here:
|
||||
kmp_loop_nest_iv_t trip_count;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Additional types for internal representation:
|
||||
|
||||
// Array for a point in the loop space, in the original space.
|
||||
// It's represented in kmp_uint64, but each dimention is calculated in
|
||||
// that loop IV type. Also dimentions have to be converted to those types
|
||||
// when used in generated code.
|
||||
typedef kmp_uint64* kmp_point_t;
|
||||
|
||||
// Array: Number of loop iterations on each nesting level to achieve some point,
|
||||
// in expanded space or in original space.
|
||||
// OMPTODO: move from using iterations to using offsets (iterations multiplied
|
||||
// by steps). For those we need to be careful with the types, as step can be
|
||||
// negative, but it'll remove multiplications and divisions in several places.
|
||||
typedef kmp_loop_nest_iv_t* kmp_iterations_t;
|
||||
|
||||
// Internal struct with additional info:
|
||||
template <typename T> struct bounds_info_internalXX_template {
|
||||
|
||||
// OMPTODO: should span have type T or should it better be
|
||||
// kmp_uint64/kmp_int64 depending on T sign? (if kmp_uint64/kmp_int64 than
|
||||
// updated bounds should probably also be kmp_uint64/kmp_int64). I'd like to
|
||||
// use big_span_t, if it can be resolved at compile time.
|
||||
typedef
|
||||
typename std::conditional<std::is_signed<T>::value, kmp_int64, kmp_uint64>
|
||||
big_span_t;
|
||||
|
||||
// typedef typename big_span_t span_t;
|
||||
typedef T span_t;
|
||||
|
||||
bounds_infoXX_template<T> b; // possibly adjusted bounds
|
||||
|
||||
// Leaving this as a union in case we'll switch to span_t with different sizes
|
||||
// (depending on T)
|
||||
union {
|
||||
// Smallest possible value of iv (may be smaller than actually possible)
|
||||
span_t span_smallest;
|
||||
kmp_uint64 span_smallest_u64;
|
||||
};
|
||||
|
||||
// Leaving this as a union in case we'll switch to span_t with different sizes
|
||||
// (depending on T)
|
||||
union {
|
||||
// Biggest possible value of iv (may be bigger than actually possible)
|
||||
span_t span_biggest;
|
||||
kmp_uint64 span_biggest_u64;
|
||||
};
|
||||
|
||||
// Did we adjust loop bounds (not counting canonicalization)?
|
||||
bool loop_bounds_adjusted;
|
||||
};
|
||||
|
||||
// Internal struct with additional info:
|
||||
struct bounds_info_internal_t {
|
||||
|
||||
bounds_info_t b; // possibly adjusted bounds
|
||||
|
||||
// Smallest possible value of iv (may be smaller than actually possible)
|
||||
kmp_uint64 span_smallest_u64;
|
||||
|
||||
// Biggest possible value of iv (may be bigger than actually possible)
|
||||
kmp_uint64 span_biggest_u64;
|
||||
|
||||
// Did we adjust loop bounds (not counting canonicalization)?
|
||||
bool loop_bounds_adjusted;
|
||||
};
|
||||
|
||||
//----------APIs for rectangular loop nests--------------------------------
|
||||
|
||||
// Canonicalize loop nest and calculate overall trip count.
|
||||
// "bounds_nest" has to be allocated per thread.
|
||||
// API will modify original bounds_nest array to bring it to a canonical form
|
||||
// (only <= and >=, no !=, <, >). If the original loop nest was already in a
|
||||
// canonical form there will be no changes to bounds in bounds_nest array
|
||||
// (only trip counts will be calculated).
|
||||
// Returns trip count of overall space.
|
||||
extern "C" kmp_loop_nest_iv_t
|
||||
__kmpc_process_loop_nest_rectang(ident_t *loc, kmp_int32 gtid,
|
||||
/*in/out*/ bounds_info_t *original_bounds_nest,
|
||||
kmp_index_t n);
|
||||
|
||||
// Calculate old induction variables corresponding to overall new_iv.
|
||||
// Note: original IV will be returned as if it had kmp_uint64 type,
|
||||
// will have to be converted to original type in user code.
|
||||
// Note: trip counts should be already calculated by
|
||||
// __kmpc_process_loop_nest_rectang.
|
||||
// OMPTODO: special case 2, 3 nested loops - if it'll be possible to inline
|
||||
// that into user code.
|
||||
extern "C" void
|
||||
__kmpc_calc_original_ivs_rectang(ident_t *loc, kmp_loop_nest_iv_t new_iv,
|
||||
const bounds_info_t *original_bounds_nest,
|
||||
/*out*/ kmp_uint64 *original_ivs,
|
||||
kmp_index_t n);
|
||||
|
||||
//----------Init API for non-rectangular loops--------------------------------
|
||||
|
||||
// Init API for collapsed loops (static, no chunks defined).
|
||||
// "bounds_nest" has to be allocated per thread.
|
||||
// API will modify original bounds_nest array to bring it to a canonical form
|
||||
// (only <= and >=, no !=, <, >). If the original loop nest was already in a
|
||||
// canonical form there will be no changes to bounds in bounds_nest array
|
||||
// (only trip counts will be calculated). Internally API will expand the space
|
||||
// to parallelogram/parallelepiped, calculate total, calculate bounds for the
|
||||
// chunks in terms of the new IV, re-calc them in terms of old IVs (especially
|
||||
// important on the left side, to hit the lower bounds and not step over), and
|
||||
// pick the correct chunk for this thread (so it will calculate chunks up to the
|
||||
// needed one). It could be optimized to calculate just this chunk, potentially
|
||||
// a bit less well distributed among threads. It is designed to make sure that
|
||||
// threads will receive predictable chunks, deterministically (so that next nest
|
||||
// of loops with similar characteristics will get exactly same chunks on same
|
||||
// threads).
|
||||
// Current contract: chunk_bounds_nest has only lb0 and ub0,
|
||||
// lb1 and ub1 are set to 0 and can be ignored. (This may change in the future).
|
||||
extern "C" kmp_int32
|
||||
__kmpc_for_collapsed_init(ident_t *loc, kmp_int32 gtid,
|
||||
/*in/out*/ bounds_info_t *original_bounds_nest,
|
||||
/*out*/ bounds_info_t *chunk_bounds_nest,
|
||||
kmp_index_t n,
|
||||
/*out*/ kmp_int32 *plastiter);
|
||||
|
||||
#endif // KMP_COLLAPSE_H
|
170
third_party/openmp/kmp_config.h
vendored
Normal file
170
third_party/openmp/kmp_config.h
vendored
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* kmp_config.h -- Feature macros
|
||||
*/
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_CONFIG_H
|
||||
#define KMP_CONFIG_H
|
||||
|
||||
#include "libc/dce.h"
|
||||
#include "kmp_platform.h"
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
#include "libc/stdio/syscall.h"
|
||||
#endif
|
||||
|
||||
#if IsModeDbg()
|
||||
#define KMP_DEBUG 1
|
||||
#endif
|
||||
|
||||
#define KMP_FTN_ENTRIES KMP_FTN_PLAIN
|
||||
#define syscall {{openmp_shall_not_use_syscall}}
|
||||
|
||||
#define LIBOMP_USE_ITT_NOTIFY 0
|
||||
#define USE_ITT_NOTIFY LIBOMP_USE_ITT_NOTIFY
|
||||
#if ! LIBOMP_USE_ITT_NOTIFY
|
||||
# define INTEL_NO_ITTNOTIFY_API
|
||||
#endif
|
||||
#define LIBOMP_USE_VERSION_SYMBOLS 0
|
||||
#if LIBOMP_USE_VERSION_SYMBOLS
|
||||
# define KMP_USE_VERSION_SYMBOLS
|
||||
#endif
|
||||
#define LIBOMP_HAVE_WEAK_ATTRIBUTE 1
|
||||
#define KMP_HAVE_WEAK_ATTRIBUTE LIBOMP_HAVE_WEAK_ATTRIBUTE
|
||||
#define LIBOMP_HAVE_PSAPI 0
|
||||
#define KMP_HAVE_PSAPI LIBOMP_HAVE_PSAPI
|
||||
#define LIBOMP_STATS 0
|
||||
#define KMP_STATS_ENABLED LIBOMP_STATS
|
||||
#ifdef __x86_64__
|
||||
#define LIBOMP_HAVE_X86INTRIN_H 1
|
||||
#else
|
||||
#define LIBOMP_HAVE_X86INTRIN_H 0
|
||||
#endif
|
||||
#define KMP_HAVE_X86INTRIN_H LIBOMP_HAVE_X86INTRIN_H
|
||||
#define LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER 0
|
||||
#define KMP_HAVE___BUILTIN_READCYCLECOUNTER LIBOMP_HAVE___BUILTIN_READCYCLECOUNTER
|
||||
#define LIBOMP_HAVE___RDTSC 1
|
||||
#define KMP_HAVE___RDTSC LIBOMP_HAVE___RDTSC
|
||||
#define LIBOMP_USE_DEBUGGER 0
|
||||
#define USE_DEBUGGER LIBOMP_USE_DEBUGGER
|
||||
#define LIBOMP_OMPT_DEBUG 0
|
||||
#define OMPT_DEBUG LIBOMP_OMPT_DEBUG
|
||||
#define LIBOMP_OMPT_SUPPORT 1
|
||||
#define OMPT_SUPPORT LIBOMP_OMPT_SUPPORT
|
||||
#define LIBOMP_OMPD_SUPPORT 0
|
||||
#define OMPD_SUPPORT LIBOMP_OMPD_SUPPORT
|
||||
#define LIBOMP_OMPX_TASKGRAPH 0
|
||||
#define OMPX_TASKGRAPH LIBOMP_OMPX_TASKGRAPH
|
||||
#define LIBOMP_PROFILING_SUPPORT 0
|
||||
#define OMP_PROFILING_SUPPORT LIBOMP_PROFILING_SUPPORT
|
||||
#define LIBOMP_OMPT_OPTIONAL 1
|
||||
#define OMPT_OPTIONAL LIBOMP_OMPT_OPTIONAL
|
||||
#define LIBOMP_USE_ADAPTIVE_LOCKS 1
|
||||
#define KMP_USE_ADAPTIVE_LOCKS LIBOMP_USE_ADAPTIVE_LOCKS
|
||||
#define KMP_DEBUG_ADAPTIVE_LOCKS 0
|
||||
#define LIBOMP_USE_INTERNODE_ALIGNMENT 0
|
||||
#define KMP_USE_INTERNODE_ALIGNMENT LIBOMP_USE_INTERNODE_ALIGNMENT
|
||||
#define LIBOMP_ENABLE_ASSERTIONS 0
|
||||
#define KMP_USE_ASSERT LIBOMP_ENABLE_ASSERTIONS
|
||||
#define LIBOMP_USE_HIER_SCHED 0
|
||||
#define KMP_USE_HIER_SCHED LIBOMP_USE_HIER_SCHED
|
||||
#define STUBS_LIBRARY 0
|
||||
#define LIBOMP_USE_HWLOC 0
|
||||
#define KMP_USE_HWLOC LIBOMP_USE_HWLOC
|
||||
#define LIBOMP_ENABLE_SHARED 0
|
||||
#define KMP_DYNAMIC_LIB LIBOMP_ENABLE_SHARED
|
||||
#define KMP_ARCH_STR "@LIBOMP_LEGAL_ARCH@"
|
||||
#define KMP_LIBRARY_FILE "@LIBOMP_LIB_FILE@"
|
||||
#define KMP_VERSION_MAJOR 5
|
||||
#define KMP_VERSION_MINOR 0
|
||||
#define MSVC 0
|
||||
#define KMP_MSVC_COMPAT MSVC
|
||||
// #define LIBOMP_HAVE_WAITPKG_INTRINSICS
|
||||
#define KMP_HAVE_WAITPKG_INTRINSICS LIBOMP_HAVE_WAITPKG_INTRINSICS
|
||||
// #define LIBOMP_HAVE_RTM_INTRINSICS
|
||||
#define KMP_HAVE_RTM_INTRINSICS LIBOMP_HAVE_RTM_INTRINSICS
|
||||
#ifdef __x86_64__
|
||||
#define LIBOMP_HAVE_IMMINTRIN_H 1
|
||||
#else
|
||||
#define LIBOMP_HAVE_IMMINTRIN_H 0
|
||||
#endif
|
||||
#define KMP_HAVE_IMMINTRIN_H LIBOMP_HAVE_IMMINTRIN_H
|
||||
#define LIBOMP_HAVE_INTRIN_H 0
|
||||
#define KMP_HAVE_INTRIN_H LIBOMP_HAVE_INTRIN_H
|
||||
#define LIBOMP_HAVE_ATTRIBUTE_WAITPKG 0
|
||||
#define KMP_HAVE_ATTRIBUTE_WAITPKG LIBOMP_HAVE_ATTRIBUTE_WAITPKG
|
||||
#define LIBOMP_HAVE_ATTRIBUTE_RTM 0
|
||||
#define KMP_HAVE_ATTRIBUTE_RTM LIBOMP_HAVE_ATTRIBUTE_RTM
|
||||
#define LIBOMP_ARCH_AARCH64_A64FX 0
|
||||
#define KMP_ARCH_AARCH64_A64FX LIBOMP_ARCH_AARCH64_A64FX
|
||||
#ifdef __x86_64__
|
||||
#define LIBOMP_HAVE_XMMINTRIN_H 1
|
||||
#else
|
||||
#define LIBOMP_HAVE_XMMINTRIN_H 0
|
||||
#endif
|
||||
#define KMP_HAVE_XMMINTRIN_H LIBOMP_HAVE_XMMINTRIN_H
|
||||
#ifdef __x86_64__
|
||||
#define LIBOMP_HAVE__MM_MALLOC 1
|
||||
#else
|
||||
#define LIBOMP_HAVE__MM_MALLOC 0
|
||||
#endif
|
||||
#define KMP_HAVE__MM_MALLOC LIBOMP_HAVE__MM_MALLOC
|
||||
#define LIBOMP_HAVE_ALIGNED_ALLOC 1
|
||||
#define KMP_HAVE_ALIGNED_ALLOC LIBOMP_HAVE_ALIGNED_ALLOC
|
||||
#define LIBOMP_HAVE_POSIX_MEMALIGN 1
|
||||
#define KMP_HAVE_POSIX_MEMALIGN LIBOMP_HAVE_POSIX_MEMALIGN
|
||||
#define LIBOMP_HAVE__ALIGNED_MALLOC 0
|
||||
#define KMP_HAVE__ALIGNED_MALLOC LIBOMP_HAVE__ALIGNED_MALLOC
|
||||
#define OPENMP_ENABLE_LIBOMPTARGET 0
|
||||
#define ENABLE_LIBOMPTARGET OPENMP_ENABLE_LIBOMPTARGET
|
||||
|
||||
// Configured cache line based on architecture
|
||||
#if KMP_ARCH_PPC64 || KMP_ARCH_PPC
|
||||
# define CACHE_LINE 128
|
||||
#elif KMP_ARCH_AARCH64_A64FX
|
||||
# define CACHE_LINE 256
|
||||
#elif KMP_ARCH_S390X
|
||||
# define CACHE_LINE 256
|
||||
#else
|
||||
# define CACHE_LINE 64
|
||||
#endif
|
||||
|
||||
#if ! KMP_32_BIT_ARCH
|
||||
# define BUILD_I8 1
|
||||
#endif
|
||||
|
||||
#define KMP_NESTED_HOT_TEAMS 1
|
||||
#define KMP_ADJUST_BLOCKTIME 1
|
||||
#define BUILD_PARALLEL_ORDERED 1
|
||||
#define KMP_ASM_INTRINS 1
|
||||
#define USE_ITT_BUILD LIBOMP_USE_ITT_NOTIFY
|
||||
#define INTEL_ITTNOTIFY_PREFIX __kmp_itt_
|
||||
#if ! KMP_MIC
|
||||
# define USE_LOAD_BALANCE 1
|
||||
#endif
|
||||
#if ! (KMP_OS_WINDOWS || KMP_OS_DARWIN)
|
||||
# define KMP_TDATA_GTID 1
|
||||
#endif
|
||||
#if STUBS_LIBRARY
|
||||
# define KMP_STUB 1
|
||||
#endif
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
# define KMP_WIN_CDECL
|
||||
#else
|
||||
# define BUILD_TV
|
||||
# define KMP_GOMP_COMPAT
|
||||
#endif
|
||||
|
||||
// use shared memory with dynamic library (except Android, where shm_*
|
||||
// functions don't exist).
|
||||
#if KMP_OS_UNIX && KMP_DYNAMIC_LIB && !__ANDROID__
|
||||
#define KMP_USE_SHM
|
||||
#endif
|
||||
|
||||
#endif // KMP_CONFIG_H
|
4569
third_party/openmp/kmp_csupport.cpp
vendored
Normal file
4569
third_party/openmp/kmp_csupport.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
131
third_party/openmp/kmp_debug.cpp
vendored
Normal file
131
third_party/openmp/kmp_debug.cpp
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* kmp_debug.cpp -- debug utilities for the Guide library
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_debug.h" /* really necessary? */
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_io.h"
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
void __kmp_debug_printf_stdout(char const *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
__kmp_vprintf(kmp_out, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __kmp_debug_printf(char const *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
__kmp_vprintf(kmp_err, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef KMP_USE_ASSERT
|
||||
int __kmp_debug_assert(char const *msg, char const *file, int line) {
|
||||
|
||||
if (file == NULL) {
|
||||
file = KMP_I18N_STR(UnknownFile);
|
||||
} else {
|
||||
// Remove directories from path, leave only file name. File name is enough,
|
||||
// there is no need in bothering developers and customers with full paths.
|
||||
char const *slash = strrchr(file, '/');
|
||||
if (slash != NULL) {
|
||||
file = slash + 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
__kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
|
||||
__kmp_debug_printf("Assertion failure at %s(%d): %s.\n", file, line, msg);
|
||||
__kmp_release_bootstrap_lock(&__kmp_stdio_lock);
|
||||
#ifdef USE_ASSERT_BREAK
|
||||
#if KMP_OS_WINDOWS
|
||||
DebugBreak();
|
||||
#endif
|
||||
#endif // USE_ASSERT_BREAK
|
||||
#ifdef USE_ASSERT_STALL
|
||||
/* __kmp_infinite_loop(); */
|
||||
for (;;)
|
||||
;
|
||||
#endif // USE_ASSERT_STALL
|
||||
#ifdef USE_ASSERT_SEG
|
||||
{
|
||||
int volatile *ZERO = (int *)0;
|
||||
++(*ZERO);
|
||||
}
|
||||
#endif // USE_ASSERT_SEG
|
||||
#endif
|
||||
|
||||
__kmp_fatal(KMP_MSG(AssertionFailure, file, line), KMP_HNT(SubmitBugReport),
|
||||
__kmp_msg_null);
|
||||
|
||||
return 0;
|
||||
|
||||
} // __kmp_debug_assert
|
||||
|
||||
#endif // KMP_USE_ASSERT
|
||||
|
||||
/* Dump debugging buffer to stderr */
|
||||
void __kmp_dump_debug_buffer(void) {
|
||||
if (__kmp_debug_buffer != NULL) {
|
||||
int i;
|
||||
int dc = __kmp_debug_count;
|
||||
char *db = &__kmp_debug_buffer[(dc % __kmp_debug_buf_lines) *
|
||||
__kmp_debug_buf_chars];
|
||||
char *db_end =
|
||||
&__kmp_debug_buffer[__kmp_debug_buf_lines * __kmp_debug_buf_chars];
|
||||
char *db2;
|
||||
|
||||
__kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
|
||||
__kmp_printf_no_lock("\nStart dump of debugging buffer (entry=%d):\n",
|
||||
dc % __kmp_debug_buf_lines);
|
||||
|
||||
for (i = 0; i < __kmp_debug_buf_lines; i++) {
|
||||
|
||||
if (*db != '\0') {
|
||||
/* Fix up where no carriage return before string termination char */
|
||||
for (db2 = db + 1; db2 < db + __kmp_debug_buf_chars - 1; db2++) {
|
||||
if (*db2 == '\0') {
|
||||
if (*(db2 - 1) != '\n') {
|
||||
*db2 = '\n';
|
||||
*(db2 + 1) = '\0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Handle case at end by shortening the printed message by one char if
|
||||
* necessary */
|
||||
if (db2 == db + __kmp_debug_buf_chars - 1 && *db2 == '\0' &&
|
||||
*(db2 - 1) != '\n') {
|
||||
*(db2 - 1) = '\n';
|
||||
}
|
||||
|
||||
__kmp_printf_no_lock("%4d: %.*s", i, __kmp_debug_buf_chars, db);
|
||||
*db = '\0'; /* only let it print once! */
|
||||
}
|
||||
|
||||
db += __kmp_debug_buf_chars;
|
||||
if (db >= db_end)
|
||||
db = __kmp_debug_buffer;
|
||||
}
|
||||
|
||||
__kmp_printf_no_lock("End dump of debugging buffer (entry=%d).\n\n",
|
||||
(dc + i - 1) % __kmp_debug_buf_lines);
|
||||
__kmp_release_bootstrap_lock(&__kmp_stdio_lock);
|
||||
}
|
||||
}
|
179
third_party/openmp/kmp_debug.h
vendored
Normal file
179
third_party/openmp/kmp_debug.h
vendored
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* kmp_debug.h -- debug / assertion code for Assure library
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_DEBUG_H
|
||||
#define KMP_DEBUG_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Build-time assertion.
|
||||
|
||||
// New C++11 style build assert
|
||||
#define KMP_BUILD_ASSERT(expr) static_assert(expr, "Build condition error")
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Run-time assertions.
|
||||
|
||||
extern void __kmp_dump_debug_buffer(void);
|
||||
|
||||
#ifdef KMP_USE_ASSERT
|
||||
extern int __kmp_debug_assert(char const *expr, char const *file, int line);
|
||||
#ifdef KMP_DEBUG
|
||||
#define KMP_ASSERT(cond) \
|
||||
if (!(cond)) { \
|
||||
__kmp_debug_assert(#cond, __FILE__, __LINE__); \
|
||||
}
|
||||
#define KMP_ASSERT2(cond, msg) \
|
||||
if (!(cond)) { \
|
||||
__kmp_debug_assert((msg), __FILE__, __LINE__); \
|
||||
}
|
||||
#define KMP_DEBUG_ASSERT(cond) KMP_ASSERT(cond)
|
||||
#define KMP_DEBUG_ASSERT2(cond, msg) KMP_ASSERT2(cond, msg)
|
||||
#define KMP_DEBUG_USE_VAR(x) /* Nothing (it is used!) */
|
||||
#else
|
||||
// Do not expose condition in release build. Use "assertion failure".
|
||||
#define KMP_ASSERT(cond) \
|
||||
if (!(cond)) { \
|
||||
__kmp_debug_assert("assertion failure", __FILE__, __LINE__); \
|
||||
}
|
||||
#define KMP_ASSERT2(cond, msg) KMP_ASSERT(cond)
|
||||
#define KMP_DEBUG_ASSERT(cond) /* Nothing */
|
||||
#define KMP_DEBUG_ASSERT2(cond, msg) /* Nothing */
|
||||
#define KMP_DEBUG_USE_VAR(x) ((void)(x))
|
||||
#endif // KMP_DEBUG
|
||||
#else
|
||||
#define KMP_ASSERT(cond) /* Nothing */
|
||||
#define KMP_ASSERT2(cond, msg) /* Nothing */
|
||||
#define KMP_DEBUG_ASSERT(cond) /* Nothing */
|
||||
#define KMP_DEBUG_ASSERT2(cond, msg) /* Nothing */
|
||||
#define KMP_DEBUG_USE_VAR(x) ((void)(x))
|
||||
#endif // KMP_USE_ASSERT
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
extern void __kmp_debug_printf_stdout(char const *format, ...);
|
||||
#endif
|
||||
extern void __kmp_debug_printf(char const *format, ...);
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
|
||||
extern int kmp_a_debug;
|
||||
extern int kmp_b_debug;
|
||||
extern int kmp_c_debug;
|
||||
extern int kmp_d_debug;
|
||||
extern int kmp_e_debug;
|
||||
extern int kmp_f_debug;
|
||||
extern int kmp_diag;
|
||||
|
||||
#define KA_TRACE(d, x) \
|
||||
if (kmp_a_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KB_TRACE(d, x) \
|
||||
if (kmp_b_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KC_TRACE(d, x) \
|
||||
if (kmp_c_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KD_TRACE(d, x) \
|
||||
if (kmp_d_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KE_TRACE(d, x) \
|
||||
if (kmp_e_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KF_TRACE(d, x) \
|
||||
if (kmp_f_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define K_DIAG(d, x) \
|
||||
{ \
|
||||
if (kmp_diag == d) { \
|
||||
__kmp_debug_printf_stdout x; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define KA_DUMP(d, x) \
|
||||
if (kmp_a_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KB_DUMP(d, x) \
|
||||
if (kmp_b_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KC_DUMP(d, x) \
|
||||
if (kmp_c_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KD_DUMP(d, x) \
|
||||
if (kmp_d_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KE_DUMP(d, x) \
|
||||
if (kmp_e_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KF_DUMP(d, x) \
|
||||
if (kmp_f_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define KA_TRACE(d, x) /* nothing to do */
|
||||
#define KB_TRACE(d, x) /* nothing to do */
|
||||
#define KC_TRACE(d, x) /* nothing to do */
|
||||
#define KD_TRACE(d, x) /* nothing to do */
|
||||
#define KE_TRACE(d, x) /* nothing to do */
|
||||
#define KF_TRACE(d, x) /* nothing to do */
|
||||
#define K_DIAG(d, x) \
|
||||
{} /* nothing to do */
|
||||
|
||||
#define KA_DUMP(d, x) /* nothing to do */
|
||||
#define KB_DUMP(d, x) /* nothing to do */
|
||||
#define KC_DUMP(d, x) /* nothing to do */
|
||||
#define KD_DUMP(d, x) /* nothing to do */
|
||||
#define KE_DUMP(d, x) /* nothing to do */
|
||||
#define KF_DUMP(d, x) /* nothing to do */
|
||||
|
||||
#endif // KMP_DEBUG
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* KMP_DEBUG_H */
|
286
third_party/openmp/kmp_debugger.cpp
vendored
Normal file
286
third_party/openmp/kmp_debugger.cpp
vendored
Normal file
|
@ -0,0 +1,286 @@
|
|||
#include "kmp_config.h"
|
||||
|
||||
#if USE_DEBUGGER
|
||||
/*
|
||||
* kmp_debugger.cpp -- debugger support.
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_lock.h"
|
||||
#include "kmp_omp.h"
|
||||
#include "kmp_str.h"
|
||||
|
||||
// NOTE: All variable names are known to the debugger, do not change!
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern kmp_omp_struct_info_t __kmp_omp_debug_struct_info;
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
int __kmp_debugging = FALSE; // Boolean whether currently debugging OpenMP RTL.
|
||||
|
||||
#define offset_and_size_of(structure, field) \
|
||||
{ offsetof(structure, field), sizeof(((structure *)NULL)->field) }
|
||||
|
||||
#define offset_and_size_not_available \
|
||||
{ -1, -1 }
|
||||
|
||||
#define addr_and_size_of(var) \
|
||||
{ (kmp_uint64)(&var), sizeof(var) }
|
||||
|
||||
#define nthr_buffer_size 1024
|
||||
static kmp_int32 kmp_omp_nthr_info_buffer[nthr_buffer_size] = {
|
||||
nthr_buffer_size * sizeof(kmp_int32)};
|
||||
|
||||
/* TODO: Check punctuation for various platforms here */
|
||||
static char func_microtask[] = "__kmp_invoke_microtask";
|
||||
static char func_fork[] = "__kmpc_fork_call";
|
||||
static char func_fork_teams[] = "__kmpc_fork_teams";
|
||||
|
||||
// Various info about runtime structures: addresses, field offsets, sizes, etc.
|
||||
kmp_omp_struct_info_t __kmp_omp_debug_struct_info = {
|
||||
|
||||
/* Change this only if you make a fundamental data structure change here */
|
||||
KMP_OMP_VERSION,
|
||||
|
||||
/* sanity check. Only should be checked if versions are identical
|
||||
* This is also used for backward compatibility to get the runtime
|
||||
* structure size if it the runtime is older than the interface */
|
||||
sizeof(kmp_omp_struct_info_t),
|
||||
|
||||
/* OpenMP RTL version info. */
|
||||
addr_and_size_of(__kmp_version_major),
|
||||
addr_and_size_of(__kmp_version_minor),
|
||||
addr_and_size_of(__kmp_version_build),
|
||||
addr_and_size_of(__kmp_openmp_version),
|
||||
{(kmp_uint64)(__kmp_copyright) + KMP_VERSION_MAGIC_LEN,
|
||||
0}, // Skip magic prefix.
|
||||
|
||||
/* Various globals. */
|
||||
addr_and_size_of(__kmp_threads),
|
||||
addr_and_size_of(__kmp_root),
|
||||
addr_and_size_of(__kmp_threads_capacity),
|
||||
#if KMP_USE_MONITOR
|
||||
addr_and_size_of(__kmp_monitor),
|
||||
#endif
|
||||
#if !KMP_USE_DYNAMIC_LOCK
|
||||
addr_and_size_of(__kmp_user_lock_table),
|
||||
#endif
|
||||
addr_and_size_of(func_microtask),
|
||||
addr_and_size_of(func_fork),
|
||||
addr_and_size_of(func_fork_teams),
|
||||
addr_and_size_of(__kmp_team_counter),
|
||||
addr_and_size_of(__kmp_task_counter),
|
||||
addr_and_size_of(kmp_omp_nthr_info_buffer),
|
||||
sizeof(void *),
|
||||
OMP_LOCK_T_SIZE < sizeof(void *),
|
||||
bs_last_barrier,
|
||||
INITIAL_TASK_DEQUE_SIZE,
|
||||
|
||||
// thread structure information
|
||||
sizeof(kmp_base_info_t),
|
||||
offset_and_size_of(kmp_base_info_t, th_info),
|
||||
offset_and_size_of(kmp_base_info_t, th_team),
|
||||
offset_and_size_of(kmp_base_info_t, th_root),
|
||||
offset_and_size_of(kmp_base_info_t, th_serial_team),
|
||||
offset_and_size_of(kmp_base_info_t, th_ident),
|
||||
offset_and_size_of(kmp_base_info_t, th_spin_here),
|
||||
offset_and_size_of(kmp_base_info_t, th_next_waiting),
|
||||
offset_and_size_of(kmp_base_info_t, th_task_team),
|
||||
offset_and_size_of(kmp_base_info_t, th_current_task),
|
||||
offset_and_size_of(kmp_base_info_t, th_task_state),
|
||||
offset_and_size_of(kmp_base_info_t, th_bar),
|
||||
offset_and_size_of(kmp_bstate_t, b_worker_arrived),
|
||||
|
||||
// teams information
|
||||
offset_and_size_of(kmp_base_info_t, th_teams_microtask),
|
||||
offset_and_size_of(kmp_base_info_t, th_teams_level),
|
||||
offset_and_size_of(kmp_teams_size_t, nteams),
|
||||
offset_and_size_of(kmp_teams_size_t, nth),
|
||||
|
||||
// kmp_desc structure (for info field above)
|
||||
sizeof(kmp_desc_base_t),
|
||||
offset_and_size_of(kmp_desc_base_t, ds_tid),
|
||||
offset_and_size_of(kmp_desc_base_t, ds_gtid),
|
||||
// On Windows* OS, ds_thread contains a thread /handle/, which is not usable,
|
||||
// while thread /id/ is in ds_thread_id.
|
||||
#if KMP_OS_WINDOWS
|
||||
offset_and_size_of(kmp_desc_base_t, ds_thread_id),
|
||||
#else
|
||||
offset_and_size_of(kmp_desc_base_t, ds_thread),
|
||||
#endif
|
||||
|
||||
// team structure information
|
||||
sizeof(kmp_base_team_t),
|
||||
offset_and_size_of(kmp_base_team_t, t_master_tid),
|
||||
offset_and_size_of(kmp_base_team_t, t_ident),
|
||||
offset_and_size_of(kmp_base_team_t, t_parent),
|
||||
offset_and_size_of(kmp_base_team_t, t_nproc),
|
||||
offset_and_size_of(kmp_base_team_t, t_threads),
|
||||
offset_and_size_of(kmp_base_team_t, t_serialized),
|
||||
offset_and_size_of(kmp_base_team_t, t_id),
|
||||
offset_and_size_of(kmp_base_team_t, t_pkfn),
|
||||
offset_and_size_of(kmp_base_team_t, t_task_team),
|
||||
offset_and_size_of(kmp_base_team_t, t_implicit_task_taskdata),
|
||||
offset_and_size_of(kmp_base_team_t, t_cancel_request),
|
||||
offset_and_size_of(kmp_base_team_t, t_bar),
|
||||
offset_and_size_of(kmp_balign_team_t, b_master_arrived),
|
||||
offset_and_size_of(kmp_balign_team_t, b_team_arrived),
|
||||
|
||||
// root structure information
|
||||
sizeof(kmp_base_root_t),
|
||||
offset_and_size_of(kmp_base_root_t, r_root_team),
|
||||
offset_and_size_of(kmp_base_root_t, r_hot_team),
|
||||
offset_and_size_of(kmp_base_root_t, r_uber_thread),
|
||||
offset_and_size_not_available,
|
||||
|
||||
// ident structure information
|
||||
sizeof(ident_t),
|
||||
offset_and_size_of(ident_t, psource),
|
||||
offset_and_size_of(ident_t, flags),
|
||||
|
||||
// lock structure information
|
||||
sizeof(kmp_base_queuing_lock_t),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, initialized),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, location),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, tail_id),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, head_id),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, next_ticket),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, now_serving),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, owner_id),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, depth_locked),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, flags),
|
||||
|
||||
#if !KMP_USE_DYNAMIC_LOCK
|
||||
/* Lock table. */
|
||||
sizeof(kmp_lock_table_t),
|
||||
offset_and_size_of(kmp_lock_table_t, used),
|
||||
offset_and_size_of(kmp_lock_table_t, allocated),
|
||||
offset_and_size_of(kmp_lock_table_t, table),
|
||||
#endif
|
||||
|
||||
// Task team structure information.
|
||||
sizeof(kmp_base_task_team_t),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_threads_data),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_found_tasks),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_nproc),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_unfinished_threads),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_active),
|
||||
|
||||
// task_data_t.
|
||||
sizeof(kmp_taskdata_t),
|
||||
offset_and_size_of(kmp_taskdata_t, td_task_id),
|
||||
offset_and_size_of(kmp_taskdata_t, td_flags),
|
||||
offset_and_size_of(kmp_taskdata_t, td_team),
|
||||
offset_and_size_of(kmp_taskdata_t, td_parent),
|
||||
offset_and_size_of(kmp_taskdata_t, td_level),
|
||||
offset_and_size_of(kmp_taskdata_t, td_ident),
|
||||
offset_and_size_of(kmp_taskdata_t, td_allocated_child_tasks),
|
||||
offset_and_size_of(kmp_taskdata_t, td_incomplete_child_tasks),
|
||||
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskwait_ident),
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskwait_counter),
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskwait_thread),
|
||||
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskgroup),
|
||||
offset_and_size_of(kmp_taskgroup_t, count),
|
||||
offset_and_size_of(kmp_taskgroup_t, cancel_request),
|
||||
|
||||
offset_and_size_of(kmp_taskdata_t, td_depnode),
|
||||
offset_and_size_of(kmp_depnode_list_t, node),
|
||||
offset_and_size_of(kmp_depnode_list_t, next),
|
||||
offset_and_size_of(kmp_base_depnode_t, successors),
|
||||
offset_and_size_of(kmp_base_depnode_t, task),
|
||||
offset_and_size_of(kmp_base_depnode_t, npredecessors),
|
||||
offset_and_size_of(kmp_base_depnode_t, nrefs),
|
||||
offset_and_size_of(kmp_task_t, routine),
|
||||
|
||||
// thread_data_t.
|
||||
sizeof(kmp_thread_data_t),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_size),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_head),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_tail),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_ntasks),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_last_stolen),
|
||||
|
||||
// The last field.
|
||||
KMP_OMP_VERSION,
|
||||
|
||||
}; // __kmp_omp_debug_struct_info
|
||||
|
||||
#undef offset_and_size_of
|
||||
#undef addr_and_size_of
|
||||
|
||||
/* Intel compiler on IA-32 architecture issues a warning "conversion
|
||||
from "unsigned long long" to "char *" may lose significant bits"
|
||||
when 64-bit value is assigned to 32-bit pointer. Use this function
|
||||
to suppress the warning. */
|
||||
static inline void *__kmp_convert_to_ptr(kmp_uint64 addr) {
|
||||
#if KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 810) // conversion from "unsigned long long" to "char
|
||||
// *" may lose significant bits
|
||||
#pragma warning(disable : 1195) // conversion from integer to smaller pointer
|
||||
#endif // KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
||||
return (void *)addr;
|
||||
#if KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
||||
#pragma warning(pop)
|
||||
#endif // KMP_COMPILER_ICC || KMP_COMPILER_ICX
|
||||
} // __kmp_convert_to_ptr
|
||||
|
||||
static int kmp_location_match(kmp_str_loc_t *loc, kmp_omp_nthr_item_t *item) {
|
||||
|
||||
int file_match = 0;
|
||||
int func_match = 0;
|
||||
int line_match = 0;
|
||||
|
||||
char *file = (char *)__kmp_convert_to_ptr(item->file);
|
||||
char *func = (char *)__kmp_convert_to_ptr(item->func);
|
||||
file_match = __kmp_str_fname_match(&loc->fname, file);
|
||||
func_match =
|
||||
item->func == 0 // If item->func is NULL, it allows any func name.
|
||||
|| strcmp(func, "*") == 0 ||
|
||||
(loc->func != NULL && strcmp(loc->func, func) == 0);
|
||||
line_match =
|
||||
item->begin <= loc->line &&
|
||||
(item->end <= 0 ||
|
||||
loc->line <= item->end); // if item->end <= 0, it means "end of file".
|
||||
|
||||
return (file_match && func_match && line_match);
|
||||
|
||||
} // kmp_location_match
|
||||
|
||||
int __kmp_omp_num_threads(ident_t const *ident) {
|
||||
|
||||
int num_threads = 0;
|
||||
|
||||
kmp_omp_nthr_info_t *info = (kmp_omp_nthr_info_t *)__kmp_convert_to_ptr(
|
||||
__kmp_omp_debug_struct_info.nthr_info.addr);
|
||||
if (info->num > 0 && info->array != 0) {
|
||||
kmp_omp_nthr_item_t *items =
|
||||
(kmp_omp_nthr_item_t *)__kmp_convert_to_ptr(info->array);
|
||||
kmp_str_loc_t loc = __kmp_str_loc_init(ident->psource, true);
|
||||
int i;
|
||||
for (i = 0; i < info->num; ++i) {
|
||||
if (kmp_location_match(&loc, &items[i])) {
|
||||
num_threads = items[i].num_threads;
|
||||
}
|
||||
}
|
||||
__kmp_str_loc_free(&loc);
|
||||
}
|
||||
|
||||
return num_threads;
|
||||
;
|
||||
|
||||
} // __kmp_omp_num_threads
|
||||
#endif /* USE_DEBUGGER */
|
48
third_party/openmp/kmp_debugger.h
vendored
Normal file
48
third_party/openmp/kmp_debugger.h
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
#if USE_DEBUGGER
|
||||
/*
|
||||
* kmp_debugger.h -- debugger support.
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_DEBUGGER_H
|
||||
#define KMP_DEBUGGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/* This external variable can be set by any debugger to flag to the runtime
|
||||
that we are currently executing inside a debugger. This will allow the
|
||||
debugger to override the number of threads spawned in a parallel region by
|
||||
using __kmp_omp_num_threads() (below).
|
||||
* When __kmp_debugging is TRUE, each team and each task gets a unique integer
|
||||
identifier that can be used by debugger to conveniently identify teams and
|
||||
tasks.
|
||||
* The debugger has access to __kmp_omp_debug_struct_info which contains
|
||||
information about the OpenMP library's important internal structures. This
|
||||
access will allow the debugger to read detailed information from the typical
|
||||
OpenMP constructs (teams, threads, tasking, etc. ) during a debugging
|
||||
session and offer detailed and useful information which the user can probe
|
||||
about the OpenMP portion of their code. */
|
||||
extern int __kmp_debugging; /* Boolean whether currently debugging OpenMP RTL */
|
||||
// Return number of threads specified by the debugger for given parallel region.
|
||||
/* The ident field, which represents a source file location, is used to check if
|
||||
the debugger has changed the number of threads for the parallel region at
|
||||
source file location ident. This way, specific parallel regions' number of
|
||||
threads can be changed at the debugger's request. */
|
||||
int __kmp_omp_num_threads(ident_t const *ident);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // KMP_DEBUGGER_H
|
||||
|
||||
#endif // USE_DEBUGGER
|
3142
third_party/openmp/kmp_dispatch.cpp
vendored
Normal file
3142
third_party/openmp/kmp_dispatch.cpp
vendored
Normal file
File diff suppressed because it is too large
Load diff
513
third_party/openmp/kmp_dispatch.h
vendored
Normal file
513
third_party/openmp/kmp_dispatch.h
vendored
Normal file
|
@ -0,0 +1,513 @@
|
|||
/*
|
||||
* kmp_dispatch.h: dynamic scheduling - iteration initialization and dispatch.
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_DISPATCH_H
|
||||
#define KMP_DISPATCH_H
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_error.h"
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_itt.h"
|
||||
#include "kmp_stats.h"
|
||||
#include "kmp_str.h"
|
||||
#if KMP_OS_WINDOWS && KMP_ARCH_X86
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
#if OMPT_SUPPORT
|
||||
#include "ompt-internal.h"
|
||||
#include "ompt-specific.h"
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
#if KMP_USE_HIER_SCHED
|
||||
// Forward declarations of some hierarchical scheduling data structures
|
||||
template <typename T> struct kmp_hier_t;
|
||||
template <typename T> struct kmp_hier_top_unit_t;
|
||||
#endif // KMP_USE_HIER_SCHED
|
||||
|
||||
template <typename T> struct dispatch_shared_info_template;
|
||||
template <typename T> struct dispatch_private_info_template;
|
||||
|
||||
template <typename T>
|
||||
extern void __kmp_dispatch_init_algorithm(ident_t *loc, int gtid,
|
||||
dispatch_private_info_template<T> *pr,
|
||||
enum sched_type schedule, T lb, T ub,
|
||||
typename traits_t<T>::signed_t st,
|
||||
#if USE_ITT_BUILD
|
||||
kmp_uint64 *cur_chunk,
|
||||
#endif
|
||||
typename traits_t<T>::signed_t chunk,
|
||||
T nproc, T unit_id);
|
||||
template <typename T>
|
||||
extern int __kmp_dispatch_next_algorithm(
|
||||
int gtid, dispatch_private_info_template<T> *pr,
|
||||
dispatch_shared_info_template<T> volatile *sh, kmp_int32 *p_last, T *p_lb,
|
||||
T *p_ub, typename traits_t<T>::signed_t *p_st, T nproc, T unit_id);
|
||||
|
||||
void __kmp_dispatch_dxo_error(int *gtid_ref, int *cid_ref, ident_t *loc_ref);
|
||||
void __kmp_dispatch_deo_error(int *gtid_ref, int *cid_ref, ident_t *loc_ref);
|
||||
|
||||
#if KMP_STATIC_STEAL_ENABLED
|
||||
|
||||
// replaces dispatch_private_info{32,64} structures and
|
||||
// dispatch_private_info{32,64}_t types
|
||||
template <typename T> struct dispatch_private_infoXX_template {
|
||||
typedef typename traits_t<T>::unsigned_t UT;
|
||||
typedef typename traits_t<T>::signed_t ST;
|
||||
UT count; // unsigned
|
||||
T ub;
|
||||
/* Adding KMP_ALIGN_CACHE here doesn't help / can hurt performance */
|
||||
T lb;
|
||||
ST st; // signed
|
||||
UT tc; // unsigned
|
||||
kmp_lock_t *steal_lock; // lock used for chunk stealing
|
||||
|
||||
UT ordered_lower; // unsigned
|
||||
UT ordered_upper; // unsigned
|
||||
|
||||
/* parm[1-4] are used in different ways by different scheduling algorithms */
|
||||
|
||||
// KMP_ALIGN(32) ensures ( if the KMP_ALIGN macro is turned on )
|
||||
// a) parm3 is properly aligned and
|
||||
// b) all parm1-4 are in the same cache line.
|
||||
// Because of parm1-4 are used together, performance seems to be better
|
||||
// if they are in the same line (not measured though).
|
||||
struct KMP_ALIGN(32) { // compiler does not accept sizeof(T)*4
|
||||
T parm1;
|
||||
T parm2;
|
||||
T parm3;
|
||||
T parm4;
|
||||
};
|
||||
|
||||
#if KMP_WEIGHTED_ITERATIONS_SUPPORTED
|
||||
UT pchunks; // total number of chunks for processes with p-core
|
||||
UT num_procs_with_pcore; // number of threads with p-core
|
||||
T first_thread_with_ecore;
|
||||
#endif
|
||||
#if KMP_OS_WINDOWS
|
||||
T last_upper;
|
||||
#endif /* KMP_OS_WINDOWS */
|
||||
};
|
||||
|
||||
#else /* KMP_STATIC_STEAL_ENABLED */
|
||||
|
||||
// replaces dispatch_private_info{32,64} structures and
|
||||
// dispatch_private_info{32,64}_t types
|
||||
template <typename T> struct dispatch_private_infoXX_template {
|
||||
typedef typename traits_t<T>::unsigned_t UT;
|
||||
typedef typename traits_t<T>::signed_t ST;
|
||||
T lb;
|
||||
T ub;
|
||||
ST st; // signed
|
||||
UT tc; // unsigned
|
||||
|
||||
T parm1;
|
||||
T parm2;
|
||||
T parm3;
|
||||
T parm4;
|
||||
|
||||
UT count; // unsigned
|
||||
|
||||
UT ordered_lower; // unsigned
|
||||
UT ordered_upper; // unsigned
|
||||
#if KMP_OS_WINDOWS
|
||||
T last_upper;
|
||||
#endif /* KMP_OS_WINDOWS */
|
||||
};
|
||||
#endif /* KMP_STATIC_STEAL_ENABLED */
|
||||
|
||||
template <typename T> struct KMP_ALIGN_CACHE dispatch_private_info_template {
|
||||
// duplicate alignment here, otherwise size of structure is not correct in our
|
||||
// compiler
|
||||
union KMP_ALIGN_CACHE private_info_tmpl {
|
||||
dispatch_private_infoXX_template<T> p;
|
||||
dispatch_private_info64_t p64;
|
||||
} u;
|
||||
enum sched_type schedule; /* scheduling algorithm */
|
||||
kmp_sched_flags_t flags; /* flags (e.g., ordered, nomerge, etc.) */
|
||||
std::atomic<kmp_uint32> steal_flag; // static_steal only, state of a buffer
|
||||
kmp_uint32 ordered_bumped;
|
||||
dispatch_private_info *next; /* stack of buffers for nest of serial regions */
|
||||
kmp_uint32 type_size;
|
||||
#if KMP_USE_HIER_SCHED
|
||||
kmp_int32 hier_id;
|
||||
kmp_hier_top_unit_t<T> *hier_parent;
|
||||
// member functions
|
||||
kmp_int32 get_hier_id() const { return hier_id; }
|
||||
kmp_hier_top_unit_t<T> *get_parent() { return hier_parent; }
|
||||
#endif
|
||||
enum cons_type pushed_ws;
|
||||
};
|
||||
|
||||
// replaces dispatch_shared_info{32,64} structures and
|
||||
// dispatch_shared_info{32,64}_t types
|
||||
template <typename T> struct dispatch_shared_infoXX_template {
|
||||
typedef typename traits_t<T>::unsigned_t UT;
|
||||
typedef typename traits_t<T>::signed_t ST;
|
||||
/* chunk index under dynamic, number of idle threads under static-steal;
|
||||
iteration index otherwise */
|
||||
volatile UT iteration;
|
||||
volatile ST num_done;
|
||||
volatile UT ordered_iteration;
|
||||
// to retain the structure size making ordered_iteration scalar
|
||||
UT ordered_dummy[KMP_MAX_ORDERED - 3];
|
||||
};
|
||||
|
||||
// replaces dispatch_shared_info structure and dispatch_shared_info_t type
|
||||
template <typename T> struct dispatch_shared_info_template {
|
||||
typedef typename traits_t<T>::unsigned_t UT;
|
||||
// we need union here to keep the structure size
|
||||
union shared_info_tmpl {
|
||||
dispatch_shared_infoXX_template<UT> s;
|
||||
dispatch_shared_info64_t s64;
|
||||
} u;
|
||||
volatile kmp_uint32 buffer_index;
|
||||
volatile kmp_int32 doacross_buf_idx; // teamwise index
|
||||
kmp_uint32 *doacross_flags; // array of iteration flags (0/1)
|
||||
kmp_int32 doacross_num_done; // count finished threads
|
||||
#if KMP_USE_HIER_SCHED
|
||||
kmp_hier_t<T> *hier;
|
||||
#endif
|
||||
#if KMP_USE_HWLOC
|
||||
// When linking with libhwloc, the ORDERED EPCC test slowsdown on big
|
||||
// machines (> 48 cores). Performance analysis showed that a cache thrash
|
||||
// was occurring and this padding helps alleviate the problem.
|
||||
char padding[64];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#undef USE_TEST_LOCKS
|
||||
|
||||
// test_then_add template (general template should NOT be used)
|
||||
template <typename T> static __forceinline T test_then_add(volatile T *p, T d);
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int32 test_then_add<kmp_int32>(volatile kmp_int32 *p,
|
||||
kmp_int32 d) {
|
||||
kmp_int32 r;
|
||||
r = KMP_TEST_THEN_ADD32(p, d);
|
||||
return r;
|
||||
}
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int64 test_then_add<kmp_int64>(volatile kmp_int64 *p,
|
||||
kmp_int64 d) {
|
||||
kmp_int64 r;
|
||||
r = KMP_TEST_THEN_ADD64(p, d);
|
||||
return r;
|
||||
}
|
||||
|
||||
// test_then_inc_acq template (general template should NOT be used)
|
||||
template <typename T> static __forceinline T test_then_inc_acq(volatile T *p);
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int32 test_then_inc_acq<kmp_int32>(volatile kmp_int32 *p) {
|
||||
kmp_int32 r;
|
||||
r = KMP_TEST_THEN_INC_ACQ32(p);
|
||||
return r;
|
||||
}
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int64 test_then_inc_acq<kmp_int64>(volatile kmp_int64 *p) {
|
||||
kmp_int64 r;
|
||||
r = KMP_TEST_THEN_INC_ACQ64(p);
|
||||
return r;
|
||||
}
|
||||
|
||||
// test_then_inc template (general template should NOT be used)
|
||||
template <typename T> static __forceinline T test_then_inc(volatile T *p);
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int32 test_then_inc<kmp_int32>(volatile kmp_int32 *p) {
|
||||
kmp_int32 r;
|
||||
r = KMP_TEST_THEN_INC32(p);
|
||||
return r;
|
||||
}
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int64 test_then_inc<kmp_int64>(volatile kmp_int64 *p) {
|
||||
kmp_int64 r;
|
||||
r = KMP_TEST_THEN_INC64(p);
|
||||
return r;
|
||||
}
|
||||
|
||||
// compare_and_swap template (general template should NOT be used)
|
||||
template <typename T>
|
||||
static __forceinline kmp_int32 compare_and_swap(volatile T *p, T c, T s);
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int32 compare_and_swap<kmp_int32>(volatile kmp_int32 *p,
|
||||
kmp_int32 c, kmp_int32 s) {
|
||||
return KMP_COMPARE_AND_STORE_REL32(p, c, s);
|
||||
}
|
||||
|
||||
template <>
|
||||
__forceinline kmp_int32 compare_and_swap<kmp_int64>(volatile kmp_int64 *p,
|
||||
kmp_int64 c, kmp_int64 s) {
|
||||
return KMP_COMPARE_AND_STORE_REL64(p, c, s);
|
||||
}
|
||||
|
||||
template <typename T> kmp_uint32 __kmp_ge(T value, T checker) {
|
||||
return value >= checker;
|
||||
}
|
||||
template <typename T> kmp_uint32 __kmp_eq(T value, T checker) {
|
||||
return value == checker;
|
||||
}
|
||||
|
||||
/*
|
||||
Spin wait loop that pauses between checks.
|
||||
Waits until function returns non-zero when called with *spinner and check.
|
||||
Does NOT put threads to sleep.
|
||||
Arguments:
|
||||
UT is unsigned 4- or 8-byte type
|
||||
spinner - memory location to check value
|
||||
checker - value which spinner is >, <, ==, etc.
|
||||
pred - predicate function to perform binary comparison of some sort
|
||||
#if USE_ITT_BUILD
|
||||
obj -- is higher-level synchronization object to report to ittnotify. It
|
||||
is used to report locks consistently. For example, if lock is acquired
|
||||
immediately, its address is reported to ittnotify via
|
||||
KMP_FSYNC_ACQUIRED(). However, it lock cannot be acquired immediately
|
||||
and lock routine calls to KMP_WAIT(), the later should report the
|
||||
same address, not an address of low-level spinner.
|
||||
#endif // USE_ITT_BUILD
|
||||
TODO: make inline function (move to header file for icl)
|
||||
*/
|
||||
template <typename UT>
|
||||
static UT __kmp_wait(volatile UT *spinner, UT checker,
|
||||
kmp_uint32 (*pred)(UT, UT) USE_ITT_BUILD_ARG(void *obj)) {
|
||||
// note: we may not belong to a team at this point
|
||||
volatile UT *spin = spinner;
|
||||
UT check = checker;
|
||||
kmp_uint32 spins;
|
||||
kmp_uint32 (*f)(UT, UT) = pred;
|
||||
kmp_uint64 time;
|
||||
UT r;
|
||||
|
||||
KMP_FSYNC_SPIN_INIT(obj, CCAST(UT *, spin));
|
||||
KMP_INIT_YIELD(spins);
|
||||
KMP_INIT_BACKOFF(time);
|
||||
// main wait spin loop
|
||||
while (!f(r = *spin, check)) {
|
||||
KMP_FSYNC_SPIN_PREPARE(obj);
|
||||
/* GEH - remove this since it was accidentally introduced when kmp_wait was
|
||||
split.
|
||||
It causes problems with infinite recursion because of exit lock */
|
||||
/* if ( TCR_4(__kmp_global.g.g_done) && __kmp_global.g.g_abort)
|
||||
__kmp_abort_thread(); */
|
||||
// If oversubscribed, or have waited a bit then yield.
|
||||
KMP_YIELD_OVERSUB_ELSE_SPIN(spins, time);
|
||||
}
|
||||
KMP_FSYNC_SPIN_ACQUIRED(obj);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
template <typename UT>
|
||||
void __kmp_dispatch_deo(int *gtid_ref, int *cid_ref, ident_t *loc_ref) {
|
||||
dispatch_private_info_template<UT> *pr;
|
||||
|
||||
int gtid = *gtid_ref;
|
||||
// int cid = *cid_ref;
|
||||
kmp_info_t *th = __kmp_threads[gtid];
|
||||
KMP_DEBUG_ASSERT(th->th.th_dispatch);
|
||||
|
||||
KD_TRACE(100, ("__kmp_dispatch_deo: T#%d called\n", gtid));
|
||||
if (__kmp_env_consistency_check) {
|
||||
pr = reinterpret_cast<dispatch_private_info_template<UT> *>(
|
||||
th->th.th_dispatch->th_dispatch_pr_current);
|
||||
if (pr->pushed_ws != ct_none) {
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
__kmp_push_sync(gtid, ct_ordered_in_pdo, loc_ref, NULL, 0);
|
||||
#else
|
||||
__kmp_push_sync(gtid, ct_ordered_in_pdo, loc_ref, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!th->th.th_team->t.t_serialized) {
|
||||
dispatch_shared_info_template<UT> *sh =
|
||||
reinterpret_cast<dispatch_shared_info_template<UT> *>(
|
||||
th->th.th_dispatch->th_dispatch_sh_current);
|
||||
UT lower;
|
||||
|
||||
if (!__kmp_env_consistency_check) {
|
||||
pr = reinterpret_cast<dispatch_private_info_template<UT> *>(
|
||||
th->th.th_dispatch->th_dispatch_pr_current);
|
||||
}
|
||||
lower = pr->u.p.ordered_lower;
|
||||
|
||||
#if !defined(KMP_GOMP_COMPAT)
|
||||
if (__kmp_env_consistency_check) {
|
||||
if (pr->ordered_bumped) {
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsMultipleNesting,
|
||||
ct_ordered_in_pdo, loc_ref,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(KMP_GOMP_COMPAT) */
|
||||
|
||||
KMP_MB();
|
||||
#ifdef KMP_DEBUG
|
||||
{
|
||||
char *buff;
|
||||
// create format specifiers before the debug output
|
||||
buff = __kmp_str_format("__kmp_dispatch_deo: T#%%d before wait: "
|
||||
"ordered_iter:%%%s lower:%%%s\n",
|
||||
traits_t<UT>::spec, traits_t<UT>::spec);
|
||||
KD_TRACE(1000, (buff, gtid, sh->u.s.ordered_iteration, lower));
|
||||
__kmp_str_free(&buff);
|
||||
}
|
||||
#endif
|
||||
__kmp_wait<UT>(&sh->u.s.ordered_iteration, lower,
|
||||
__kmp_ge<UT> USE_ITT_BUILD_ARG(NULL));
|
||||
KMP_MB(); /* is this necessary? */
|
||||
#ifdef KMP_DEBUG
|
||||
{
|
||||
char *buff;
|
||||
// create format specifiers before the debug output
|
||||
buff = __kmp_str_format("__kmp_dispatch_deo: T#%%d after wait: "
|
||||
"ordered_iter:%%%s lower:%%%s\n",
|
||||
traits_t<UT>::spec, traits_t<UT>::spec);
|
||||
KD_TRACE(1000, (buff, gtid, sh->u.s.ordered_iteration, lower));
|
||||
__kmp_str_free(&buff);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
KD_TRACE(100, ("__kmp_dispatch_deo: T#%d returned\n", gtid));
|
||||
}
|
||||
|
||||
template <typename UT>
|
||||
void __kmp_dispatch_dxo(int *gtid_ref, int *cid_ref, ident_t *loc_ref) {
|
||||
typedef typename traits_t<UT>::signed_t ST;
|
||||
dispatch_private_info_template<UT> *pr;
|
||||
|
||||
int gtid = *gtid_ref;
|
||||
// int cid = *cid_ref;
|
||||
kmp_info_t *th = __kmp_threads[gtid];
|
||||
KMP_DEBUG_ASSERT(th->th.th_dispatch);
|
||||
|
||||
KD_TRACE(100, ("__kmp_dispatch_dxo: T#%d called\n", gtid));
|
||||
if (__kmp_env_consistency_check) {
|
||||
pr = reinterpret_cast<dispatch_private_info_template<UT> *>(
|
||||
th->th.th_dispatch->th_dispatch_pr_current);
|
||||
if (pr->pushed_ws != ct_none) {
|
||||
__kmp_pop_sync(gtid, ct_ordered_in_pdo, loc_ref);
|
||||
}
|
||||
}
|
||||
|
||||
if (!th->th.th_team->t.t_serialized) {
|
||||
dispatch_shared_info_template<UT> *sh =
|
||||
reinterpret_cast<dispatch_shared_info_template<UT> *>(
|
||||
th->th.th_dispatch->th_dispatch_sh_current);
|
||||
|
||||
if (!__kmp_env_consistency_check) {
|
||||
pr = reinterpret_cast<dispatch_private_info_template<UT> *>(
|
||||
th->th.th_dispatch->th_dispatch_pr_current);
|
||||
}
|
||||
|
||||
KMP_FSYNC_RELEASING(CCAST(UT *, &sh->u.s.ordered_iteration));
|
||||
#if !defined(KMP_GOMP_COMPAT)
|
||||
if (__kmp_env_consistency_check) {
|
||||
if (pr->ordered_bumped != 0) {
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
/* How to test it? - OM */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsMultipleNesting,
|
||||
ct_ordered_in_pdo, loc_ref,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(KMP_GOMP_COMPAT) */
|
||||
|
||||
KMP_MB(); /* Flush all pending memory write invalidates. */
|
||||
|
||||
pr->ordered_bumped += 1;
|
||||
|
||||
KD_TRACE(1000,
|
||||
("__kmp_dispatch_dxo: T#%d bumping ordered ordered_bumped=%d\n",
|
||||
gtid, pr->ordered_bumped));
|
||||
|
||||
KMP_MB(); /* Flush all pending memory write invalidates. */
|
||||
|
||||
/* TODO use general release procedure? */
|
||||
test_then_inc<ST>((volatile ST *)&sh->u.s.ordered_iteration);
|
||||
|
||||
KMP_MB(); /* Flush all pending memory write invalidates. */
|
||||
}
|
||||
KD_TRACE(100, ("__kmp_dispatch_dxo: T#%d returned\n", gtid));
|
||||
}
|
||||
|
||||
/* Computes and returns x to the power of y, where y must a non-negative integer
|
||||
*/
|
||||
template <typename UT>
|
||||
static __forceinline long double __kmp_pow(long double x, UT y) {
|
||||
long double s = 1.0L;
|
||||
|
||||
KMP_DEBUG_ASSERT(x > 0.0 && x < 1.0);
|
||||
// KMP_DEBUG_ASSERT(y >= 0); // y is unsigned
|
||||
while (y) {
|
||||
if (y & 1)
|
||||
s *= x;
|
||||
x *= x;
|
||||
y >>= 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Computes and returns the number of unassigned iterations after idx chunks
|
||||
have been assigned
|
||||
(the total number of unassigned iterations in chunks with index greater than
|
||||
or equal to idx).
|
||||
__forceinline seems to be broken so that if we __forceinline this function,
|
||||
the behavior is wrong
|
||||
(one of the unit tests, sch_guided_analytical_basic.cpp, fails)
|
||||
*/
|
||||
template <typename T>
|
||||
static __inline typename traits_t<T>::unsigned_t
|
||||
__kmp_dispatch_guided_remaining(T tc, typename traits_t<T>::floating_t base,
|
||||
typename traits_t<T>::unsigned_t idx) {
|
||||
/* Note: On Windows* OS on IA-32 architecture and Intel(R) 64, at
|
||||
least for ICL 8.1, long double arithmetic may not really have
|
||||
long double precision, even with /Qlong_double. Currently, we
|
||||
workaround that in the caller code, by manipulating the FPCW for
|
||||
Windows* OS on IA-32 architecture. The lack of precision is not
|
||||
expected to be a correctness issue, though.
|
||||
*/
|
||||
typedef typename traits_t<T>::unsigned_t UT;
|
||||
|
||||
long double x = tc * __kmp_pow<UT>(base, idx);
|
||||
UT r = (UT)x;
|
||||
if (x == r)
|
||||
return r;
|
||||
return r + 1;
|
||||
}
|
||||
|
||||
// Parameters of the guided-iterative algorithm:
|
||||
// p2 = n * nproc * ( chunk + 1 ) // point of switching to dynamic
|
||||
// p3 = 1 / ( n * nproc ) // remaining iterations multiplier
|
||||
// by default n = 2. For example with n = 3 the chunks distribution will be more
|
||||
// flat.
|
||||
// With n = 1 first chunk is the same as for static schedule, e.g. trip / nproc.
|
||||
static const int guided_int_param = 2;
|
||||
static const double guided_flt_param = 0.5; // = 1.0 / guided_int_param;
|
||||
#endif // KMP_DISPATCH_H
|
1112
third_party/openmp/kmp_dispatch_hier.h
vendored
Normal file
1112
third_party/openmp/kmp_dispatch_hier.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
500
third_party/openmp/kmp_environment.cpp
vendored
Normal file
500
third_party/openmp/kmp_environment.cpp
vendored
Normal file
|
@ -0,0 +1,500 @@
|
|||
/*
|
||||
* kmp_environment.cpp -- Handle environment variables OS-independently.
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/* We use GetEnvironmentVariable for Windows* OS instead of getenv because the
|
||||
act of loading a DLL on Windows* OS makes any user-set environment variables
|
||||
(i.e. with putenv()) unavailable. getenv() apparently gets a clean copy of
|
||||
the env variables as they existed at the start of the run. JH 12/23/2002
|
||||
|
||||
On Windows* OS, there are two environments (at least, see below):
|
||||
|
||||
1. Environment maintained by Windows* OS on IA-32 architecture. Accessible
|
||||
through GetEnvironmentVariable(), SetEnvironmentVariable(), and
|
||||
GetEnvironmentStrings().
|
||||
|
||||
2. Environment maintained by C RTL. Accessible through getenv(), putenv().
|
||||
|
||||
putenv() function updates both C and Windows* OS on IA-32 architecture.
|
||||
getenv() function search for variables in C RTL environment only.
|
||||
Windows* OS on IA-32 architecture functions work *only* with Windows* OS on
|
||||
IA-32 architecture.
|
||||
|
||||
Windows* OS on IA-32 architecture maintained by OS, so there is always only
|
||||
one Windows* OS on IA-32 architecture per process. Changes in Windows* OS on
|
||||
IA-32 architecture are process-visible.
|
||||
|
||||
C environment maintained by C RTL. Multiple copies of C RTL may be present
|
||||
in the process, and each C RTL maintains its own environment. :-(
|
||||
|
||||
Thus, proper way to work with environment on Windows* OS is:
|
||||
|
||||
1. Set variables with putenv() function -- both C and Windows* OS on IA-32
|
||||
architecture are being updated. Windows* OS on IA-32 architecture may be
|
||||
considered primary target, while updating C RTL environment is free bonus.
|
||||
|
||||
2. Get variables with GetEnvironmentVariable() -- getenv() does not
|
||||
search Windows* OS on IA-32 architecture, and can not see variables
|
||||
set with SetEnvironmentVariable().
|
||||
|
||||
2007-04-05 -- lev
|
||||
*/
|
||||
|
||||
#include "kmp_environment.h"
|
||||
|
||||
#include "kmp.h" //
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_os.h" // KMP_OS_*.
|
||||
#include "kmp_str.h" // __kmp_str_*().
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
#include <stdlib.h> // getenv, setenv, unsetenv.
|
||||
#include <string.h> // strlen, strcpy.
|
||||
#if KMP_OS_DARWIN
|
||||
#include <crt_externs.h>
|
||||
#define environ (*_NSGetEnviron())
|
||||
#else
|
||||
extern char **environ;
|
||||
#endif
|
||||
#elif KMP_OS_WINDOWS
|
||||
#include <windows.h> // GetEnvironmentVariable, SetEnvironmentVariable,
|
||||
// GetLastError.
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
// TODO: Eliminate direct memory allocations, use string operations instead.
|
||||
|
||||
static inline void *allocate(size_t size) {
|
||||
void *ptr = KMP_INTERNAL_MALLOC(size);
|
||||
if (ptr == NULL) {
|
||||
KMP_FATAL(MemoryAllocFailed);
|
||||
}
|
||||
return ptr;
|
||||
} // allocate
|
||||
|
||||
char *__kmp_env_get(char const *name) {
|
||||
|
||||
char *result = NULL;
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
char const *value = getenv(name);
|
||||
if (value != NULL) {
|
||||
size_t len = KMP_STRLEN(value) + 1;
|
||||
result = (char *)KMP_INTERNAL_MALLOC(len);
|
||||
if (result == NULL) {
|
||||
KMP_FATAL(MemoryAllocFailed);
|
||||
}
|
||||
KMP_STRNCPY_S(result, len, value, len);
|
||||
}
|
||||
#elif KMP_OS_WINDOWS
|
||||
/* We use GetEnvironmentVariable for Windows* OS instead of getenv because the
|
||||
act of loading a DLL on Windows* OS makes any user-set environment
|
||||
variables (i.e. with putenv()) unavailable. getenv() apparently gets a
|
||||
clean copy of the env variables as they existed at the start of the run.
|
||||
JH 12/23/2002 */
|
||||
DWORD rc;
|
||||
rc = GetEnvironmentVariable(name, NULL, 0);
|
||||
if (!rc) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_ENVVAR_NOT_FOUND) {
|
||||
__kmp_fatal(KMP_MSG(CantGetEnvVar, name), KMP_ERR(error), __kmp_msg_null);
|
||||
}
|
||||
// Variable is not found, it's ok, just continue.
|
||||
} else {
|
||||
DWORD len = rc;
|
||||
result = (char *)KMP_INTERNAL_MALLOC(len);
|
||||
if (result == NULL) {
|
||||
KMP_FATAL(MemoryAllocFailed);
|
||||
}
|
||||
rc = GetEnvironmentVariable(name, result, len);
|
||||
if (!rc) {
|
||||
// GetEnvironmentVariable() may return 0 if variable is empty.
|
||||
// In such a case GetLastError() returns ERROR_SUCCESS.
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_SUCCESS) {
|
||||
// Unexpected error. The variable should be in the environment,
|
||||
// and buffer should be large enough.
|
||||
__kmp_fatal(KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
KMP_INTERNAL_FREE((void *)result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
return result;
|
||||
|
||||
} // func __kmp_env_get
|
||||
|
||||
// TODO: Find and replace all regular free() with __kmp_env_free().
|
||||
|
||||
void __kmp_env_free(char const **value) {
|
||||
|
||||
KMP_DEBUG_ASSERT(value != NULL);
|
||||
KMP_INTERNAL_FREE(CCAST(char *, *value));
|
||||
*value = NULL;
|
||||
|
||||
} // func __kmp_env_free
|
||||
|
||||
int __kmp_env_exists(char const *name) {
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
char const *value = getenv(name);
|
||||
return ((value == NULL) ? (0) : (1));
|
||||
#elif KMP_OS_WINDOWS
|
||||
DWORD rc;
|
||||
rc = GetEnvironmentVariable(name, NULL, 0);
|
||||
if (rc == 0) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_ENVVAR_NOT_FOUND) {
|
||||
__kmp_fatal(KMP_MSG(CantGetEnvVar, name), KMP_ERR(error), __kmp_msg_null);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
} // func __kmp_env_exists
|
||||
|
||||
void __kmp_env_set(char const *name, char const *value, int overwrite) {
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
int rc = setenv(name, value, overwrite);
|
||||
if (rc != 0) {
|
||||
// Dead code. I tried to put too many variables into Linux* OS
|
||||
// environment on IA-32 architecture. When application consumes
|
||||
// more than ~2.5 GB of memory, entire system feels bad. Sometimes
|
||||
// application is killed (by OS?), sometimes system stops
|
||||
// responding... But this error message never appears. --ln
|
||||
__kmp_fatal(KMP_MSG(CantSetEnvVar, name), KMP_HNT(NotEnoughMemory),
|
||||
__kmp_msg_null);
|
||||
}
|
||||
#elif KMP_OS_WINDOWS
|
||||
BOOL rc;
|
||||
if (!overwrite) {
|
||||
rc = GetEnvironmentVariable(name, NULL, 0);
|
||||
if (rc) {
|
||||
// Variable exists, do not overwrite.
|
||||
return;
|
||||
}
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_ENVVAR_NOT_FOUND) {
|
||||
__kmp_fatal(KMP_MSG(CantGetEnvVar, name), KMP_ERR(error), __kmp_msg_null);
|
||||
}
|
||||
}
|
||||
rc = SetEnvironmentVariable(name, value);
|
||||
if (!rc) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_fatal(KMP_MSG(CantSetEnvVar, name), KMP_ERR(error), __kmp_msg_null);
|
||||
}
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
} // func __kmp_env_set
|
||||
|
||||
void __kmp_env_unset(char const *name) {
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
unsetenv(name);
|
||||
#elif KMP_OS_WINDOWS
|
||||
BOOL rc = SetEnvironmentVariable(name, NULL);
|
||||
if (!rc) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_fatal(KMP_MSG(CantSetEnvVar, name), KMP_ERR(error), __kmp_msg_null);
|
||||
}
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
} // func __kmp_env_unset
|
||||
|
||||
/* Intel OpenMP RTL string representation of environment: just a string of
|
||||
characters, variables are separated with vertical bars, e. g.:
|
||||
|
||||
"KMP_WARNINGS=0|KMP_AFFINITY=compact|"
|
||||
|
||||
Empty variables are allowed and ignored:
|
||||
|
||||
"||KMP_WARNINGS=1||"
|
||||
*/
|
||||
|
||||
static void
|
||||
___kmp_env_blk_parse_string(kmp_env_blk_t *block, // M: Env block to fill.
|
||||
char const *env // I: String to parse.
|
||||
) {
|
||||
|
||||
char const chr_delimiter = '|';
|
||||
char const str_delimiter[] = {chr_delimiter, 0};
|
||||
|
||||
char *bulk = NULL;
|
||||
kmp_env_var_t *vars = NULL;
|
||||
int count = 0; // Number of used elements in vars array.
|
||||
int delimiters = 0; // Number of delimiters in input string.
|
||||
|
||||
// Copy original string, we will modify the copy.
|
||||
bulk = __kmp_str_format("%s", env);
|
||||
|
||||
// Loop thru all the vars in environment block. Count delimiters (maximum
|
||||
// number of variables is number of delimiters plus one).
|
||||
{
|
||||
char const *ptr = bulk;
|
||||
for (;;) {
|
||||
ptr = strchr(ptr, chr_delimiter);
|
||||
if (ptr == NULL) {
|
||||
break;
|
||||
}
|
||||
++delimiters;
|
||||
ptr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate vars array.
|
||||
vars = (kmp_env_var_t *)allocate((delimiters + 1) * sizeof(kmp_env_var_t));
|
||||
|
||||
// Loop thru all the variables.
|
||||
{
|
||||
char *var; // Pointer to variable (both name and value).
|
||||
char *name; // Pointer to name of variable.
|
||||
char *value; // Pointer to value.
|
||||
char *buf; // Buffer for __kmp_str_token() function.
|
||||
var = __kmp_str_token(bulk, str_delimiter, &buf); // Get the first var.
|
||||
while (var != NULL) {
|
||||
// Save found variable in vars array.
|
||||
__kmp_str_split(var, '=', &name, &value);
|
||||
KMP_DEBUG_ASSERT(count < delimiters + 1);
|
||||
vars[count].name = name;
|
||||
vars[count].value = value;
|
||||
++count;
|
||||
// Get the next var.
|
||||
var = __kmp_str_token(NULL, str_delimiter, &buf);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
}
|
||||
|
||||
/* Windows* OS (actually, DOS) environment block is a piece of memory with
|
||||
environment variables. Each variable is terminated with zero byte, entire
|
||||
block is terminated with one extra zero byte, so we have two zero bytes at
|
||||
the end of environment block, e. g.:
|
||||
|
||||
"HOME=C:\\users\\lev\x00OS=Windows_NT\x00\x00"
|
||||
|
||||
It is not clear how empty environment is represented. "\x00\x00"?
|
||||
*/
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
static void ___kmp_env_blk_parse_windows(
|
||||
kmp_env_blk_t *block, // M: Env block to fill.
|
||||
char const *env // I: Pointer to Windows* OS (DOS) environment block.
|
||||
) {
|
||||
|
||||
char *bulk = NULL;
|
||||
kmp_env_var_t *vars = NULL;
|
||||
int count = 0; // Number of used elements in vars array.
|
||||
int size = 0; // Size of bulk.
|
||||
|
||||
char *name; // Pointer to name of variable.
|
||||
char *value; // Pointer to value.
|
||||
|
||||
if (env != NULL) {
|
||||
|
||||
// Loop thru all the vars in environment block. Count variables, find size
|
||||
// of block.
|
||||
{
|
||||
char const *var; // Pointer to beginning of var.
|
||||
int len; // Length of variable.
|
||||
count = 0;
|
||||
var =
|
||||
env; // The first variable starts and beginning of environment block.
|
||||
len = KMP_STRLEN(var);
|
||||
while (len != 0) {
|
||||
++count;
|
||||
size = size + len + 1;
|
||||
var = var + len +
|
||||
1; // Move pointer to the beginning of the next variable.
|
||||
len = KMP_STRLEN(var);
|
||||
}
|
||||
size =
|
||||
size + 1; // Total size of env block, including terminating zero byte.
|
||||
}
|
||||
|
||||
// Copy original block to bulk, we will modify bulk, not original block.
|
||||
bulk = (char *)allocate(size);
|
||||
KMP_MEMCPY_S(bulk, size, env, size);
|
||||
// Allocate vars array.
|
||||
vars = (kmp_env_var_t *)allocate(count * sizeof(kmp_env_var_t));
|
||||
|
||||
// Loop thru all the vars, now in bulk.
|
||||
{
|
||||
char *var; // Pointer to beginning of var.
|
||||
int len; // Length of variable.
|
||||
count = 0;
|
||||
var = bulk;
|
||||
len = KMP_STRLEN(var);
|
||||
while (len != 0) {
|
||||
// Save variable in vars array.
|
||||
__kmp_str_split(var, '=', &name, &value);
|
||||
vars[count].name = name;
|
||||
vars[count].value = value;
|
||||
++count;
|
||||
// Get the next var.
|
||||
var = var + len + 1;
|
||||
len = KMP_STRLEN(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Unix environment block is a array of pointers to variables, last pointer in
|
||||
array is NULL:
|
||||
|
||||
{ "HOME=/home/lev", "TERM=xterm", NULL }
|
||||
*/
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
static void
|
||||
___kmp_env_blk_parse_unix(kmp_env_blk_t *block, // M: Env block to fill.
|
||||
char **env // I: Unix environment to parse.
|
||||
) {
|
||||
char *bulk = NULL;
|
||||
kmp_env_var_t *vars = NULL;
|
||||
int count = 0;
|
||||
size_t size = 0; // Size of bulk.
|
||||
|
||||
// Count number of variables and length of required bulk.
|
||||
{
|
||||
while (env[count] != NULL) {
|
||||
size += KMP_STRLEN(env[count]) + 1;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate memory.
|
||||
bulk = (char *)allocate(size);
|
||||
vars = (kmp_env_var_t *)allocate(count * sizeof(kmp_env_var_t));
|
||||
|
||||
// Loop thru all the vars.
|
||||
{
|
||||
char *var; // Pointer to beginning of var.
|
||||
char *name; // Pointer to name of variable.
|
||||
char *value; // Pointer to value.
|
||||
size_t len; // Length of variable.
|
||||
int i;
|
||||
var = bulk;
|
||||
for (i = 0; i < count; ++i) {
|
||||
KMP_ASSERT(var < bulk + size);
|
||||
[[maybe_unused]] size_t ssize = size - (var - bulk);
|
||||
// Copy variable to bulk.
|
||||
len = KMP_STRLEN(env[i]);
|
||||
KMP_MEMCPY_S(var, ssize, env[i], len + 1);
|
||||
// Save found variable in vars array.
|
||||
__kmp_str_split(var, '=', &name, &value);
|
||||
vars[i].name = name;
|
||||
vars[i].value = value;
|
||||
// Move pointer.
|
||||
var += len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
}
|
||||
#endif
|
||||
|
||||
void __kmp_env_blk_init(kmp_env_blk_t *block, // M: Block to initialize.
|
||||
char const *bulk // I: Initialization string, or NULL.
|
||||
) {
|
||||
|
||||
if (bulk != NULL) {
|
||||
___kmp_env_blk_parse_string(block, bulk);
|
||||
} else {
|
||||
#if KMP_OS_UNIX
|
||||
___kmp_env_blk_parse_unix(block, environ);
|
||||
#elif KMP_OS_WINDOWS
|
||||
{
|
||||
char *mem = GetEnvironmentStrings();
|
||||
if (mem == NULL) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_fatal(KMP_MSG(CantGetEnvironment), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
}
|
||||
___kmp_env_blk_parse_windows(block, mem);
|
||||
FreeEnvironmentStrings(mem);
|
||||
}
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
}
|
||||
|
||||
} // __kmp_env_blk_init
|
||||
|
||||
static int ___kmp_env_var_cmp( // Comparison function for qsort().
|
||||
kmp_env_var_t const *lhs, kmp_env_var_t const *rhs) {
|
||||
return strcmp(lhs->name, rhs->name);
|
||||
}
|
||||
|
||||
void __kmp_env_blk_sort(
|
||||
kmp_env_blk_t *block // M: Block of environment variables to sort.
|
||||
) {
|
||||
|
||||
qsort(CCAST(kmp_env_var_t *, block->vars), block->count,
|
||||
sizeof(kmp_env_var_t),
|
||||
(int (*)(void const *, void const *)) & ___kmp_env_var_cmp);
|
||||
|
||||
} // __kmp_env_block_sort
|
||||
|
||||
void __kmp_env_blk_free(
|
||||
kmp_env_blk_t *block // M: Block of environment variables to free.
|
||||
) {
|
||||
|
||||
KMP_INTERNAL_FREE(CCAST(kmp_env_var_t *, block->vars));
|
||||
__kmp_str_free(&(block->bulk));
|
||||
|
||||
block->count = 0;
|
||||
block->vars = NULL;
|
||||
|
||||
} // __kmp_env_blk_free
|
||||
|
||||
char const * // R: Value of variable or NULL if variable does not exist.
|
||||
__kmp_env_blk_var(kmp_env_blk_t *block, // I: Block of environment variables.
|
||||
char const *name // I: Name of variable to find.
|
||||
) {
|
||||
|
||||
int i;
|
||||
for (i = 0; i < block->count; ++i) {
|
||||
if (strcmp(block->vars[i].name, name) == 0) {
|
||||
return block->vars[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
} // __kmp_env_block_var
|
||||
|
||||
// end of file //
|
77
third_party/openmp/kmp_environment.h
vendored
Normal file
77
third_party/openmp/kmp_environment.h
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* kmp_environment.h -- Handle environment variables OS-independently.
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ENVIRONMENT_H
|
||||
#define KMP_ENVIRONMENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Return a copy of the value of environment variable or NULL if the variable
|
||||
// does not exist.
|
||||
// *Note*: Returned pointed *must* be freed after use with __kmp_env_free().
|
||||
char *__kmp_env_get(char const *name);
|
||||
void __kmp_env_free(char const **value);
|
||||
|
||||
// Return 1 if the environment variable exists or 0 if does not exist.
|
||||
int __kmp_env_exists(char const *name);
|
||||
|
||||
// Set the environment variable.
|
||||
void __kmp_env_set(char const *name, char const *value, int overwrite);
|
||||
|
||||
// Unset (remove) environment variable.
|
||||
void __kmp_env_unset(char const *name);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Working with environment blocks.
|
||||
|
||||
/* kmp_env_blk_t is read-only collection of environment variables (or
|
||||
environment-like). Usage:
|
||||
|
||||
kmp_env_blk_t block;
|
||||
__kmp_env_blk_init( & block, NULL ); // Initialize block from process
|
||||
// environment.
|
||||
// or
|
||||
__kmp_env_blk_init( & block, "KMP_WARNING=1|KMP_AFFINITY=none" ); // from string
|
||||
__kmp_env_blk_sort( & block ); // Optionally, sort list.
|
||||
for ( i = 0; i < block.count; ++ i ) {
|
||||
// Process block.vars[ i ].name and block.vars[ i ].value...
|
||||
}
|
||||
__kmp_env_block_free( & block );
|
||||
*/
|
||||
|
||||
struct __kmp_env_var {
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
typedef struct __kmp_env_var kmp_env_var_t;
|
||||
|
||||
struct __kmp_env_blk {
|
||||
char *bulk;
|
||||
kmp_env_var_t *vars;
|
||||
int count;
|
||||
};
|
||||
typedef struct __kmp_env_blk kmp_env_blk_t;
|
||||
|
||||
void __kmp_env_blk_init(kmp_env_blk_t *block, char const *bulk);
|
||||
void __kmp_env_blk_free(kmp_env_blk_t *block);
|
||||
void __kmp_env_blk_sort(kmp_env_blk_t *block);
|
||||
char const *__kmp_env_blk_var(kmp_env_blk_t *block, char const *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // KMP_ENVIRONMENT_H
|
||||
|
||||
// end of file //
|
451
third_party/openmp/kmp_error.cpp
vendored
Normal file
451
third_party/openmp/kmp_error.cpp
vendored
Normal file
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* kmp_error.cpp -- KPTS functions for error checking at runtime
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_error.h"
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_str.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#define MIN_STACK 100
|
||||
|
||||
static char const *cons_text_c[] = {
|
||||
"(none)",
|
||||
"\"parallel\"",
|
||||
"work-sharing", /* this is not called "for"
|
||||
because of lowering of
|
||||
"sections" pragmas */
|
||||
"\"ordered\" work-sharing", /* this is not called "for ordered" because of
|
||||
lowering of "sections" pragmas */
|
||||
"\"sections\"",
|
||||
"work-sharing", /* this is not called "single" because of lowering of
|
||||
"sections" pragmas */
|
||||
"\"critical\"",
|
||||
"\"ordered\"", /* in PARALLEL */
|
||||
"\"ordered\"", /* in PDO */
|
||||
"\"master\"",
|
||||
"\"reduce\"",
|
||||
"\"barrier\"",
|
||||
"\"masked\""};
|
||||
|
||||
#define get_src(ident) ((ident) == NULL ? NULL : (ident)->psource)
|
||||
|
||||
#define PUSH_MSG(ct, ident) \
|
||||
"\tpushing on stack: %s (%s)\n", cons_text_c[(ct)], get_src((ident))
|
||||
#define POP_MSG(p) \
|
||||
"\tpopping off stack: %s (%s)\n", cons_text_c[(p)->stack_data[tos].type], \
|
||||
get_src((p)->stack_data[tos].ident)
|
||||
|
||||
static int const cons_text_c_num = sizeof(cons_text_c) / sizeof(char const *);
|
||||
|
||||
/* --------------- START OF STATIC LOCAL ROUTINES ------------------------- */
|
||||
|
||||
static void __kmp_check_null_func(void) { /* nothing to do */
|
||||
}
|
||||
|
||||
static void __kmp_expand_cons_stack(int gtid, struct cons_header *p) {
|
||||
int i;
|
||||
struct cons_data *d;
|
||||
|
||||
/* TODO for monitor perhaps? */
|
||||
if (gtid < 0)
|
||||
__kmp_check_null_func();
|
||||
|
||||
KE_TRACE(10, ("expand cons_stack (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
|
||||
d = p->stack_data;
|
||||
|
||||
p->stack_size = (p->stack_size * 2) + 100;
|
||||
|
||||
/* TODO free the old data */
|
||||
p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) *
|
||||
(p->stack_size + 1));
|
||||
|
||||
for (i = p->stack_top; i >= 0; --i)
|
||||
p->stack_data[i] = d[i];
|
||||
|
||||
/* NOTE: we do not free the old stack_data */
|
||||
}
|
||||
|
||||
// NOTE: Function returns allocated memory, caller must free it!
|
||||
static char *__kmp_pragma(int ct, ident_t const *ident) {
|
||||
char const *cons = NULL; // Construct name.
|
||||
char *file = NULL; // File name.
|
||||
char *func = NULL; // Function (routine) name.
|
||||
char *line = NULL; // Line number.
|
||||
kmp_str_buf_t buffer;
|
||||
kmp_msg_t prgm;
|
||||
__kmp_str_buf_init(&buffer);
|
||||
if (0 < ct && ct < cons_text_c_num) {
|
||||
cons = cons_text_c[ct];
|
||||
} else {
|
||||
KMP_DEBUG_ASSERT(0);
|
||||
}
|
||||
if (ident != NULL && ident->psource != NULL) {
|
||||
char *tail = NULL;
|
||||
__kmp_str_buf_print(&buffer, "%s",
|
||||
ident->psource); // Copy source to buffer.
|
||||
// Split string in buffer to file, func, and line.
|
||||
tail = buffer.str;
|
||||
__kmp_str_split(tail, ';', NULL, &tail);
|
||||
__kmp_str_split(tail, ';', &file, &tail);
|
||||
__kmp_str_split(tail, ';', &func, &tail);
|
||||
__kmp_str_split(tail, ';', &line, &tail);
|
||||
}
|
||||
prgm = __kmp_msg_format(kmp_i18n_fmt_Pragma, cons, file, func, line);
|
||||
__kmp_str_buf_free(&buffer);
|
||||
return prgm.str;
|
||||
} // __kmp_pragma
|
||||
|
||||
/* ----------------- END OF STATIC LOCAL ROUTINES ------------------------- */
|
||||
|
||||
void __kmp_error_construct(kmp_i18n_id_t id, // Message identifier.
|
||||
enum cons_type ct, // Construct type.
|
||||
ident_t const *ident // Construct ident.
|
||||
) {
|
||||
char *construct = __kmp_pragma(ct, ident);
|
||||
__kmp_fatal(__kmp_msg_format(id, construct), __kmp_msg_null);
|
||||
KMP_INTERNAL_FREE(construct);
|
||||
}
|
||||
|
||||
void __kmp_error_construct2(kmp_i18n_id_t id, // Message identifier.
|
||||
enum cons_type ct, // First construct type.
|
||||
ident_t const *ident, // First construct ident.
|
||||
struct cons_data const *cons // Second construct.
|
||||
) {
|
||||
char *construct1 = __kmp_pragma(ct, ident);
|
||||
char *construct2 = __kmp_pragma(cons->type, cons->ident);
|
||||
__kmp_fatal(__kmp_msg_format(id, construct1, construct2), __kmp_msg_null);
|
||||
KMP_INTERNAL_FREE(construct1);
|
||||
KMP_INTERNAL_FREE(construct2);
|
||||
}
|
||||
|
||||
struct cons_header *__kmp_allocate_cons_stack(int gtid) {
|
||||
struct cons_header *p;
|
||||
|
||||
/* TODO for monitor perhaps? */
|
||||
if (gtid < 0) {
|
||||
__kmp_check_null_func();
|
||||
}
|
||||
KE_TRACE(10, ("allocate cons_stack (%d)\n", gtid));
|
||||
p = (struct cons_header *)__kmp_allocate(sizeof(struct cons_header));
|
||||
p->p_top = p->w_top = p->s_top = 0;
|
||||
p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) *
|
||||
(MIN_STACK + 1));
|
||||
p->stack_size = MIN_STACK;
|
||||
p->stack_top = 0;
|
||||
p->stack_data[0].type = ct_none;
|
||||
p->stack_data[0].prev = 0;
|
||||
p->stack_data[0].ident = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
void __kmp_free_cons_stack(void *ptr) {
|
||||
struct cons_header *p = (struct cons_header *)ptr;
|
||||
if (p != NULL) {
|
||||
if (p->stack_data != NULL) {
|
||||
__kmp_free(p->stack_data);
|
||||
p->stack_data = NULL;
|
||||
}
|
||||
__kmp_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
#if KMP_DEBUG
|
||||
static void dump_cons_stack(int gtid, struct cons_header *p) {
|
||||
int i;
|
||||
int tos = p->stack_top;
|
||||
kmp_str_buf_t buffer;
|
||||
__kmp_str_buf_init(&buffer);
|
||||
__kmp_str_buf_print(
|
||||
&buffer,
|
||||
"+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
|
||||
__kmp_str_buf_print(&buffer,
|
||||
"Begin construct stack with %d items for thread %d\n",
|
||||
tos, gtid);
|
||||
__kmp_str_buf_print(&buffer, " stack_top=%d { P=%d, W=%d, S=%d }\n", tos,
|
||||
p->p_top, p->w_top, p->s_top);
|
||||
for (i = tos; i > 0; i--) {
|
||||
struct cons_data *c = &(p->stack_data[i]);
|
||||
__kmp_str_buf_print(
|
||||
&buffer, " stack_data[%2d] = { %s (%s) %d %p }\n", i,
|
||||
cons_text_c[c->type], get_src(c->ident), c->prev, c->name);
|
||||
}
|
||||
__kmp_str_buf_print(&buffer, "End construct stack for thread %d\n", gtid);
|
||||
__kmp_str_buf_print(
|
||||
&buffer,
|
||||
"+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
|
||||
__kmp_debug_printf("%s", buffer.str);
|
||||
__kmp_str_buf_free(&buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __kmp_push_parallel(int gtid, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons);
|
||||
KE_TRACE(10, ("__kmp_push_parallel (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
KE_TRACE(100, (PUSH_MSG(ct_parallel, ident)));
|
||||
if (p->stack_top >= p->stack_size) {
|
||||
__kmp_expand_cons_stack(gtid, p);
|
||||
}
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[tos].type = ct_parallel;
|
||||
p->stack_data[tos].prev = p->p_top;
|
||||
p->stack_data[tos].ident = ident;
|
||||
p->stack_data[tos].name = NULL;
|
||||
p->p_top = tos;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
void __kmp_check_workshare(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons);
|
||||
KE_TRACE(10, ("__kmp_check_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
|
||||
if (p->stack_top >= p->stack_size) {
|
||||
__kmp_expand_cons_stack(gtid, p);
|
||||
}
|
||||
if (p->w_top > p->p_top) {
|
||||
// We are already in a WORKSHARE construct for this PARALLEL region.
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
if (p->s_top > p->p_top) {
|
||||
// We are already in a SYNC construct for this PARALLEL region.
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->s_top]);
|
||||
}
|
||||
}
|
||||
|
||||
void __kmp_push_workshare(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
KE_TRACE(10, ("__kmp_push_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
__kmp_check_workshare(gtid, ct, ident);
|
||||
KE_TRACE(100, (PUSH_MSG(ct, ident)));
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[tos].type = ct;
|
||||
p->stack_data[tos].prev = p->w_top;
|
||||
p->stack_data[tos].ident = ident;
|
||||
p->stack_data[tos].name = NULL;
|
||||
p->w_top = tos;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
void
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
__kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq )
|
||||
#else
|
||||
__kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
|
||||
#endif
|
||||
{
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KE_TRACE(10, ("__kmp_check_sync (gtid=%d)\n", __kmp_get_gtid()));
|
||||
|
||||
if (p->stack_top >= p->stack_size)
|
||||
__kmp_expand_cons_stack(gtid, p);
|
||||
|
||||
if (ct == ct_ordered_in_parallel || ct == ct_ordered_in_pdo) {
|
||||
if (p->w_top <= p->p_top) {
|
||||
/* we are not in a worksharing construct */
|
||||
#ifdef BUILD_PARALLEL_ORDERED
|
||||
/* do not report error messages for PARALLEL ORDERED */
|
||||
KMP_ASSERT(ct == ct_ordered_in_parallel);
|
||||
#else
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsBoundToWorksharing, ct, ident);
|
||||
#endif /* BUILD_PARALLEL_ORDERED */
|
||||
} else {
|
||||
/* inside a WORKSHARING construct for this PARALLEL region */
|
||||
if (!IS_CONS_TYPE_ORDERED(p->stack_data[p->w_top].type)) {
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsNoOrderedClause, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
}
|
||||
if (p->s_top > p->p_top && p->s_top > p->w_top) {
|
||||
/* inside a sync construct which is inside a worksharing construct */
|
||||
int index = p->s_top;
|
||||
enum cons_type stack_type;
|
||||
|
||||
stack_type = p->stack_data[index].type;
|
||||
|
||||
if (stack_type == ct_critical ||
|
||||
((stack_type == ct_ordered_in_parallel ||
|
||||
stack_type == ct_ordered_in_pdo) &&
|
||||
/* C doesn't allow named ordered; ordered in ordered gets error */
|
||||
p->stack_data[index].ident != NULL &&
|
||||
(p->stack_data[index].ident->flags & KMP_IDENT_KMPC))) {
|
||||
/* we are in ORDERED which is inside an ORDERED or CRITICAL construct */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[index]);
|
||||
}
|
||||
}
|
||||
} else if (ct == ct_critical) {
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
if (lck != NULL &&
|
||||
__kmp_get_user_lock_owner(lck, seq) ==
|
||||
gtid) { /* this thread already has lock for this critical section */
|
||||
#else
|
||||
if (lck != NULL &&
|
||||
__kmp_get_user_lock_owner(lck) ==
|
||||
gtid) { /* this thread already has lock for this critical section */
|
||||
#endif
|
||||
int index = p->s_top;
|
||||
struct cons_data cons = {NULL, ct_critical, 0, NULL};
|
||||
/* walk up construct stack and try to find critical with matching name */
|
||||
while (index != 0 && p->stack_data[index].name != lck) {
|
||||
index = p->stack_data[index].prev;
|
||||
}
|
||||
if (index != 0) {
|
||||
/* found match on the stack (may not always because of interleaved
|
||||
* critical for Fortran) */
|
||||
cons = p->stack_data[index];
|
||||
}
|
||||
/* we are in CRITICAL which is inside a CRITICAL construct of same name */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsNestingSameName, ct, ident, &cons);
|
||||
}
|
||||
} else if (ct == ct_master || ct == ct_masked || ct == ct_reduce) {
|
||||
if (p->w_top > p->p_top) {
|
||||
/* inside a WORKSHARING construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
if (ct == ct_reduce && p->s_top > p->p_top) {
|
||||
/* inside a another SYNC construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->s_top]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
__kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck, kmp_uint32 seq )
|
||||
#else
|
||||
__kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
|
||||
#endif
|
||||
{
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KMP_ASSERT(gtid == __kmp_get_gtid());
|
||||
KE_TRACE(10, ("__kmp_push_sync (gtid=%d)\n", gtid));
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
__kmp_check_sync(gtid, ct, ident, lck, seq);
|
||||
#else
|
||||
__kmp_check_sync(gtid, ct, ident, lck);
|
||||
#endif
|
||||
KE_TRACE(100, (PUSH_MSG(ct, ident)));
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[tos].type = ct;
|
||||
p->stack_data[tos].prev = p->s_top;
|
||||
p->stack_data[tos].ident = ident;
|
||||
p->stack_data[tos].name = lck;
|
||||
p->s_top = tos;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void __kmp_pop_parallel(int gtid, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
tos = p->stack_top;
|
||||
KE_TRACE(10, ("__kmp_pop_parallel (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
if (tos == 0 || p->p_top == 0) {
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct_parallel, ident);
|
||||
}
|
||||
if (tos != p->p_top || p->stack_data[tos].type != ct_parallel) {
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct_parallel, ident,
|
||||
&p->stack_data[tos]);
|
||||
}
|
||||
KE_TRACE(100, (POP_MSG(p)));
|
||||
p->p_top = p->stack_data[tos].prev;
|
||||
p->stack_data[tos].type = ct_none;
|
||||
p->stack_data[tos].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
enum cons_type __kmp_pop_workshare(int gtid, enum cons_type ct,
|
||||
ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
tos = p->stack_top;
|
||||
KE_TRACE(10, ("__kmp_pop_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
if (tos == 0 || p->w_top == 0) {
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident);
|
||||
}
|
||||
|
||||
if (tos != p->w_top ||
|
||||
(p->stack_data[tos].type != ct &&
|
||||
// below is the exception to the rule that construct types must match
|
||||
!(p->stack_data[tos].type == ct_pdo_ordered && ct == ct_pdo))) {
|
||||
__kmp_check_null_func();
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident,
|
||||
&p->stack_data[tos]);
|
||||
}
|
||||
KE_TRACE(100, (POP_MSG(p)));
|
||||
p->w_top = p->stack_data[tos].prev;
|
||||
p->stack_data[tos].type = ct_none;
|
||||
p->stack_data[tos].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
return p->stack_data[p->w_top].type;
|
||||
}
|
||||
|
||||
void __kmp_pop_sync(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
tos = p->stack_top;
|
||||
KE_TRACE(10, ("__kmp_pop_sync (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
if (tos == 0 || p->s_top == 0) {
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident);
|
||||
}
|
||||
if (tos != p->s_top || p->stack_data[tos].type != ct) {
|
||||
__kmp_check_null_func();
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident,
|
||||
&p->stack_data[tos]);
|
||||
}
|
||||
KE_TRACE(100, (POP_MSG(p)));
|
||||
p->s_top = p->stack_data[tos].prev;
|
||||
p->stack_data[tos].type = ct_none;
|
||||
p->stack_data[tos].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void __kmp_check_barrier(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
KE_TRACE(10, ("__kmp_check_barrier (loc: %p, gtid: %d %d)\n", ident, gtid,
|
||||
__kmp_get_gtid()));
|
||||
if (ident != 0) {
|
||||
__kmp_check_null_func();
|
||||
}
|
||||
if (p->w_top > p->p_top) {
|
||||
/* we are already in a WORKSHARING construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
if (p->s_top > p->p_top) {
|
||||
/* we are already in a SYNC construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->s_top]);
|
||||
}
|
||||
}
|
60
third_party/openmp/kmp_error.h
vendored
Normal file
60
third_party/openmp/kmp_error.h
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* kmp_error.h -- PTS functions for error checking at runtime.
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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_ERROR_H
|
||||
#define KMP_ERROR_H
|
||||
|
||||
#include "kmp_i18n.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void __kmp_error_construct(kmp_i18n_id_t id, enum cons_type ct,
|
||||
ident_t const *ident);
|
||||
void __kmp_error_construct2(kmp_i18n_id_t id, enum cons_type ct,
|
||||
ident_t const *ident, struct cons_data const *cons);
|
||||
|
||||
struct cons_header *__kmp_allocate_cons_stack(int gtid);
|
||||
void __kmp_free_cons_stack(void *ptr);
|
||||
|
||||
void __kmp_push_parallel(int gtid, ident_t const *ident);
|
||||
void __kmp_push_workshare(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
void __kmp_push_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name, kmp_uint32);
|
||||
#else
|
||||
void __kmp_push_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name);
|
||||
#endif
|
||||
|
||||
void __kmp_check_workshare(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
void __kmp_check_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name, kmp_uint32);
|
||||
#else
|
||||
void __kmp_check_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name);
|
||||
#endif
|
||||
|
||||
void __kmp_pop_parallel(int gtid, ident_t const *ident);
|
||||
enum cons_type __kmp_pop_workshare(int gtid, enum cons_type ct,
|
||||
ident_t const *ident);
|
||||
void __kmp_pop_sync(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
void __kmp_check_barrier(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // KMP_ERROR_H
|
34
third_party/openmp/kmp_ftn_cdecl.cpp
vendored
Normal file
34
third_party/openmp/kmp_ftn_cdecl.cpp
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* kmp_ftn_cdecl.cpp -- Fortran __cdecl linkage support for OpenMP.
|
||||
*/
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_affinity.h"
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
#if defined KMP_WIN_CDECL || !KMP_DYNAMIC_LIB
|
||||
#define KMP_FTN_ENTRIES KMP_FTN_UPPER
|
||||
#endif
|
||||
#elif KMP_OS_UNIX
|
||||
#define KMP_FTN_ENTRIES KMP_FTN_PLAIN
|
||||
#endif
|
||||
|
||||
// Note: This string is not printed when KMP_VERSION=1.
|
||||
char const __kmp_version_ftncdecl[] =
|
||||
KMP_VERSION_PREFIX "Fortran __cdecl OMP support: "
|
||||
#ifdef KMP_FTN_ENTRIES
|
||||
"yes";
|
||||
#define FTN_STDCALL /* no stdcall */
|
||||
#include "kmp_ftn_os.h"
|
||||
#include "kmp_ftn_entry.h"
|
||||
#else
|
||||
"no";
|
||||
#endif /* KMP_FTN_ENTRIES */
|
1783
third_party/openmp/kmp_ftn_entry.h
vendored
Normal file
1783
third_party/openmp/kmp_ftn_entry.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
755
third_party/openmp/kmp_ftn_os.h
vendored
Normal file
755
third_party/openmp/kmp_ftn_os.h
vendored
Normal file
|
@ -0,0 +1,755 @@
|
|||
/*
|
||||
* kmp_ftn_os.h -- KPTS Fortran defines 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_FTN_OS_H
|
||||
#define KMP_FTN_OS_H
|
||||
|
||||
// KMP_FNT_ENTRIES may be one of: KMP_FTN_PLAIN, KMP_FTN_UPPER, KMP_FTN_APPEND,
|
||||
// KMP_FTN_UAPPEND.
|
||||
|
||||
/* -------------------------- External definitions ------------------------ */
|
||||
|
||||
#if KMP_FTN_ENTRIES == KMP_FTN_PLAIN
|
||||
|
||||
#define FTN_SET_STACKSIZE kmp_set_stacksize
|
||||
#define FTN_SET_STACKSIZE_S kmp_set_stacksize_s
|
||||
#define FTN_GET_STACKSIZE kmp_get_stacksize
|
||||
#define FTN_GET_STACKSIZE_S kmp_get_stacksize_s
|
||||
#define FTN_SET_BLOCKTIME kmp_set_blocktime
|
||||
#define FTN_GET_BLOCKTIME kmp_get_blocktime
|
||||
#define FTN_SET_LIBRARY_SERIAL kmp_set_library_serial
|
||||
#define FTN_SET_LIBRARY_TURNAROUND kmp_set_library_turnaround
|
||||
#define FTN_SET_LIBRARY_THROUGHPUT kmp_set_library_throughput
|
||||
#define FTN_SET_LIBRARY kmp_set_library
|
||||
#define FTN_GET_LIBRARY kmp_get_library
|
||||
#define FTN_SET_DEFAULTS kmp_set_defaults
|
||||
#define FTN_SET_DISP_NUM_BUFFERS kmp_set_disp_num_buffers
|
||||
#define FTN_SET_AFFINITY kmp_set_affinity
|
||||
#define FTN_GET_AFFINITY kmp_get_affinity
|
||||
#define FTN_GET_AFFINITY_MAX_PROC kmp_get_affinity_max_proc
|
||||
#define FTN_CREATE_AFFINITY_MASK kmp_create_affinity_mask
|
||||
#define FTN_DESTROY_AFFINITY_MASK kmp_destroy_affinity_mask
|
||||
#define FTN_SET_AFFINITY_MASK_PROC kmp_set_affinity_mask_proc
|
||||
#define FTN_UNSET_AFFINITY_MASK_PROC kmp_unset_affinity_mask_proc
|
||||
#define FTN_GET_AFFINITY_MASK_PROC kmp_get_affinity_mask_proc
|
||||
|
||||
#define FTN_MALLOC kmp_malloc
|
||||
#define FTN_ALIGNED_MALLOC kmp_aligned_malloc
|
||||
#define FTN_CALLOC kmp_calloc
|
||||
#define FTN_REALLOC kmp_realloc
|
||||
#define FTN_KFREE kmp_free
|
||||
|
||||
#define FTN_GET_NUM_KNOWN_THREADS kmp_get_num_known_threads
|
||||
|
||||
#define FTN_SET_NUM_THREADS omp_set_num_threads
|
||||
#define FTN_GET_NUM_THREADS omp_get_num_threads
|
||||
#define FTN_GET_MAX_THREADS omp_get_max_threads
|
||||
#define FTN_GET_THREAD_NUM omp_get_thread_num
|
||||
#define FTN_GET_NUM_PROCS omp_get_num_procs
|
||||
#define FTN_SET_DYNAMIC omp_set_dynamic
|
||||
#define FTN_GET_DYNAMIC omp_get_dynamic
|
||||
#define FTN_SET_NESTED omp_set_nested
|
||||
#define FTN_GET_NESTED omp_get_nested
|
||||
#define FTN_IN_PARALLEL omp_in_parallel
|
||||
#define FTN_GET_THREAD_LIMIT omp_get_thread_limit
|
||||
#define FTN_SET_SCHEDULE omp_set_schedule
|
||||
#define FTN_GET_SCHEDULE omp_get_schedule
|
||||
#define FTN_SET_MAX_ACTIVE_LEVELS omp_set_max_active_levels
|
||||
#define FTN_GET_MAX_ACTIVE_LEVELS omp_get_max_active_levels
|
||||
#define FTN_GET_ACTIVE_LEVEL omp_get_active_level
|
||||
#define FTN_GET_LEVEL omp_get_level
|
||||
#define FTN_GET_ANCESTOR_THREAD_NUM omp_get_ancestor_thread_num
|
||||
#define FTN_GET_TEAM_SIZE omp_get_team_size
|
||||
#define FTN_IN_FINAL omp_in_final
|
||||
#define FTN_GET_PROC_BIND omp_get_proc_bind
|
||||
#define FTN_GET_NUM_TEAMS omp_get_num_teams
|
||||
#define FTN_GET_TEAM_NUM omp_get_team_num
|
||||
#define FTN_INIT_LOCK omp_init_lock
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
#define FTN_INIT_LOCK_WITH_HINT omp_init_lock_with_hint
|
||||
#define FTN_INIT_NEST_LOCK_WITH_HINT omp_init_nest_lock_with_hint
|
||||
#endif
|
||||
#define FTN_DESTROY_LOCK omp_destroy_lock
|
||||
#define FTN_SET_LOCK omp_set_lock
|
||||
#define FTN_UNSET_LOCK omp_unset_lock
|
||||
#define FTN_TEST_LOCK omp_test_lock
|
||||
#define FTN_INIT_NEST_LOCK omp_init_nest_lock
|
||||
#define FTN_DESTROY_NEST_LOCK omp_destroy_nest_lock
|
||||
#define FTN_SET_NEST_LOCK omp_set_nest_lock
|
||||
#define FTN_UNSET_NEST_LOCK omp_unset_nest_lock
|
||||
#define FTN_TEST_NEST_LOCK omp_test_nest_lock
|
||||
|
||||
#define FTN_SET_WARNINGS_ON kmp_set_warnings_on
|
||||
#define FTN_SET_WARNINGS_OFF kmp_set_warnings_off
|
||||
|
||||
#define FTN_GET_WTIME omp_get_wtime
|
||||
#define FTN_GET_WTICK omp_get_wtick
|
||||
|
||||
#define FTN_GET_NUM_DEVICES omp_get_num_devices
|
||||
#define FTN_GET_DEFAULT_DEVICE omp_get_default_device
|
||||
#define FTN_SET_DEFAULT_DEVICE omp_set_default_device
|
||||
#define FTN_IS_INITIAL_DEVICE omp_is_initial_device
|
||||
|
||||
#define FTN_GET_CANCELLATION omp_get_cancellation
|
||||
#define FTN_GET_CANCELLATION_STATUS kmp_get_cancellation_status
|
||||
|
||||
#define FTN_GET_MAX_TASK_PRIORITY omp_get_max_task_priority
|
||||
#define FTN_GET_NUM_PLACES omp_get_num_places
|
||||
#define FTN_GET_PLACE_NUM_PROCS omp_get_place_num_procs
|
||||
#define FTN_GET_PLACE_PROC_IDS omp_get_place_proc_ids
|
||||
#define FTN_GET_PLACE_NUM omp_get_place_num
|
||||
#define FTN_GET_PARTITION_NUM_PLACES omp_get_partition_num_places
|
||||
#define FTN_GET_PARTITION_PLACE_NUMS omp_get_partition_place_nums
|
||||
#define FTN_GET_INITIAL_DEVICE omp_get_initial_device
|
||||
#ifdef KMP_STUB
|
||||
#define FTN_TARGET_ALLOC omp_target_alloc
|
||||
#define FTN_TARGET_FREE omp_target_free
|
||||
#define FTN_TARGET_IS_PRESENT omp_target_is_present
|
||||
#define FTN_TARGET_MEMCPY omp_target_memcpy
|
||||
#define FTN_TARGET_MEMCPY_RECT omp_target_memcpy_rect
|
||||
#define FTN_TARGET_MEMSET omp_target_memset
|
||||
#define FTN_TARGET_MEMSET_ASYNC omp_target_memset_async
|
||||
#define FTN_TARGET_ASSOCIATE_PTR omp_target_associate_ptr
|
||||
#define FTN_TARGET_DISASSOCIATE_PTR omp_target_disassociate_ptr
|
||||
#endif
|
||||
|
||||
#define FTN_CONTROL_TOOL omp_control_tool
|
||||
#define FTN_INIT_ALLOCATOR omp_init_allocator
|
||||
#define FTN_DESTROY_ALLOCATOR omp_destroy_allocator
|
||||
#define FTN_SET_DEFAULT_ALLOCATOR omp_set_default_allocator
|
||||
#define FTN_GET_DEFAULT_ALLOCATOR omp_get_default_allocator
|
||||
#define FTN_GET_DEVICE_NUM omp_get_device_num
|
||||
#define FTN_SET_AFFINITY_FORMAT omp_set_affinity_format
|
||||
#define FTN_GET_AFFINITY_FORMAT omp_get_affinity_format
|
||||
#define FTN_DISPLAY_AFFINITY omp_display_affinity
|
||||
#define FTN_CAPTURE_AFFINITY omp_capture_affinity
|
||||
#define FTN_PAUSE_RESOURCE omp_pause_resource
|
||||
#define FTN_PAUSE_RESOURCE_ALL omp_pause_resource_all
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS omp_get_supported_active_levels
|
||||
#define FTN_DISPLAY_ENV omp_display_env
|
||||
#define FTN_IN_EXPLICIT_TASK omp_in_explicit_task
|
||||
#define FTN_FULFILL_EVENT omp_fulfill_event
|
||||
#define FTN_SET_NUM_TEAMS omp_set_num_teams
|
||||
#define FTN_GET_MAX_TEAMS omp_get_max_teams
|
||||
#define FTN_SET_TEAMS_THREAD_LIMIT omp_set_teams_thread_limit
|
||||
#define FTN_GET_TEAMS_THREAD_LIMIT omp_get_teams_thread_limit
|
||||
|
||||
#define FTN_GET_NUM_INTEROP_PROPERTIES omp_get_num_interop_properties
|
||||
#define FTN_GET_INTEROP_INT omp_get_interop_int
|
||||
#define FTN_GET_INTEROP_PTR omp_get_interop_ptr
|
||||
#define FTN_GET_INTEROP_STR omp_get_interop_str
|
||||
#define FTN_GET_INTEROP_NAME omp_get_interop_name
|
||||
#define FTN_GET_INTEROP_TYPE_DESC omp_get_interop_type_desc
|
||||
#define FTN_GET_INTEROP_RC_DESC omp_get_interop_rc_desc
|
||||
|
||||
#endif /* KMP_FTN_PLAIN */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if KMP_FTN_ENTRIES == KMP_FTN_APPEND
|
||||
|
||||
#define FTN_SET_STACKSIZE kmp_set_stacksize_
|
||||
#define FTN_SET_STACKSIZE_S kmp_set_stacksize_s_
|
||||
#define FTN_GET_STACKSIZE kmp_get_stacksize_
|
||||
#define FTN_GET_STACKSIZE_S kmp_get_stacksize_s_
|
||||
#define FTN_SET_BLOCKTIME kmp_set_blocktime_
|
||||
#define FTN_GET_BLOCKTIME kmp_get_blocktime_
|
||||
#define FTN_SET_LIBRARY_SERIAL kmp_set_library_serial_
|
||||
#define FTN_SET_LIBRARY_TURNAROUND kmp_set_library_turnaround_
|
||||
#define FTN_SET_LIBRARY_THROUGHPUT kmp_set_library_throughput_
|
||||
#define FTN_SET_LIBRARY kmp_set_library_
|
||||
#define FTN_GET_LIBRARY kmp_get_library_
|
||||
#define FTN_SET_DEFAULTS kmp_set_defaults_
|
||||
#define FTN_SET_DISP_NUM_BUFFERS kmp_set_disp_num_buffers_
|
||||
#define FTN_SET_AFFINITY kmp_set_affinity_
|
||||
#define FTN_GET_AFFINITY kmp_get_affinity_
|
||||
#define FTN_GET_AFFINITY_MAX_PROC kmp_get_affinity_max_proc_
|
||||
#define FTN_CREATE_AFFINITY_MASK kmp_create_affinity_mask_
|
||||
#define FTN_DESTROY_AFFINITY_MASK kmp_destroy_affinity_mask_
|
||||
#define FTN_SET_AFFINITY_MASK_PROC kmp_set_affinity_mask_proc_
|
||||
#define FTN_UNSET_AFFINITY_MASK_PROC kmp_unset_affinity_mask_proc_
|
||||
#define FTN_GET_AFFINITY_MASK_PROC kmp_get_affinity_mask_proc_
|
||||
|
||||
#define FTN_MALLOC kmp_malloc_
|
||||
#define FTN_ALIGNED_MALLOC kmp_aligned_malloc_
|
||||
#define FTN_CALLOC kmp_calloc_
|
||||
#define FTN_REALLOC kmp_realloc_
|
||||
#define FTN_KFREE kmp_free_
|
||||
|
||||
#define FTN_GET_NUM_KNOWN_THREADS kmp_get_num_known_threads_
|
||||
|
||||
#define FTN_SET_NUM_THREADS omp_set_num_threads_
|
||||
#define FTN_GET_NUM_THREADS omp_get_num_threads_
|
||||
#define FTN_GET_MAX_THREADS omp_get_max_threads_
|
||||
#define FTN_GET_THREAD_NUM omp_get_thread_num_
|
||||
#define FTN_GET_NUM_PROCS omp_get_num_procs_
|
||||
#define FTN_SET_DYNAMIC omp_set_dynamic_
|
||||
#define FTN_GET_DYNAMIC omp_get_dynamic_
|
||||
#define FTN_SET_NESTED omp_set_nested_
|
||||
#define FTN_GET_NESTED omp_get_nested_
|
||||
#define FTN_IN_PARALLEL omp_in_parallel_
|
||||
#define FTN_GET_THREAD_LIMIT omp_get_thread_limit_
|
||||
#define FTN_SET_SCHEDULE omp_set_schedule_
|
||||
#define FTN_GET_SCHEDULE omp_get_schedule_
|
||||
#define FTN_SET_MAX_ACTIVE_LEVELS omp_set_max_active_levels_
|
||||
#define FTN_GET_MAX_ACTIVE_LEVELS omp_get_max_active_levels_
|
||||
#define FTN_GET_ACTIVE_LEVEL omp_get_active_level_
|
||||
#define FTN_GET_LEVEL omp_get_level_
|
||||
#define FTN_GET_ANCESTOR_THREAD_NUM omp_get_ancestor_thread_num_
|
||||
#define FTN_GET_TEAM_SIZE omp_get_team_size_
|
||||
#define FTN_IN_FINAL omp_in_final_
|
||||
#define FTN_GET_PROC_BIND omp_get_proc_bind_
|
||||
#define FTN_GET_NUM_TEAMS omp_get_num_teams_
|
||||
#define FTN_GET_TEAM_NUM omp_get_team_num_
|
||||
#define FTN_INIT_LOCK omp_init_lock_
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
#define FTN_INIT_LOCK_WITH_HINT omp_init_lock_with_hint_
|
||||
#define FTN_INIT_NEST_LOCK_WITH_HINT omp_init_nest_lock_with_hint_
|
||||
#endif
|
||||
#define FTN_DESTROY_LOCK omp_destroy_lock_
|
||||
#define FTN_SET_LOCK omp_set_lock_
|
||||
#define FTN_UNSET_LOCK omp_unset_lock_
|
||||
#define FTN_TEST_LOCK omp_test_lock_
|
||||
#define FTN_INIT_NEST_LOCK omp_init_nest_lock_
|
||||
#define FTN_DESTROY_NEST_LOCK omp_destroy_nest_lock_
|
||||
#define FTN_SET_NEST_LOCK omp_set_nest_lock_
|
||||
#define FTN_UNSET_NEST_LOCK omp_unset_nest_lock_
|
||||
#define FTN_TEST_NEST_LOCK omp_test_nest_lock_
|
||||
|
||||
#define FTN_SET_WARNINGS_ON kmp_set_warnings_on_
|
||||
#define FTN_SET_WARNINGS_OFF kmp_set_warnings_off_
|
||||
|
||||
#define FTN_GET_WTIME omp_get_wtime_
|
||||
#define FTN_GET_WTICK omp_get_wtick_
|
||||
|
||||
#define FTN_GET_NUM_DEVICES omp_get_num_devices_
|
||||
#define FTN_GET_DEFAULT_DEVICE omp_get_default_device_
|
||||
#define FTN_SET_DEFAULT_DEVICE omp_set_default_device_
|
||||
#define FTN_IS_INITIAL_DEVICE omp_is_initial_device_
|
||||
|
||||
#define FTN_GET_CANCELLATION omp_get_cancellation_
|
||||
#define FTN_GET_CANCELLATION_STATUS kmp_get_cancellation_status_
|
||||
|
||||
#define FTN_GET_MAX_TASK_PRIORITY omp_get_max_task_priority_
|
||||
#define FTN_GET_NUM_PLACES omp_get_num_places_
|
||||
#define FTN_GET_PLACE_NUM_PROCS omp_get_place_num_procs_
|
||||
#define FTN_GET_PLACE_PROC_IDS omp_get_place_proc_ids_
|
||||
#define FTN_GET_PLACE_NUM omp_get_place_num_
|
||||
#define FTN_GET_PARTITION_NUM_PLACES omp_get_partition_num_places_
|
||||
#define FTN_GET_PARTITION_PLACE_NUMS omp_get_partition_place_nums_
|
||||
#define FTN_GET_INITIAL_DEVICE omp_get_initial_device_
|
||||
#ifdef KMP_STUB
|
||||
#define FTN_TARGET_ALLOC omp_target_alloc_
|
||||
#define FTN_TARGET_FREE omp_target_free_
|
||||
#define FTN_TARGET_IS_PRESENT omp_target_is_present_
|
||||
#define FTN_TARGET_MEMCPY omp_target_memcpy_
|
||||
#define FTN_TARGET_MEMCPY_RECT omp_target_memcpy_rect_
|
||||
#define FTN_TARGET_ASSOCIATE_PTR omp_target_associate_ptr_
|
||||
#define FTN_TARGET_DISASSOCIATE_PTR omp_target_disassociate_ptr_
|
||||
#endif
|
||||
|
||||
#define FTN_CONTROL_TOOL omp_control_tool_
|
||||
#define FTN_INIT_ALLOCATOR omp_init_allocator_
|
||||
#define FTN_DESTROY_ALLOCATOR omp_destroy_allocator_
|
||||
#define FTN_SET_DEFAULT_ALLOCATOR omp_set_default_allocator_
|
||||
#define FTN_GET_DEFAULT_ALLOCATOR omp_get_default_allocator_
|
||||
#define FTN_ALLOC omp_alloc_
|
||||
#define FTN_FREE omp_free_
|
||||
#define FTN_GET_DEVICE_NUM omp_get_device_num_
|
||||
#define FTN_SET_AFFINITY_FORMAT omp_set_affinity_format_
|
||||
#define FTN_GET_AFFINITY_FORMAT omp_get_affinity_format_
|
||||
#define FTN_DISPLAY_AFFINITY omp_display_affinity_
|
||||
#define FTN_CAPTURE_AFFINITY omp_capture_affinity_
|
||||
#define FTN_PAUSE_RESOURCE omp_pause_resource_
|
||||
#define FTN_PAUSE_RESOURCE_ALL omp_pause_resource_all_
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS omp_get_supported_active_levels_
|
||||
#define FTN_DISPLAY_ENV omp_display_env_
|
||||
#define FTN_IN_EXPLICIT_TASK omp_in_explicit_task_
|
||||
#define FTN_FULFILL_EVENT omp_fulfill_event_
|
||||
#define FTN_SET_NUM_TEAMS omp_set_num_teams_
|
||||
#define FTN_GET_MAX_TEAMS omp_get_max_teams_
|
||||
#define FTN_SET_TEAMS_THREAD_LIMIT omp_set_teams_thread_limit_
|
||||
#define FTN_GET_TEAMS_THREAD_LIMIT omp_get_teams_thread_limit_
|
||||
|
||||
#define FTN_GET_NUM_INTEROP_PROPERTIES omp_get_num_interop_properties_
|
||||
#define FTN_GET_INTEROP_INT omp_get_interop_int_
|
||||
#define FTN_GET_INTEROP_PTR omp_get_interop_ptr_
|
||||
#define FTN_GET_INTEROP_STR omp_get_interop_str_
|
||||
#define FTN_GET_INTEROP_NAME omp_get_interop_name_
|
||||
#define FTN_GET_INTEROP_TYPE_DESC omp_get_interop_type_desc_
|
||||
#define FTN_GET_INTEROP_RC_DESC omp_get_interop_rc_desc_
|
||||
|
||||
#endif /* KMP_FTN_APPEND */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if KMP_FTN_ENTRIES == KMP_FTN_UPPER
|
||||
|
||||
#define FTN_SET_STACKSIZE KMP_SET_STACKSIZE
|
||||
#define FTN_SET_STACKSIZE_S KMP_SET_STACKSIZE_S
|
||||
#define FTN_GET_STACKSIZE KMP_GET_STACKSIZE
|
||||
#define FTN_GET_STACKSIZE_S KMP_GET_STACKSIZE_S
|
||||
#define FTN_SET_BLOCKTIME KMP_SET_BLOCKTIME
|
||||
#define FTN_GET_BLOCKTIME KMP_GET_BLOCKTIME
|
||||
#define FTN_SET_LIBRARY_SERIAL KMP_SET_LIBRARY_SERIAL
|
||||
#define FTN_SET_LIBRARY_TURNAROUND KMP_SET_LIBRARY_TURNAROUND
|
||||
#define FTN_SET_LIBRARY_THROUGHPUT KMP_SET_LIBRARY_THROUGHPUT
|
||||
#define FTN_SET_LIBRARY KMP_SET_LIBRARY
|
||||
#define FTN_GET_LIBRARY KMP_GET_LIBRARY
|
||||
#define FTN_SET_DEFAULTS KMP_SET_DEFAULTS
|
||||
#define FTN_SET_DISP_NUM_BUFFERS KMP_SET_DISP_NUM_BUFFERS
|
||||
#define FTN_SET_AFFINITY KMP_SET_AFFINITY
|
||||
#define FTN_GET_AFFINITY KMP_GET_AFFINITY
|
||||
#define FTN_GET_AFFINITY_MAX_PROC KMP_GET_AFFINITY_MAX_PROC
|
||||
#define FTN_CREATE_AFFINITY_MASK KMP_CREATE_AFFINITY_MASK
|
||||
#define FTN_DESTROY_AFFINITY_MASK KMP_DESTROY_AFFINITY_MASK
|
||||
#define FTN_SET_AFFINITY_MASK_PROC KMP_SET_AFFINITY_MASK_PROC
|
||||
#define FTN_UNSET_AFFINITY_MASK_PROC KMP_UNSET_AFFINITY_MASK_PROC
|
||||
#define FTN_GET_AFFINITY_MASK_PROC KMP_GET_AFFINITY_MASK_PROC
|
||||
|
||||
#define FTN_MALLOC KMP_MALLOC
|
||||
#define FTN_ALIGNED_MALLOC KMP_ALIGNED_MALLOC
|
||||
#define FTN_CALLOC KMP_CALLOC
|
||||
#define FTN_REALLOC KMP_REALLOC
|
||||
#define FTN_KFREE KMP_FREE
|
||||
|
||||
#define FTN_GET_NUM_KNOWN_THREADS KMP_GET_NUM_KNOWN_THREADS
|
||||
|
||||
#define FTN_SET_NUM_THREADS OMP_SET_NUM_THREADS
|
||||
#define FTN_GET_NUM_THREADS OMP_GET_NUM_THREADS
|
||||
#define FTN_GET_MAX_THREADS OMP_GET_MAX_THREADS
|
||||
#define FTN_GET_THREAD_NUM OMP_GET_THREAD_NUM
|
||||
#define FTN_GET_NUM_PROCS OMP_GET_NUM_PROCS
|
||||
#define FTN_SET_DYNAMIC OMP_SET_DYNAMIC
|
||||
#define FTN_GET_DYNAMIC OMP_GET_DYNAMIC
|
||||
#define FTN_SET_NESTED OMP_SET_NESTED
|
||||
#define FTN_GET_NESTED OMP_GET_NESTED
|
||||
#define FTN_IN_PARALLEL OMP_IN_PARALLEL
|
||||
#define FTN_GET_THREAD_LIMIT OMP_GET_THREAD_LIMIT
|
||||
#define FTN_SET_SCHEDULE OMP_SET_SCHEDULE
|
||||
#define FTN_GET_SCHEDULE OMP_GET_SCHEDULE
|
||||
#define FTN_SET_MAX_ACTIVE_LEVELS OMP_SET_MAX_ACTIVE_LEVELS
|
||||
#define FTN_GET_MAX_ACTIVE_LEVELS OMP_GET_MAX_ACTIVE_LEVELS
|
||||
#define FTN_GET_ACTIVE_LEVEL OMP_GET_ACTIVE_LEVEL
|
||||
#define FTN_GET_LEVEL OMP_GET_LEVEL
|
||||
#define FTN_GET_ANCESTOR_THREAD_NUM OMP_GET_ANCESTOR_THREAD_NUM
|
||||
#define FTN_GET_TEAM_SIZE OMP_GET_TEAM_SIZE
|
||||
#define FTN_IN_FINAL OMP_IN_FINAL
|
||||
#define FTN_GET_PROC_BIND OMP_GET_PROC_BIND
|
||||
#define FTN_GET_NUM_TEAMS OMP_GET_NUM_TEAMS
|
||||
#define FTN_GET_TEAM_NUM OMP_GET_TEAM_NUM
|
||||
#define FTN_INIT_LOCK OMP_INIT_LOCK
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
#define FTN_INIT_LOCK_WITH_HINT OMP_INIT_LOCK_WITH_HINT
|
||||
#define FTN_INIT_NEST_LOCK_WITH_HINT OMP_INIT_NEST_LOCK_WITH_HINT
|
||||
#endif
|
||||
#define FTN_DESTROY_LOCK OMP_DESTROY_LOCK
|
||||
#define FTN_SET_LOCK OMP_SET_LOCK
|
||||
#define FTN_UNSET_LOCK OMP_UNSET_LOCK
|
||||
#define FTN_TEST_LOCK OMP_TEST_LOCK
|
||||
#define FTN_INIT_NEST_LOCK OMP_INIT_NEST_LOCK
|
||||
#define FTN_DESTROY_NEST_LOCK OMP_DESTROY_NEST_LOCK
|
||||
#define FTN_SET_NEST_LOCK OMP_SET_NEST_LOCK
|
||||
#define FTN_UNSET_NEST_LOCK OMP_UNSET_NEST_LOCK
|
||||
#define FTN_TEST_NEST_LOCK OMP_TEST_NEST_LOCK
|
||||
|
||||
#define FTN_SET_WARNINGS_ON KMP_SET_WARNINGS_ON
|
||||
#define FTN_SET_WARNINGS_OFF KMP_SET_WARNINGS_OFF
|
||||
|
||||
#define FTN_GET_WTIME OMP_GET_WTIME
|
||||
#define FTN_GET_WTICK OMP_GET_WTICK
|
||||
|
||||
#define FTN_GET_NUM_DEVICES OMP_GET_NUM_DEVICES
|
||||
#define FTN_GET_DEFAULT_DEVICE OMP_GET_DEFAULT_DEVICE
|
||||
#define FTN_SET_DEFAULT_DEVICE OMP_SET_DEFAULT_DEVICE
|
||||
#define FTN_IS_INITIAL_DEVICE OMP_IS_INITIAL_DEVICE
|
||||
|
||||
#define FTN_GET_CANCELLATION OMP_GET_CANCELLATION
|
||||
#define FTN_GET_CANCELLATION_STATUS KMP_GET_CANCELLATION_STATUS
|
||||
|
||||
#define FTN_GET_MAX_TASK_PRIORITY OMP_GET_MAX_TASK_PRIORITY
|
||||
#define FTN_GET_NUM_PLACES OMP_GET_NUM_PLACES
|
||||
#define FTN_GET_PLACE_NUM_PROCS OMP_GET_PLACE_NUM_PROCS
|
||||
#define FTN_GET_PLACE_PROC_IDS OMP_GET_PLACE_PROC_IDS
|
||||
#define FTN_GET_PLACE_NUM OMP_GET_PLACE_NUM
|
||||
#define FTN_GET_PARTITION_NUM_PLACES OMP_GET_PARTITION_NUM_PLACES
|
||||
#define FTN_GET_PARTITION_PLACE_NUMS OMP_GET_PARTITION_PLACE_NUMS
|
||||
#define FTN_GET_INITIAL_DEVICE OMP_GET_INITIAL_DEVICE
|
||||
#ifdef KMP_STUB
|
||||
#define FTN_TARGET_ALLOC OMP_TARGET_ALLOC
|
||||
#define FTN_TARGET_FREE OMP_TARGET_FREE
|
||||
#define FTN_TARGET_IS_PRESENT OMP_TARGET_IS_PRESENT
|
||||
#define FTN_TARGET_MEMCPY OMP_TARGET_MEMCPY
|
||||
#define FTN_TARGET_MEMCPY_RECT OMP_TARGET_MEMCPY_RECT
|
||||
#define FTN_TARGET_ASSOCIATE_PTR OMP_TARGET_ASSOCIATE_PTR
|
||||
#define FTN_TARGET_DISASSOCIATE_PTR OMP_TARGET_DISASSOCIATE_PTR
|
||||
#endif
|
||||
|
||||
#define FTN_CONTROL_TOOL OMP_CONTROL_TOOL
|
||||
#define FTN_INIT_ALLOCATOR OMP_INIT_ALLOCATOR
|
||||
#define FTN_DESTROY_ALLOCATOR OMP_DESTROY_ALLOCATOR
|
||||
#define FTN_SET_DEFAULT_ALLOCATOR OMP_SET_DEFAULT_ALLOCATOR
|
||||
#define FTN_GET_DEFAULT_ALLOCATOR OMP_GET_DEFAULT_ALLOCATOR
|
||||
#define FTN_GET_DEVICE_NUM OMP_GET_DEVICE_NUM
|
||||
#define FTN_SET_AFFINITY_FORMAT OMP_SET_AFFINITY_FORMAT
|
||||
#define FTN_GET_AFFINITY_FORMAT OMP_GET_AFFINITY_FORMAT
|
||||
#define FTN_DISPLAY_AFFINITY OMP_DISPLAY_AFFINITY
|
||||
#define FTN_CAPTURE_AFFINITY OMP_CAPTURE_AFFINITY
|
||||
#define FTN_PAUSE_RESOURCE OMP_PAUSE_RESOURCE
|
||||
#define FTN_PAUSE_RESOURCE_ALL OMP_PAUSE_RESOURCE_ALL
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS OMP_GET_SUPPORTED_ACTIVE_LEVELS
|
||||
#define FTN_DISPLAY_ENV OMP_DISPLAY_ENV
|
||||
#define FTN_IN_EXPLICIT_TASK OMP_IN_EXPLICIT_TASK
|
||||
#define FTN_FULFILL_EVENT OMP_FULFILL_EVENT
|
||||
#define FTN_SET_NUM_TEAMS OMP_SET_NUM_TEAMS
|
||||
#define FTN_GET_MAX_TEAMS OMP_GET_MAX_TEAMS
|
||||
#define FTN_SET_TEAMS_THREAD_LIMIT OMP_SET_TEAMS_THREAD_LIMIT
|
||||
#define FTN_GET_TEAMS_THREAD_LIMIT OMP_GET_TEAMS_THREAD_LIMIT
|
||||
|
||||
#define FTN_GET_NUM_INTEROP_PROPERTIES OMP_GET_NUM_INTEROP_PROPERTIES
|
||||
#define FTN_GET_INTEROP_INT OMP_GET_INTEROP_INT
|
||||
#define FTN_GET_INTEROP_PTR OMP_GET_INTEROP_PTR
|
||||
#define FTN_GET_INTEROP_STR OMP_GET_INTEROP_STR
|
||||
#define FTN_GET_INTEROP_NAME OMP_GET_INTEROP_NAME
|
||||
#define FTN_GET_INTEROP_TYPE_DESC OMP_GET_INTEROP_TYPE_DESC
|
||||
#define FTN_GET_INTEROP_RC_DESC OMP_GET_INTEROP_RC_DESC
|
||||
|
||||
#endif /* KMP_FTN_UPPER */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if KMP_FTN_ENTRIES == KMP_FTN_UAPPEND
|
||||
|
||||
#define FTN_SET_STACKSIZE KMP_SET_STACKSIZE_
|
||||
#define FTN_SET_STACKSIZE_S KMP_SET_STACKSIZE_S_
|
||||
#define FTN_GET_STACKSIZE KMP_GET_STACKSIZE_
|
||||
#define FTN_GET_STACKSIZE_S KMP_GET_STACKSIZE_S_
|
||||
#define FTN_SET_BLOCKTIME KMP_SET_BLOCKTIME_
|
||||
#define FTN_GET_BLOCKTIME KMP_GET_BLOCKTIME_
|
||||
#define FTN_SET_LIBRARY_SERIAL KMP_SET_LIBRARY_SERIAL_
|
||||
#define FTN_SET_LIBRARY_TURNAROUND KMP_SET_LIBRARY_TURNAROUND_
|
||||
#define FTN_SET_LIBRARY_THROUGHPUT KMP_SET_LIBRARY_THROUGHPUT_
|
||||
#define FTN_SET_LIBRARY KMP_SET_LIBRARY_
|
||||
#define FTN_GET_LIBRARY KMP_GET_LIBRARY_
|
||||
#define FTN_SET_DEFAULTS KMP_SET_DEFAULTS_
|
||||
#define FTN_SET_DISP_NUM_BUFFERS KMP_SET_DISP_NUM_BUFFERS_
|
||||
#define FTN_SET_AFFINITY KMP_SET_AFFINITY_
|
||||
#define FTN_GET_AFFINITY KMP_GET_AFFINITY_
|
||||
#define FTN_GET_AFFINITY_MAX_PROC KMP_GET_AFFINITY_MAX_PROC_
|
||||
#define FTN_CREATE_AFFINITY_MASK KMP_CREATE_AFFINITY_MASK_
|
||||
#define FTN_DESTROY_AFFINITY_MASK KMP_DESTROY_AFFINITY_MASK_
|
||||
#define FTN_SET_AFFINITY_MASK_PROC KMP_SET_AFFINITY_MASK_PROC_
|
||||
#define FTN_UNSET_AFFINITY_MASK_PROC KMP_UNSET_AFFINITY_MASK_PROC_
|
||||
#define FTN_GET_AFFINITY_MASK_PROC KMP_GET_AFFINITY_MASK_PROC_
|
||||
|
||||
#define FTN_MALLOC KMP_MALLOC_
|
||||
#define FTN_ALIGNED_MALLOC KMP_ALIGNED_MALLOC_
|
||||
#define FTN_CALLOC KMP_CALLOC_
|
||||
#define FTN_REALLOC KMP_REALLOC_
|
||||
#define FTN_KFREE KMP_FREE_
|
||||
|
||||
#define FTN_GET_NUM_KNOWN_THREADS KMP_GET_NUM_KNOWN_THREADS_
|
||||
|
||||
#define FTN_SET_NUM_THREADS OMP_SET_NUM_THREADS_
|
||||
#define FTN_GET_NUM_THREADS OMP_GET_NUM_THREADS_
|
||||
#define FTN_GET_MAX_THREADS OMP_GET_MAX_THREADS_
|
||||
#define FTN_GET_THREAD_NUM OMP_GET_THREAD_NUM_
|
||||
#define FTN_GET_NUM_PROCS OMP_GET_NUM_PROCS_
|
||||
#define FTN_SET_DYNAMIC OMP_SET_DYNAMIC_
|
||||
#define FTN_GET_DYNAMIC OMP_GET_DYNAMIC_
|
||||
#define FTN_SET_NESTED OMP_SET_NESTED_
|
||||
#define FTN_GET_NESTED OMP_GET_NESTED_
|
||||
#define FTN_IN_PARALLEL OMP_IN_PARALLEL_
|
||||
#define FTN_GET_THREAD_LIMIT OMP_GET_THREAD_LIMIT_
|
||||
#define FTN_SET_SCHEDULE OMP_SET_SCHEDULE_
|
||||
#define FTN_GET_SCHEDULE OMP_GET_SCHEDULE_
|
||||
#define FTN_SET_MAX_ACTIVE_LEVELS OMP_SET_MAX_ACTIVE_LEVELS_
|
||||
#define FTN_GET_MAX_ACTIVE_LEVELS OMP_GET_MAX_ACTIVE_LEVELS_
|
||||
#define FTN_GET_ACTIVE_LEVEL OMP_GET_ACTIVE_LEVEL_
|
||||
#define FTN_GET_LEVEL OMP_GET_LEVEL_
|
||||
#define FTN_GET_ANCESTOR_THREAD_NUM OMP_GET_ANCESTOR_THREAD_NUM_
|
||||
#define FTN_GET_TEAM_SIZE OMP_GET_TEAM_SIZE_
|
||||
#define FTN_IN_FINAL OMP_IN_FINAL_
|
||||
#define FTN_GET_PROC_BIND OMP_GET_PROC_BIND_
|
||||
#define FTN_GET_NUM_TEAMS OMP_GET_NUM_TEAMS_
|
||||
#define FTN_GET_TEAM_NUM OMP_GET_TEAM_NUM_
|
||||
#define FTN_INIT_LOCK OMP_INIT_LOCK_
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
#define FTN_INIT_LOCK_WITH_HINT OMP_INIT_LOCK_WITH_HINT_
|
||||
#define FTN_INIT_NEST_LOCK_WITH_HINT OMP_INIT_NEST_LOCK_WITH_HINT_
|
||||
#endif
|
||||
#define FTN_DESTROY_LOCK OMP_DESTROY_LOCK_
|
||||
#define FTN_SET_LOCK OMP_SET_LOCK_
|
||||
#define FTN_UNSET_LOCK OMP_UNSET_LOCK_
|
||||
#define FTN_TEST_LOCK OMP_TEST_LOCK_
|
||||
#define FTN_INIT_NEST_LOCK OMP_INIT_NEST_LOCK_
|
||||
#define FTN_DESTROY_NEST_LOCK OMP_DESTROY_NEST_LOCK_
|
||||
#define FTN_SET_NEST_LOCK OMP_SET_NEST_LOCK_
|
||||
#define FTN_UNSET_NEST_LOCK OMP_UNSET_NEST_LOCK_
|
||||
#define FTN_TEST_NEST_LOCK OMP_TEST_NEST_LOCK_
|
||||
|
||||
#define FTN_SET_WARNINGS_ON KMP_SET_WARNINGS_ON_
|
||||
#define FTN_SET_WARNINGS_OFF KMP_SET_WARNINGS_OFF_
|
||||
|
||||
#define FTN_GET_WTIME OMP_GET_WTIME_
|
||||
#define FTN_GET_WTICK OMP_GET_WTICK_
|
||||
|
||||
#define FTN_GET_NUM_DEVICES OMP_GET_NUM_DEVICES_
|
||||
#define FTN_GET_DEFAULT_DEVICE OMP_GET_DEFAULT_DEVICE_
|
||||
#define FTN_SET_DEFAULT_DEVICE OMP_SET_DEFAULT_DEVICE_
|
||||
#define FTN_IS_INITIAL_DEVICE OMP_IS_INITIAL_DEVICE_
|
||||
|
||||
#define FTN_GET_CANCELLATION OMP_GET_CANCELLATION_
|
||||
#define FTN_GET_CANCELLATION_STATUS KMP_GET_CANCELLATION_STATUS_
|
||||
|
||||
#define FTN_GET_MAX_TASK_PRIORITY OMP_GET_MAX_TASK_PRIORITY_
|
||||
#define FTN_GET_NUM_PLACES OMP_GET_NUM_PLACES_
|
||||
#define FTN_GET_PLACE_NUM_PROCS OMP_GET_PLACE_NUM_PROCS_
|
||||
#define FTN_GET_PLACE_PROC_IDS OMP_GET_PLACE_PROC_IDS_
|
||||
#define FTN_GET_PLACE_NUM OMP_GET_PLACE_NUM_
|
||||
#define FTN_GET_PARTITION_NUM_PLACES OMP_GET_PARTITION_NUM_PLACES_
|
||||
#define FTN_GET_PARTITION_PLACE_NUMS OMP_GET_PARTITION_PLACE_NUMS_
|
||||
#define FTN_GET_INITIAL_DEVICE OMP_GET_INITIAL_DEVICE_
|
||||
#ifdef KMP_STUB
|
||||
#define FTN_TARGET_ALLOC OMP_TARGET_ALLOC_
|
||||
#define FTN_TARGET_FREE OMP_TARGET_FREE_
|
||||
#define FTN_TARGET_IS_PRESENT OMP_TARGET_IS_PRESENT_
|
||||
#define FTN_TARGET_MEMCPY OMP_TARGET_MEMCPY_
|
||||
#define FTN_TARGET_MEMCPY_RECT OMP_TARGET_MEMCPY_RECT_
|
||||
#define FTN_TARGET_ASSOCIATE_PTR OMP_TARGET_ASSOCIATE_PTR_
|
||||
#define FTN_TARGET_DISASSOCIATE_PTR OMP_TARGET_DISASSOCIATE_PTR_
|
||||
#endif
|
||||
|
||||
#define FTN_CONTROL_TOOL OMP_CONTROL_TOOL_
|
||||
#define FTN_INIT_ALLOCATOR OMP_INIT_ALLOCATOR_
|
||||
#define FTN_DESTROY_ALLOCATOR OMP_DESTROY_ALLOCATOR_
|
||||
#define FTN_SET_DEFAULT_ALLOCATOR OMP_SET_DEFAULT_ALLOCATOR_
|
||||
#define FTN_GET_DEFAULT_ALLOCATOR OMP_GET_DEFAULT_ALLOCATOR_
|
||||
#define FTN_ALLOC OMP_ALLOC_
|
||||
#define FTN_FREE OMP_FREE_
|
||||
#define FTN_GET_DEVICE_NUM OMP_GET_DEVICE_NUM_
|
||||
#define FTN_SET_AFFINITY_FORMAT OMP_SET_AFFINITY_FORMAT_
|
||||
#define FTN_GET_AFFINITY_FORMAT OMP_GET_AFFINITY_FORMAT_
|
||||
#define FTN_DISPLAY_AFFINITY OMP_DISPLAY_AFFINITY_
|
||||
#define FTN_CAPTURE_AFFINITY OMP_CAPTURE_AFFINITY_
|
||||
#define FTN_PAUSE_RESOURCE OMP_PAUSE_RESOURCE_
|
||||
#define FTN_PAUSE_RESOURCE_ALL OMP_PAUSE_RESOURCE_ALL_
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS OMP_GET_SUPPORTED_ACTIVE_LEVELS_
|
||||
#define FTN_DISPLAY_ENV OMP_DISPLAY_ENV_
|
||||
#define FTN_IN_EXPLICIT_TASK OMP_IN_EXPLICIT_TASK_
|
||||
#define FTN_FULFILL_EVENT OMP_FULFILL_EVENT_
|
||||
#define FTN_SET_NUM_TEAMS OMP_SET_NUM_TEAMS_
|
||||
#define FTN_GET_MAX_TEAMS OMP_GET_MAX_TEAMS_
|
||||
#define FTN_SET_TEAMS_THREAD_LIMIT OMP_SET_TEAMS_THREAD_LIMIT_
|
||||
#define FTN_GET_TEAMS_THREAD_LIMIT OMP_GET_TEAMS_THREAD_LIMIT_
|
||||
|
||||
#define FTN_GET_NUM_INTEROP_PROPERTIES OMP_GET_NUM_INTEROP_PROPERTIES_
|
||||
#define FTN_GET_INTEROP_INT OMP_GET_INTEROP_INT_
|
||||
#define FTN_GET_INTEROP_PTR OMP_GET_INTEROP_PTR_
|
||||
#define FTN_GET_INTEROP_STR OMP_GET_INTEROP_STR_
|
||||
#define FTN_GET_INTEROP_NAME OMP_GET_INTEROP_NAME_
|
||||
#define FTN_GET_INTEROP_TYPE_DESC OMP_GET_INTEROP_TYPE_DESC_
|
||||
#define FTN_GET_INTEROP_RC_DESC OMP_GET_INTEROP_RC_DESC_
|
||||
|
||||
#endif /* KMP_FTN_UAPPEND */
|
||||
|
||||
/* -------------------------- GOMP API NAMES ------------------------ */
|
||||
// All GOMP_1.0 symbols
|
||||
#define KMP_API_NAME_GOMP_ATOMIC_END GOMP_atomic_end
|
||||
#define KMP_API_NAME_GOMP_ATOMIC_START GOMP_atomic_start
|
||||
#define KMP_API_NAME_GOMP_BARRIER GOMP_barrier
|
||||
#define KMP_API_NAME_GOMP_CRITICAL_END GOMP_critical_end
|
||||
#define KMP_API_NAME_GOMP_CRITICAL_NAME_END GOMP_critical_name_end
|
||||
#define KMP_API_NAME_GOMP_CRITICAL_NAME_START GOMP_critical_name_start
|
||||
#define KMP_API_NAME_GOMP_CRITICAL_START GOMP_critical_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_DYNAMIC_NEXT GOMP_loop_dynamic_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_DYNAMIC_START GOMP_loop_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_END GOMP_loop_end
|
||||
#define KMP_API_NAME_GOMP_LOOP_END_NOWAIT GOMP_loop_end_nowait
|
||||
#define KMP_API_NAME_GOMP_LOOP_GUIDED_NEXT GOMP_loop_guided_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_GUIDED_START GOMP_loop_guided_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_NEXT \
|
||||
GOMP_loop_ordered_dynamic_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_DYNAMIC_START \
|
||||
GOMP_loop_ordered_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_NEXT GOMP_loop_ordered_guided_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_GUIDED_START \
|
||||
GOMP_loop_ordered_guided_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_NEXT \
|
||||
GOMP_loop_ordered_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_RUNTIME_START \
|
||||
GOMP_loop_ordered_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_NEXT GOMP_loop_ordered_static_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_STATIC_START \
|
||||
GOMP_loop_ordered_static_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_RUNTIME_NEXT GOMP_loop_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_RUNTIME_START GOMP_loop_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_STATIC_NEXT GOMP_loop_static_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_STATIC_START GOMP_loop_static_start
|
||||
#define KMP_API_NAME_GOMP_ORDERED_END GOMP_ordered_end
|
||||
#define KMP_API_NAME_GOMP_ORDERED_START GOMP_ordered_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_END GOMP_parallel_end
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC_START \
|
||||
GOMP_parallel_loop_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED_START \
|
||||
GOMP_parallel_loop_guided_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME_START \
|
||||
GOMP_parallel_loop_runtime_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC_START \
|
||||
GOMP_parallel_loop_static_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START GOMP_parallel_sections_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_START GOMP_parallel_start
|
||||
#define KMP_API_NAME_GOMP_SECTIONS_END GOMP_sections_end
|
||||
#define KMP_API_NAME_GOMP_SECTIONS_END_NOWAIT GOMP_sections_end_nowait
|
||||
#define KMP_API_NAME_GOMP_SECTIONS_NEXT GOMP_sections_next
|
||||
#define KMP_API_NAME_GOMP_SECTIONS_START GOMP_sections_start
|
||||
#define KMP_API_NAME_GOMP_SINGLE_COPY_END GOMP_single_copy_end
|
||||
#define KMP_API_NAME_GOMP_SINGLE_COPY_START GOMP_single_copy_start
|
||||
#define KMP_API_NAME_GOMP_SINGLE_START GOMP_single_start
|
||||
|
||||
// All GOMP_2.0 symbols
|
||||
#define KMP_API_NAME_GOMP_TASK GOMP_task
|
||||
#define KMP_API_NAME_GOMP_TASKWAIT GOMP_taskwait
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_NEXT GOMP_loop_ull_dynamic_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_DYNAMIC_START GOMP_loop_ull_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_NEXT GOMP_loop_ull_guided_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_GUIDED_START GOMP_loop_ull_guided_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_NEXT \
|
||||
GOMP_loop_ull_ordered_dynamic_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_DYNAMIC_START \
|
||||
GOMP_loop_ull_ordered_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_NEXT \
|
||||
GOMP_loop_ull_ordered_guided_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_GUIDED_START \
|
||||
GOMP_loop_ull_ordered_guided_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT \
|
||||
GOMP_loop_ull_ordered_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_START \
|
||||
GOMP_loop_ull_ordered_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_NEXT \
|
||||
GOMP_loop_ull_ordered_static_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_STATIC_START \
|
||||
GOMP_loop_ull_ordered_static_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_NEXT GOMP_loop_ull_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_RUNTIME_START GOMP_loop_ull_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_STATIC_NEXT GOMP_loop_ull_static_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_STATIC_START GOMP_loop_ull_static_start
|
||||
|
||||
// All GOMP_3.0 symbols
|
||||
#define KMP_API_NAME_GOMP_TASKYIELD GOMP_taskyield
|
||||
|
||||
// All GOMP_4.0 symbols
|
||||
#define KMP_API_NAME_GOMP_BARRIER_CANCEL GOMP_barrier_cancel
|
||||
#define KMP_API_NAME_GOMP_CANCEL GOMP_cancel
|
||||
#define KMP_API_NAME_GOMP_CANCELLATION_POINT GOMP_cancellation_point
|
||||
#define KMP_API_NAME_GOMP_LOOP_END_CANCEL GOMP_loop_end_cancel
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_DYNAMIC GOMP_parallel_loop_dynamic
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_GUIDED GOMP_parallel_loop_guided
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_RUNTIME GOMP_parallel_loop_runtime
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_STATIC GOMP_parallel_loop_static
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_SECTIONS GOMP_parallel_sections
|
||||
#define KMP_API_NAME_GOMP_PARALLEL GOMP_parallel
|
||||
#define KMP_API_NAME_GOMP_SECTIONS_END_CANCEL GOMP_sections_end_cancel
|
||||
#define KMP_API_NAME_GOMP_TASKGROUP_START GOMP_taskgroup_start
|
||||
#define KMP_API_NAME_GOMP_TASKGROUP_END GOMP_taskgroup_end
|
||||
/* Target functions should be taken care of by liboffload */
|
||||
#define KMP_API_NAME_GOMP_TARGET GOMP_target
|
||||
#define KMP_API_NAME_GOMP_TARGET_DATA GOMP_target_data
|
||||
#define KMP_API_NAME_GOMP_TARGET_END_DATA GOMP_target_end_data
|
||||
#define KMP_API_NAME_GOMP_TARGET_UPDATE GOMP_target_update
|
||||
#define KMP_API_NAME_GOMP_TEAMS GOMP_teams
|
||||
|
||||
// All GOMP_4.5 symbols
|
||||
#define KMP_API_NAME_GOMP_TASKLOOP GOMP_taskloop
|
||||
#define KMP_API_NAME_GOMP_TASKLOOP_ULL GOMP_taskloop_ull
|
||||
#define KMP_API_NAME_GOMP_DOACROSS_POST GOMP_doacross_post
|
||||
#define KMP_API_NAME_GOMP_DOACROSS_WAIT GOMP_doacross_wait
|
||||
#define KMP_API_NAME_GOMP_LOOP_DOACROSS_STATIC_START \
|
||||
GOMP_loop_doacross_static_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_DOACROSS_DYNAMIC_START \
|
||||
GOMP_loop_doacross_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_DOACROSS_GUIDED_START \
|
||||
GOMP_loop_doacross_guided_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_DOACROSS_RUNTIME_START \
|
||||
GOMP_loop_doacross_runtime_start
|
||||
#define KMP_API_NAME_GOMP_DOACROSS_ULL_POST GOMP_doacross_ull_post
|
||||
#define KMP_API_NAME_GOMP_DOACROSS_ULL_WAIT GOMP_doacross_ull_wait
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_STATIC_START \
|
||||
GOMP_loop_ull_doacross_static_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_DYNAMIC_START \
|
||||
GOMP_loop_ull_doacross_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_GUIDED_START \
|
||||
GOMP_loop_ull_doacross_guided_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_RUNTIME_START \
|
||||
GOMP_loop_ull_doacross_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_NEXT \
|
||||
GOMP_loop_nonmonotonic_dynamic_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_DYNAMIC_START \
|
||||
GOMP_loop_nonmonotonic_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_NEXT \
|
||||
GOMP_loop_nonmonotonic_guided_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_GUIDED_START \
|
||||
GOMP_loop_nonmonotonic_guided_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_NEXT \
|
||||
GOMP_loop_ull_nonmonotonic_dynamic_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_DYNAMIC_START \
|
||||
GOMP_loop_ull_nonmonotonic_dynamic_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_NEXT \
|
||||
GOMP_loop_ull_nonmonotonic_guided_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_GUIDED_START \
|
||||
GOMP_loop_ull_nonmonotonic_guided_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC \
|
||||
GOMP_parallel_loop_nonmonotonic_dynamic
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_GUIDED \
|
||||
GOMP_parallel_loop_nonmonotonic_guided
|
||||
|
||||
// All GOMP_5.0 symbols
|
||||
#define KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_NEXT \
|
||||
GOMP_loop_maybe_nonmonotonic_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_MAYBE_NONMONOTONIC_RUNTIME_START \
|
||||
GOMP_loop_maybe_nonmonotonic_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_NEXT \
|
||||
GOMP_loop_nonmonotonic_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_NONMONOTONIC_RUNTIME_START \
|
||||
GOMP_loop_nonmonotonic_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_NEXT \
|
||||
GOMP_loop_ull_maybe_nonmonotonic_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_MAYBE_NONMONOTONIC_RUNTIME_START \
|
||||
GOMP_loop_ull_maybe_nonmonotonic_runtime_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_NEXT \
|
||||
GOMP_loop_ull_nonmonotonic_runtime_next
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_NONMONOTONIC_RUNTIME_START \
|
||||
GOMP_loop_ull_nonmonotonic_runtime_start
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME \
|
||||
GOMP_parallel_loop_nonmonotonic_runtime
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_LOOP_MAYBE_NONMONOTONIC_RUNTIME \
|
||||
GOMP_parallel_loop_maybe_nonmonotonic_runtime
|
||||
#define KMP_API_NAME_GOMP_TEAMS_REG GOMP_teams_reg
|
||||
#define KMP_API_NAME_GOMP_TASKWAIT_DEPEND GOMP_taskwait_depend
|
||||
#define KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_REGISTER \
|
||||
GOMP_taskgroup_reduction_register
|
||||
#define KMP_API_NAME_GOMP_TASKGROUP_REDUCTION_UNREGISTER \
|
||||
GOMP_taskgroup_reduction_unregister
|
||||
#define KMP_API_NAME_GOMP_TASK_REDUCTION_REMAP GOMP_task_reduction_remap
|
||||
#define KMP_API_NAME_GOMP_PARALLEL_REDUCTIONS GOMP_parallel_reductions
|
||||
#define KMP_API_NAME_GOMP_LOOP_START GOMP_loop_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_START GOMP_loop_ull_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_DOACROSS_START GOMP_loop_doacross_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_DOACROSS_START GOMP_loop_ull_doacross_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ORDERED_START GOMP_loop_ordered_start
|
||||
#define KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_START GOMP_loop_ull_ordered_start
|
||||
#define KMP_API_NAME_GOMP_SECTIONS2_START GOMP_sections2_start
|
||||
#define KMP_API_NAME_GOMP_WORKSHARE_TASK_REDUCTION_UNREGISTER \
|
||||
GOMP_workshare_task_reduction_unregister
|
||||
#define KMP_API_NAME_GOMP_ALLOC GOMP_alloc
|
||||
#define KMP_API_NAME_GOMP_FREE GOMP_free
|
||||
#endif /* KMP_FTN_OS_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue