I am working on a console application under Linux. It transmits and receives data streams via special communication hardware (developed here in house). I am recording all data in RAM buffers (the communication links are at GBit/sec speed) printing to log files any anomalies after the transmission.
I have a timer which wakes my program every 100usec do fill / read data to/from DMA buffers.
Here is the problem:
The application works, but from time to time it would crash, just saying "real-time signal 1" on the terminal. This is very annoying and often ruins my test cycles. I am new to signal programming. How do I do this correctly? Do I have to employ some kind of locking within the timer function?
This is my application structure:
Code:
void bar(int sig)
{
}
main() /* well, not really main() but called by main() */
{
siginfo_t info;
timer_t m_id = 0;
int m_signal_control = SIGRTMIN;
int m_signal_timer = SIGRTMIN + 1;
struct sigevent timer_info;
struct itimerspec m_spec;
struct sigaction foo;
sigset_t set;
install_sig_handlers();
sigemptyset(&set);
sigaddset(&set, m_signal_control);
sigaddset(&set, m_signal_timer);
memset(&timer_info, 0, sizeof(timer_info));
timer_info.sigev_notify = SIGEV_SIGNAL;
timer_info.sigev_signo = m_signal_timer;
timer_create(CLOCK_REALTIME, &timer_info, &m_id);
m_spec.it_value.tv_sec = 0;
m_spec.it_value.tv_nsec = app_loop * 1000;
m_spec.it_interval.tv_sec = m_spec.it_value.tv_sec;
m_spec.it_interval.tv_nsec = m_spec.it_value.tv_nsec;
/* intialize other stuff */
timer_settime(m_id, 0, &m_spec, NULL );
foo.sa_handler = bar;
sigemptyset(&foo.sa_mask);
sigaction(m_signal_timer, &foo, NULL );
while (!terminate)
{
sigwaitinfo(&set, &info);
/* do stuff */
}
sigwaitinfo (&set, &info);
timer_delete(m_id);
/* output results */
}
This is the "sig_handler.c" module
Code:
/* set from a signal handler registered to the INT/QUIT/HUP signals */
volatile int terminate = 0;
/* set from a signal handler registered to the CHDL signal */
volatile int terminate_child = 0;
/* Signal handler for the QUIT/HUP/INT signals */
static void terminate_sig_handler(const int sig)
{
terminate = 1;
terminate_child = 1;
}
/* Signal handler for the CHLD signal */
static void child_sig_handler(const int sig)
{
terminate_child = 1;
}
/* Install the INT/HUP/QUIT and CHDL signal handlers. */
void install_sig_handlers(void)
{
/* register signal handlers from INT/HUP/QUIT */
signal(SIGINT, terminate_sig_handler);
signal(SIGHUP, terminate_sig_handler);
signal(SIGQUIT, terminate_sig_handler);
signal(SIGTERM, terminate_sig_handler);
signal(SIGPIPE, child_sig_handler);
signal(SIGCHLD, child_sig_handler);
}
Interface to "sig_handler.c":
Code:
#ifndef __SIG_HANDLER_H_
#define __SIG_HANDLER_H_
/* set from a signal handler registered to the INT/QUIT/HUP signals */
extern volatile int terminate;
/* set from a signal handler registered to the CHDL signal */
extern volatile int terminate_child;
void install_sig_handlers ();
#endif
I am not the originator of this code, so there are some uncertainties about details ...
Any help is appreciated - tank you!!
Johannes