]> rtime.felk.cvut.cz Git - ert_linux.git/blobdiff - ert_linux/ert_linux_main.tlc
Include SIGINT handler to properly stop model when aborted by CTRL+C.
[ert_linux.git] / ert_linux / ert_linux_main.tlc
index 1b70a0d1c5e9125ebf3431c855ec55c992577f6e..30943c29281a07efef2698a2d95563f2b945c2a5 100644 (file)
   #include <semaphore.h>                 /* Semaphores library header file */
   #include <time.h>
   #include <stdlib.h>
+  #include <stdbool.h>
   #include <unistd.h>
   #include <sys/mman.h>                  /* For mlockall() */
+  #include <signal.h>
   #include "%<modelName>.h"              /* Model's header file */
   #include "rtwtypes.h"                  /* MathWorks types */
   %if extMode == 1
     #include "ext_work.h"                  /* External mode header file */
   %endif
 
+  #ifndef TRUE
+  #define TRUE true
+  #define FALSE false
+  #endif
+
   /*==================*
    * Required defines *
    *==================*/
        %<modelName>_step%<i>();
        sem_wait(&sub_rate[%<i>].sem);    /* sem_val = 0 */
       }
+      return NULL;
     }
   %endforeach
 %endfunction
    * This is the thread function of the base rate loop.
    * Fundamental sample time = %<fundamentalStepSize>s
    */
-  void * base_rate()
+  void * base_rate(void *param_unused)
   {
     %assign  sec = FEVAL("uint32", fundamentalStepSize)
     %assign nsec = FEVAL("uint32", (fundamentalStepSize - FEVAL("floor", fundamentalStepSize))*1000000000)
     int step_sem_value;
     int_T i;
 
+    (void)param_unused;
+
     %if extMode == 1
       %<SLibGenERTExtModeInit()>
       CHECKE(sem_post(&ext_mode_ready));
       sem_post(&sub_rate[i].sem);
       sem_post(&sub_rate[i].sem);
     }
+    return NULL;
+  }
+
+  /**
+   * Signal handler for ABORT during simulation
+   */
+  void abort_signal_handler(int sig) {
+    fprintf(stderr, "Simulation aborted by pressing CTRL+C\n");
+    rtmSetStopRequested(%<modelName>_M, 1);
   }
 
   /**
       (void *)(argv);
     %endif
 
-    CHECKE(mlockall(MCL_FUTURE));
+    CHECKE(mlockall(MCL_CURRENT | MCL_FUTURE));
 
     /* Initialize model */
     %<modelName>_initialize();
     %if extMode == 1
       /* External mode */
       CHECKE(sem_wait(&ext_mode_ready));
+
+      signal(SIGINT, abort_signal_handler); /* important for letting the destructor be called. */
+
       while(rtmGetErrorStatus(%<modelName>_M) == NULL && !rtmGetStopRequested(%<modelName>_M)) {
         rtExtModeOneStep(rtmGetRTWExtModeInfo(RT_MDL), NUMST, (boolean_T *)&rtmGetStopRequested(RT_MDL));
        usleep(%<FEVAL("uint32", fundamentalStepSize * 1000000)>);