#if defined(LIBCO_C) /*[amd64, arm, ppc, x86]: by default, co_swap_function is marked as a text (code) section if not supported, uncomment the below line to use mprotect instead */ /* #define LIBCO_MPROTECT */ /*[amd64]: Win64 only: provides a substantial speed-up, but will thrash XMM regs do not use this unless you are certain your application won't use SSE */ /* #define LIBCO_NO_SSE */ #if !defined(thread_local) /* User can override thread_local for obscure compilers */ #if !defined(LIBCO_MP) /* Running in single-threaded environment */ #define thread_local #else /* Running in multi-threaded environment */ #if defined(__STDC__) /* Compiling as C Language */ #if defined(_MSC_VER) /* Don't rely on MSVC's C11 support */ #define thread_local __declspec(thread) #elif __STDC_VERSION__ < 201112L /* If we are on C90/99 */ #if defined(__clang__) || defined(__GNUC__) /* Clang and GCC */ #define thread_local __thread #else /* Otherwise, we ignore the directive (unless user provides their own) */ #define thread_local #endif #else /* C11 and newer define thread_local in threads.h */ #include #endif #elif defined(__cplusplus) /* Compiling as C++ Language */ #if __cplusplus < 201103L /* thread_local is a C++11 feature */ #if defined(_MSC_VER) #define thread_local __declspec(thread) #elif defined(__clang__) || defined(__GNUC__) #define thread_local __thread #else /* Otherwise, we ignore the directive (unless user provides their own) */ #define thread_local #endif #else /* In C++ >= 11, thread_local in a builtin keyword */ /* Don't do anything */ #endif #endif #endif #endif /* In alignas(a), 'a' should be a power of two that is at least the type's alignment and at most the implementation's alignment limit. This limit is 2**13 on MSVC. To be portable to MSVC through at least version 10.0, 'a' should be an integer constant, as MSVC does not support expressions such as 1 << 3. The following C11 requirements are NOT supported on MSVC: - If 'a' is zero, alignas has no effect. - alignas can be used multiple times; the strictest one wins. - alignas (TYPE) is equivalent to alignas (alignof (TYPE)). */ #if !defined(alignas) #if defined(__STDC__) /* C Language */ #if defined(_MSC_VER) /* Don't rely on MSVC's C11 support */ #define alignas(bytes) __declspec(align(bytes)) #elif __STDC_VERSION__ >= 201112L /* C11 and above */ #include #elif defined(__clang__) || defined(__GNUC__) /* C90/99 on Clang/GCC */ #define alignas(bytes) __attribute__ ((aligned (bytes))) #else /* Otherwise, we ignore the directive (user should provide their own) */ #define alignas(bytes) #endif #elif defined(__cplusplus) /* C++ Language */ #if __cplusplus < 201103L #if defined(_MSC_VER) #define alignas(bytes) __declspec(align(bytes)) #elif defined(__clang__) || defined(__GNUC__) /* C++98/03 on Clang/GCC */ #define alignas(bytes) __attribute__ ((aligned (bytes))) #else /* Otherwise, we ignore the directive (unless user provides their own) */ #define alignas(bytes) #endif #else /* C++ >= 11 has alignas keyword */ /* Do nothing */ #endif #endif /* = !defined(__STDC_VERSION__) && !defined(__cplusplus) */ #endif #if !defined(LIBCO_ASSERT) #include #define LIBCO_ASSERT assert #endif #if defined (__OpenBSD__) #if !defined(LIBCO_MALLOC) || !defined(LIBCO_FREE) #include #include static void* malloc_obsd(size_t size) { long pagesize = sysconf(_SC_PAGESIZE); char* memory = (char*)mmap(NULL, size + pagesize, PROT_READ|PROT_WRITE, MAP_STACK|MAP_PRIVATE|MAP_ANON, -1, 0); if (memory == MAP_FAILED) return NULL; *(size_t*)memory = size + pagesize; memory += pagesize; return (void*)memory; } static void free_obsd(void *ptr) { char* memory = (char*)ptr - sysconf(_SC_PAGESIZE); munmap(memory, *(size_t*)memory); } #define LIBCO_MALLOC malloc_obsd #define LIBCO_FREE free_obsd #endif #endif #if !defined(LIBCO_MALLOC) || !defined(LIBCO_FREE) #include #define LIBCO_MALLOC malloc #define LIBCO_FREE free #endif #if defined(_MSC_VER) #define section(name) __declspec(allocate("." #name)) #elif defined(__APPLE__) #define section(name) __attribute__((section("__TEXT,__" #name))) #elif defined(__SWITCH__) /* This is basically the same as the last case, however the "#" suffix will create a secondary .text section. Because of that, the toolchain will treat the section as non-executable. This might be related to the linker scripts used for libnx homebrew. The reason that this is a seperate ifdef, is purely to silence a cosmetic warn about ignoring the +w attribute on .text which would happen on other platforms under some conditions (said warning is by design when data is being merged like this into .text). */ #define section(name) __attribute__((section("." #name))) #else #define section(name) __attribute__((section("." #name "#"))) #endif /* if defined(LIBCO_C) */ #endif