diff --git a/core/src/plc_app/plc_state_manager.c b/core/src/plc_app/plc_state_manager.c index d43b4837..3982be6a 100644 --- a/core/src/plc_app/plc_state_manager.c +++ b/core/src/plc_app/plc_state_manager.c @@ -23,8 +23,9 @@ void *plc_cycle_thread(void *arg) { PluginManager *pm = (PluginManager *)arg; - // Initialize PLC + // Initialize PLC with real-time optimizations set_realtime_priority(); + lock_memory(); symbols_init(pm); ext_config_init__(); ext_glueVars(); diff --git a/core/src/plc_app/utils/utils.c b/core/src/plc_app/utils/utils.c index 9ea41d69..d01586cc 100644 --- a/core/src/plc_app/utils/utils.c +++ b/core/src/plc_app/utils/utils.c @@ -2,6 +2,7 @@ #include #include #include +#include #include unsigned long long *ext_common_ticktime__ = NULL; @@ -55,6 +56,19 @@ void set_realtime_priority(void) } } +// Lock all memory pages to prevent page faults during PLC execution +void lock_memory(void) +{ + if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) + { + log_error("mlockall failed: %s", strerror(errno)); + } + else + { + log_info("Memory locked successfully (MCL_CURRENT | MCL_FUTURE)"); + } +} + size_t parse_hex_string(const char *hex_string, uint8_t *data) { size_t count = 0; diff --git a/core/src/plc_app/utils/utils.h b/core/src/plc_app/utils/utils.h index 5e04384a..c3c8e88a 100644 --- a/core/src/plc_app/utils/utils.h +++ b/core/src/plc_app/utils/utils.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -42,6 +43,14 @@ void timespec_diff(struct timespec *a, struct timespec *b, */ void set_realtime_priority(void); +/** + * @brief Lock all current and future memory pages to prevent page faults + * + * This prevents the kernel from swapping out memory pages during PLC execution, + * which could cause unpredictable latency spikes in the scan cycle. + */ +void lock_memory(void); + /** * @brief Parse a hex string into a byte array *