diff --git a/core/src/drivers/plugins/native/ethercat/CMakeLists.txt b/core/src/drivers/plugins/native/ethercat/CMakeLists.txt index 40e5d57..5126f2b 100644 --- a/core/src/drivers/plugins/native/ethercat/CMakeLists.txt +++ b/core/src/drivers/plugins/native/ethercat/CMakeLists.txt @@ -60,8 +60,21 @@ target_compile_options(soem PUBLIC\n\ # HAVE_U_INT*_T tells bundled bittypes.h to skip its typedefs --\n\ # MSYS2 POSIX headers (sys/types.h) already provide these types and\n\ # use different underlying types on LP64 (long vs long long for 64-bit).\n\ +#\n\ +# __USE_W32_SOCKETS tells MSYS2 / Cygwin's POSIX headers\n\ +# (\`sys/select.h\`, \`sys/unistd.h\`) NOT to declare their own \`select\`\n\ +# and \`gethostname\` — the Win32 \`winsock2.h\` declarations (which the\n\ +# bundled wpcap headers pull in transitively) are the ones we want\n\ +# to use. Without this, any TU that includes both a POSIX header\n\ +# (e.g. \`\` in ethercat_plugin.c, which transitively pulls\n\ +# in sys/select.h) AND a SOEM/wpcap header (which pulls in\n\ +# winsock2.h) gets a redeclaration error because the two libcs\n\ +# disagree on the signature ( \`struct timeval *\` vs \`const TIMEVAL *\`,\n\ +# \`size_t\` vs \`int\`). Marking the macro PUBLIC propagates it to\n\ +# every target linking against soem (notably ethercat_plugin).\n\ target_compile_definitions(soem PUBLIC\n\ WIN32\n\ + __USE_W32_SOCKETS\n\ HAVE_U_INT8_T\n\ HAVE_U_INT16_T\n\ HAVE_U_INT32_T\n\ diff --git a/core/src/plc_app/image_tables.cpp b/core/src/plc_app/image_tables.cpp index de41933..d2805d8 100644 --- a/core/src/plc_app/image_tables.cpp +++ b/core/src/plc_app/image_tables.cpp @@ -93,7 +93,16 @@ namespace { { pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr) != 0) return -1; + // Priority inheritance is a POSIX optional feature. MSYS2/Cygwin + // pthread on Windows doesn't ship it (PTHREAD_PRIO_INHERIT is + // undefined, pthread_mutexattr_setprotocol is unavailable). + // Windows has no real-time scheduling anyway, so the PI protocol + // would be a no-op even if it linked — fall back to a plain + // recursive mutex. +#if !defined(__CYGWIN__) && !defined(__MSYS__) && \ + defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); +#endif pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); int rc = pthread_mutex_init(m, &attr); pthread_mutexattr_destroy(&attr); diff --git a/core/src/plc_app/plc_state_manager.cpp b/core/src/plc_app/plc_state_manager.cpp index fce8eb3..c77116a 100644 --- a/core/src/plc_app/plc_state_manager.cpp +++ b/core/src/plc_app/plc_state_manager.cpp @@ -140,6 +140,13 @@ static void *plc_task_thread(void *arg) if (ctx->cpu_affinity_mask != 0) { + // CPU affinity uses `cpu_set_t` / `CPU_ZERO` / `CPU_SETSIZE` / + // `pthread_setaffinity_np` — all Linux extensions to ``, + // not present on MSYS2/Cygwin/Windows. Skip silently when + // building for a non-Linux host: Windows doesn't expose + // SCHED_FIFO either, so any "pin to CPU" guarantee would already + // be unachievable there. +#if !defined(__CYGWIN__) && !defined(__MSYS__) && defined(__linux__) cpu_set_t cs; CPU_ZERO(&cs); for (int cpu = 0; cpu < 64 && cpu < CPU_SETSIZE; ++cpu) @@ -151,6 +158,10 @@ static void *plc_task_thread(void *arg) log_warn("[task %s] pthread_setaffinity_np failed: %s", ctx->name, strerror(errno)); } +#else + log_info("[task %s] CPU affinity requested but unsupported on this platform", + ctx->name); +#endif } if (sigsetjmp(ctx->crash_jmp, 1) != 0)