Runtime: Fix bugs in Linux target.
authorEdouard Tisserant
Fri, 17 Feb 2023 11:41:58 +0100
changeset 3727 265fc8001d0a
parent 3726 516779f11803
child 3728 743a384f1bbb
child 3731 549763a28934
Runtime: Fix bugs in Linux target.

- next occurence absolute time computation failing on 32-bit because of casting
- PLC thread was started before period was set, potentially passing uninitialized timespec to clock_nanosleep()
targets/Linux/plc_Linux_main.c
--- a/targets/Linux/plc_Linux_main.c	Thu Feb 16 12:13:16 2023 +0100
+++ b/targets/Linux/plc_Linux_main.c	Fri Feb 17 11:41:58 2023 +0100
@@ -44,12 +44,12 @@
 
 static void inc_timespec(struct timespec *ts, unsigned long long value_ns)
 {
+    long long next_ns = ((long long) ts->tv_sec * 1000000000) + ts->tv_nsec + value_ns;
 #ifdef __lldiv_t_defined
-    lldiv_t next_div = lldiv(ts->tv_sec * 1000000000 + ts->tv_nsec + value_ns, 1000000000);
+    lldiv_t next_div = lldiv(next_ns, 1000000000);
     ts->tv_sec = next_div.quot;
     ts->tv_nsec = next_div.rem;
 #else
-    long long next_ns = ts->tv_sec * 1000000000 + ts->tv_nsec + value_ns;
     ts->tv_sec = next_ns / 1000000000;
     ts->tv_nsec = next_ns % 1000000000;
 #endif
@@ -66,7 +66,7 @@
     // interrupt clock_nanpsleep
     pthread_kill(PLC_thread, SIGUSR1);
 }
-//
+
 void catch_signal(int sig)
 {
 //  signal(SIGTERM, catch_signal);
@@ -91,8 +91,13 @@
         // Sleep until next PLC run
         // TODO check result of clock_nanosleep and wait again or exit eventually
         int res = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_abs_time, NULL);
-        if(res==EINTR) continue;
-        if(res!=0) return;
+        if(res==EINTR){
+            continue;
+        }
+        if(res!=0){
+            printf("PLC thread died with error %d \n", res);
+            return;
+        }
         PLC_GetTime(&__CURRENT_TIME);
         __run();
         inc_timespec(&next_abs_time, period_ns);
@@ -107,8 +112,6 @@
 
     PLC_shutdown = 0;
 
-    pthread_create(&PLC_thread, NULL, (void*) &PLC_thread_proc, NULL);
-
     pthread_mutex_init(&debug_wait_mutex, NULL);
     pthread_mutex_init(&debug_mutex, NULL);
     pthread_mutex_init(&python_wait_mutex, NULL);
@@ -126,7 +129,11 @@
         /* install signal handler for manual break */
         signal(SIGINT, catch_signal);
 
-        PLC_SetTimer(common_ticktime__,common_ticktime__);
+        /* initialize next occurence and period */
+        period_ns = common_ticktime__;
+        clock_gettime(CLOCK_MONOTONIC, &next_abs_time);
+
+        pthread_create(&PLC_thread, NULL, (void*) &PLC_thread_proc, NULL);
     }else{
         return 1;
     }