native: Handle gracefully SIGTERM and SIGINT
When SIGTERM or SIGINT are received handle them by gracefully exiting the program. Fixes #5477 Signed-off-by: Alberto Escolar Piedras <alpi@oticon.com>
This commit is contained in:
parent
36e2efaf91
commit
e04764dbc7
|
@ -20,7 +20,7 @@ zephyr_link_libraries_ifdef(CONFIG_COVERAGE
|
|||
-lgcov
|
||||
)
|
||||
|
||||
zephyr_compile_definitions(_POSIX_C_SOURCE=199309)
|
||||
zephyr_compile_definitions(_POSIX_C_SOURCE=200809)
|
||||
|
||||
zephyr_ld_options(
|
||||
-ldl
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* Barebones HW model sufficient to run some of the sample apps
|
||||
* Bare-bones HW model sufficient to run some of the sample apps
|
||||
* and regression tests
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include "hw_models_top.h"
|
||||
#include "timer_model.h"
|
||||
#include "irq_ctrl.h"
|
||||
|
@ -33,6 +36,56 @@ static u64_t *Timer_list[NUMBER_OF_TIMERS] = {
|
|||
|
||||
static u64_t next_timer_time;
|
||||
|
||||
/* Have we received a SIGTERM or SIGINT */
|
||||
static volatile sig_atomic_t signaled_end;
|
||||
|
||||
|
||||
/**
|
||||
* Handler for SIGTERM and SIGINT
|
||||
*/
|
||||
void hwm_signal_end_handler(int sig)
|
||||
{
|
||||
signaled_end = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the handler for SIGTERM and SIGINT which will cause the
|
||||
* program to exit gracefully when they are received the 1st time
|
||||
*
|
||||
* Note that our handler only sets a variable indicating the signal was
|
||||
* received, and in each iteration of the hw main loop this variable is
|
||||
* evaluated.
|
||||
* If for some reason (the program is stuck) we never evaluate it, the program
|
||||
* would never exit.
|
||||
* Therefore we set SA_RESETHAND: This way, the 2nd time the signal is received
|
||||
* the default handler would be called to terminate the program no matter what.
|
||||
*
|
||||
* Note that SA_RESETHAND requires either _POSIX_C_SOURCE>=200809 or
|
||||
* _XOPEN_SOURCE>=500
|
||||
*/
|
||||
void hwm_set_sig_handler(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
int e;
|
||||
|
||||
act.sa_handler = hwm_signal_end_handler;
|
||||
e = sigemptyset(&act.sa_mask);
|
||||
if (e) {
|
||||
posix_print_error_and_exit("Error on sigemptyset()\n");
|
||||
}
|
||||
|
||||
act.sa_flags = SA_RESETHAND;
|
||||
|
||||
e = sigaction(SIGTERM, &act, NULL);
|
||||
if (e) {
|
||||
posix_print_error_and_exit("Error on sigaction()\n");
|
||||
}
|
||||
e = sigaction(SIGINT, &act, NULL);
|
||||
if (e) {
|
||||
posix_print_error_and_exit("Error on sigaction()\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void hwm_sleep_until_next_timer(void)
|
||||
{
|
||||
|
@ -46,9 +99,9 @@ static void hwm_sleep_until_next_timer(void)
|
|||
next_timer_index);
|
||||
}
|
||||
|
||||
if (device_time >= end_of_time) {
|
||||
posix_print_trace("\n\n\n\n\n\nAutostopped after %.3Lfs\n",
|
||||
((long double)end_of_time)/1.0e6);
|
||||
if (signaled_end || (device_time >= end_of_time)) {
|
||||
posix_print_trace("\nStopped after %.3Lfs\n",
|
||||
((long double)device_time)/1.0e6);
|
||||
|
||||
main_clean_up(0);
|
||||
}
|
||||
|
@ -120,6 +173,7 @@ u64_t hwm_get_time(void)
|
|||
*/
|
||||
void hwm_init(void)
|
||||
{
|
||||
hwm_set_sig_handler();
|
||||
hwtimer_init();
|
||||
hw_irq_ctrl_init();
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/*
|
||||
* The basic principle of operation is:
|
||||
* No asynchronous behavior, no undeterminism.
|
||||
* No asynchronous behavior, no indeterminism.
|
||||
* If you run the same thing 20 times, you get exactly the same result 20
|
||||
* times.
|
||||
* It does not matter if you are running from console, or in a debugger
|
||||
|
@ -15,7 +15,7 @@
|
|||
* This is achieved as follows:
|
||||
* The HW models run in their own simulated time. We do really not attempt
|
||||
* to link ourselves to the actual real time / wall time of the machine as this
|
||||
* would make execution undeterministic and debugging or instrumentation not
|
||||
* would make execution indeterministic and debugging or instrumentation not
|
||||
* really possible. Although we may slow the run to real time.
|
||||
*/
|
||||
|
||||
|
@ -42,12 +42,13 @@ void main_clean_up(int exit_code)
|
|||
exit(exit_code);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the actual main for the Linux process,
|
||||
* the Zephyr application main is renamed something else thru a define.
|
||||
*
|
||||
* Note that normally one wants to use this POSIX arch to be part of a
|
||||
* simulation engine, with some proper HW models and whatnot
|
||||
* simulation engine, with some proper HW models and what not
|
||||
*
|
||||
* This is just a very simple demo which is able to run some of the sample
|
||||
* apps (hello world, synchronization, philosophers) and run the sanity-check
|
||||
|
|
|
@ -76,11 +76,7 @@ static void hwtimer_tick_timer_reached(void)
|
|||
requested_time.tv_sec = diff / 1e6;
|
||||
requested_time.tv_nsec = (diff - requested_time.tv_sec*1e6)*1e3;
|
||||
|
||||
int s = nanosleep(&requested_time, &remaining);
|
||||
|
||||
if (s == -1) {
|
||||
posix_print_trace("Interrupted or error\n");
|
||||
}
|
||||
nanosleep(&requested_time, &remaining);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue