diff --git a/Makefile b/Makefile index d900bb21a9..a20c48fa17 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,8 @@ else AR = gcc-ar endif endif + + ALPINE=$(wildcard /etc/alpine-release) endif ifeq ($(UNAME_S),Darwin) @@ -396,9 +398,14 @@ endif # target specific build options libponyrt.buildoptions = -DPONY_NO_ASSERT +libponyrt-pic.buildoptions = -DPONY_NO_ASSERT libponyrt.tests.linkoptions += -rdynamic +ifneq ($(ALPINE),) + libponyrt.tests.linkoptions += -lexecinfo +endif + libponyc.buildoptions = -D__STDC_CONSTANT_MACROS libponyc.buildoptions += -D__STDC_FORMAT_MACROS libponyc.buildoptions += -D__STDC_LIMIT_MACROS @@ -410,16 +417,29 @@ libponyc.tests.buildoptions += -DPONY_PACKAGES_DIR=\"$(packages_abs_src)\" libponyc.tests.linkoptions += -rdynamic +ifneq ($(ALPINE),) + libponyc.tests.linkoptions += -lexecinfo +endif + libponyc.benchmarks.buildoptions = -D__STDC_CONSTANT_MACROS libponyc.benchmarks.buildoptions += -D__STDC_FORMAT_MACROS libponyc.benchmarks.buildoptions += -D__STDC_LIMIT_MACROS libgbenchmark.buildoptions := -DHAVE_POSIX_REGEX +ifneq ($(ALPINE),) + libponyc.benchmarks.linkoptions += -lexecinfo + libponyrt.benchmarks.linkoptions += -lexecinfo +endif + ponyc.buildoptions = $(libponyc.buildoptions) ponyc.linkoptions += -rdynamic +ifneq ($(ALPINE),) + ponyc.linkoptions += -lexecinfo +endif + ifeq ($(OSTYPE), linux) libponyrt-pic.buildoptions += -fpic endif diff --git a/src/common/platform.h b/src/common/platform.h index 164945960c..0a2d9d76f7 100644 --- a/src/common/platform.h +++ b/src/common/platform.h @@ -1,6 +1,12 @@ #ifndef PLATFORM_H #define PLATFORM_H +#ifdef __linux__ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#endif + #include #include diff --git a/src/common/pony/detail/atomics.h b/src/common/pony/detail/atomics.h index 764db96c81..149f6a9e5e 100644 --- a/src/common/pony/detail/atomics.h +++ b/src/common/pony/detail/atomics.h @@ -36,7 +36,7 @@ using std::atomic_thread_fence; # endif #elif defined(__GNUC__) && !defined(__clang__) # include -# if __GNUC_PREREQ(4, 9) +# if ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((4) << 16) + (9)) # ifdef __cplusplus // g++ doesn't like C11 atomics. We never need atomic ops in C++ files so // we only define the atomic types. @@ -50,7 +50,7 @@ using std::atomic_thread_fence; # define PONY_ATOMIC(T) T _Atomic # define PONY_ATOMIC_RVALUE(T) T _Atomic # endif -# elif __GNUC_PREREQ(4, 7) +# elif ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((4) << 16) + (7)) # define PONY_ATOMIC(T) alignas(sizeof(T)) T # define PONY_ATOMIC_RVALUE(T) T # define PONY_ATOMIC_BUILTINS diff --git a/src/common/ponyassert.h b/src/common/ponyassert.h index 80a0d8ec2b..f8fcb324ec 100644 --- a/src/common/ponyassert.h +++ b/src/common/ponyassert.h @@ -2,11 +2,12 @@ #define PLATFORM_PONYASSERT_H #include "platform.h" +#include PONY_EXTERN_C_BEGIN -#if defined(NDEBUG) && defined(PONY_NO_ASSERT) -# define pony_assert(expr) ((void)0) +#if defined(PONY_NO_ASSERT) +# define pony_assert(expr) assert(expr) #else # define pony_assert(expr) \ ((expr) ? (void)0 : \ diff --git a/src/libponyc/codegen/genexe.c b/src/libponyc/codegen/genexe.c index d82d6fcde9..0028b6ad9f 100644 --- a/src/libponyc/codegen/genexe.c +++ b/src/libponyc/codegen/genexe.c @@ -261,6 +261,7 @@ static bool link_exe(compile_t* c, ast_t* program, "Warning: environment variable $CC undefined, using %s as the linker\n", PONY_COMPILER); } + const char* mcx16_arg = target_is_ilp32(c->opt->triple) ? "" : "-mcx16"; const char* fuseld = target_is_linux(c->opt->triple) ? "-fuse-ld=gold" : ""; const char* ldl = target_is_linux(c->opt->triple) ? "-ldl" : ""; diff --git a/src/libponyrt/asio/asio.c b/src/libponyrt/asio/asio.c index 36fb19cd48..79f29ca8c6 100644 --- a/src/libponyrt/asio/asio.c +++ b/src/libponyrt/asio/asio.c @@ -33,6 +33,11 @@ asio_backend_t* ponyint_asio_get_backend() return running_base.backend; } +uint32_t ponyint_asio_get_cpu() +{ + return asio_cpu; +} + void ponyint_asio_init(uint32_t cpu) { asio_cpu = cpu; diff --git a/src/libponyrt/asio/asio.h b/src/libponyrt/asio/asio.h index 618a9759f5..36cd173512 100644 --- a/src/libponyrt/asio/asio.h +++ b/src/libponyrt/asio/asio.h @@ -68,6 +68,11 @@ bool ponyint_asio_start(); */ asio_backend_t* ponyint_asio_get_backend(); +/** Returns the cpu assigned for the ASIO thread. + * + */ +uint32_t ponyint_asio_get_cpu(); + /** Attempts to stop an asynchronous event mechanism. * * Stopping an event mechanism is only possible if there are no pending "noisy" diff --git a/src/libponyrt/asio/epoll.c b/src/libponyrt/asio/epoll.c index 8443e79a28..17b6612b80 100644 --- a/src/libponyrt/asio/epoll.c +++ b/src/libponyrt/asio/epoll.c @@ -6,6 +6,7 @@ #include "../actor/messageq.h" #include "../mem/pool.h" +#include "../sched/cpu.h" #include #include #include @@ -163,6 +164,7 @@ PONY_API void pony_asio_event_resubscribe_read(asio_event_t* ev) DECLARE_THREAD_FN(ponyint_asio_backend_dispatch) { + ponyint_cpu_affinity(ponyint_asio_get_cpu()); pony_register_thread(); asio_backend_t* b = arg; diff --git a/src/libponyrt/asio/iocp.c b/src/libponyrt/asio/iocp.c index f5672da875..7e36630a2d 100644 --- a/src/libponyrt/asio/iocp.c +++ b/src/libponyrt/asio/iocp.c @@ -7,6 +7,7 @@ #include "../actor/messageq.h" #include "../mem/pool.h" +#include "../sched/cpu.h" #include #include #include @@ -101,6 +102,7 @@ void ponyint_asio_backend_final(asio_backend_t* b) DECLARE_THREAD_FN(ponyint_asio_backend_dispatch) { + ponyint_cpu_affinity(ponyint_asio_get_cpu()); pony_register_thread(); asio_backend_t* b = (asio_backend_t*)arg; asio_event_t* stdin_event = NULL; diff --git a/src/libponyrt/asio/kqueue.c b/src/libponyrt/asio/kqueue.c index 794ee26f69..8c9206e944 100644 --- a/src/libponyrt/asio/kqueue.c +++ b/src/libponyrt/asio/kqueue.c @@ -4,6 +4,7 @@ #include "../actor/messageq.h" #include "../mem/pool.h" +#include "../sched/cpu.h" #include "ponyassert.h" #include #include @@ -120,6 +121,7 @@ PONY_API void pony_asio_event_resubscribe_write(asio_event_t* ev) DECLARE_THREAD_FN(ponyint_asio_backend_dispatch) { + ponyint_cpu_affinity(ponyint_asio_get_cpu()); pony_register_thread(); asio_backend_t* b = arg; struct kevent fired[MAX_EVENTS]; diff --git a/src/libponyrt/platform/threads.c b/src/libponyrt/platform/threads.c index 5b8e1a980f..e23d990791 100644 --- a/src/libponyrt/platform/threads.c +++ b/src/libponyrt/platform/threads.c @@ -176,8 +176,6 @@ bool ponyint_thread_create(pony_thread_id_t* thread, thread_fn start, CPU_ZERO(&set); CPU_SET(cpu, &set); - pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &set); - if(use_numa) { struct rlimit limit; diff --git a/src/libponyrt/sched/cpu.c b/src/libponyrt/sched/cpu.c index d9e897c0ae..df6f28af87 100644 --- a/src/libponyrt/sched/cpu.c +++ b/src/libponyrt/sched/cpu.c @@ -256,7 +256,11 @@ void ponyint_cpu_affinity(uint32_t cpu) return; #if defined(PLATFORM_IS_LINUX) - // Affinity is handled when spawning the thread. + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(cpu, &set); + + sched_setaffinity(0, sizeof(cpu_set_t), &set); #elif defined(PLATFORM_IS_FREEBSD) // No pinning, since we cannot yet determine hyperthreads vs physical cores. #elif defined(PLATFORM_IS_MACOSX) diff --git a/src/libponyrt/sched/scheduler.c b/src/libponyrt/sched/scheduler.c index f46bfbf2fd..917520b54a 100644 --- a/src/libponyrt/sched/scheduler.c +++ b/src/libponyrt/sched/scheduler.c @@ -12,7 +12,7 @@ #include #include -#define SCHED_BATCH 100 +#define PONY_SCHED_BATCH 100 static DECLARE_THREAD_FN(run_thread); @@ -284,7 +284,7 @@ static void run(scheduler_t* sched) } // Run the current actor and get the next actor. - bool reschedule = ponyint_actor_run(&sched->ctx, actor, SCHED_BATCH); + bool reschedule = ponyint_actor_run(&sched->ctx, actor, PONY_SCHED_BATCH); pony_actor_t* next = pop_global(sched); if(reschedule) @@ -370,6 +370,7 @@ static void ponyint_sched_shutdown() pony_ctx_t* ponyint_sched_init(uint32_t threads, bool noyield, bool nopin, bool pinasio) { + this_scheduler = NULL; pony_register_thread(); this_scheduler->ctx.current = NULL;