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:
Alberto Escolar Piedras 2017-12-30 15:20:08 +01:00 committed by Anas Nashif
parent 36e2efaf91
commit e04764dbc7
4 changed files with 64 additions and 13 deletions

View file

@ -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

View file

@ -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();

View file

@ -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

View file

@ -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