| #include "kmp.h" | |
| #include <utility> | |
| #if !(KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_MIC || KMP_ARCH_AARCH64 || \ | |
| KMP_ARCH_PPC64 || KMP_ARCH_RISCV64 || KMP_ARCH_LOONGARCH64 || \ | |
| KMP_ARCH_ARM || KMP_ARCH_VE || KMP_ARCH_S390X || KMP_ARCH_PPC_XCOFF || \ | |
| KMP_ARCH_AARCH64_32) | |
| template <size_t> using microtask_argument_t = void *; | |
| template <size_t... Indices> | |
| static void invokeMicrotask(microtask_t pkfn, int *gtid, int *tid, | |
| void *p_argv[], std::index_sequence<Indices...>) { | |
| // WebAssembly's `call_indirect` requires the callee type to exactly match the | |
| // call site. Cast the variadic microtask_t to the fixed-arity signature that | |
| // matches argc before invoking it. | |
| using typed_microtask_t = | |
| void (*)(int *, int *, microtask_argument_t<Indices>...); | |
| (*(typed_microtask_t)pkfn)(gtid, tid, p_argv[Indices]...); | |
| } | |
| // Keep a bounded set of exact signatures for targets that cannot dynamically | |
| // construct a variable-argument microtask call. | |
| int __kmp_invoke_microtask(microtask_t pkfn, int gtid, int tid, int argc, | |
| void *p_argv[] | |
| #if OMPT_SUPPORT | |
| , | |
| void **exit_frame_ptr | |
| #endif | |
| ) { | |
| #if OMPT_SUPPORT | |
| *exit_frame_ptr = OMPT_GET_FRAME_ADDRESS(0); | |
| #endif | |
| #define KMP_INVOKE_MICROTASK_CASE(N) \ | |
| case N: \ | |
| invokeMicrotask(pkfn, >id, &tid, p_argv, std::make_index_sequence<N>{}); \ | |
| break | |
| switch (argc) { | |
| KMP_INVOKE_MICROTASK_CASE(0); | |
| KMP_INVOKE_MICROTASK_CASE(1); | |
| KMP_INVOKE_MICROTASK_CASE(2); | |
| KMP_INVOKE_MICROTASK_CASE(3); | |
| KMP_INVOKE_MICROTASK_CASE(4); | |
| KMP_INVOKE_MICROTASK_CASE(5); | |
| KMP_INVOKE_MICROTASK_CASE(6); | |
| KMP_INVOKE_MICROTASK_CASE(7); | |
| KMP_INVOKE_MICROTASK_CASE(8); | |
| KMP_INVOKE_MICROTASK_CASE(9); | |
| KMP_INVOKE_MICROTASK_CASE(10); | |
| KMP_INVOKE_MICROTASK_CASE(11); | |
| KMP_INVOKE_MICROTASK_CASE(12); | |
| KMP_INVOKE_MICROTASK_CASE(13); | |
| KMP_INVOKE_MICROTASK_CASE(14); | |
| KMP_INVOKE_MICROTASK_CASE(15); | |
| KMP_INVOKE_MICROTASK_CASE(16); | |
| KMP_INVOKE_MICROTASK_CASE(17); | |
| KMP_INVOKE_MICROTASK_CASE(18); | |
| KMP_INVOKE_MICROTASK_CASE(19); | |
| KMP_INVOKE_MICROTASK_CASE(20); | |
| KMP_INVOKE_MICROTASK_CASE(21); | |
| KMP_INVOKE_MICROTASK_CASE(22); | |
| KMP_INVOKE_MICROTASK_CASE(23); | |
| KMP_INVOKE_MICROTASK_CASE(24); | |
| KMP_INVOKE_MICROTASK_CASE(25); | |
| KMP_INVOKE_MICROTASK_CASE(26); | |
| KMP_INVOKE_MICROTASK_CASE(27); | |
| KMP_INVOKE_MICROTASK_CASE(28); | |
| KMP_INVOKE_MICROTASK_CASE(29); | |
| KMP_INVOKE_MICROTASK_CASE(30); | |
| KMP_INVOKE_MICROTASK_CASE(31); | |
| KMP_INVOKE_MICROTASK_CASE(32); | |
| default: | |
| fprintf(stderr, "Too many args to microtask: %d!\n", argc); | |
| fflush(stderr); | |
| exit(-1); | |
| } | |
| #undef KMP_INVOKE_MICROTASK_CASE | |
| return 1; | |
| } | |
| #endif |