Я пытаюсь интегрировать следующий фрагмент кода в более крупную программу (которой, к сожалению, я не могу поделиться), которая работает в системе ARM‹-> DSP:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
timer_t timerid;
int i = 0;
int sec = 0;
volatile int keep_going = 1;
clock_t curr_time = 0, t_old = 0;
static void handler(int sig)
{
curr_time = clock();
if ((curr_time - t_old)/CLOCKS_PER_SEC >= 10.)
keep_going = 0;
}
int main(int argc, char *argv[])
{
struct sigevent sev;
struct itimerspec its;
long long freq_nanosecs;
sigset_t mask;
struct sigaction sa;
memset(&sa, 0, sizeof sa);
// Timer settings
printf("Establishing handler for signal %d\n", SIG);
sa.sa_flags = SA_SIGINFO;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sigaction(SIG, &sa, NULL);
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIG;
sev.sigev_value.sival_ptr = &timerid;
timer_create(CLOCKID, &sev, &timerid);
/* Start the timer */
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 1000;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
timer_settime(timerid, 0, &its, NULL);
t_old = clock();
while(keep_going);
printf("%f sec passed..\n", (double)(curr_time - t_old)/CLOCKS_PER_SEC);
exit(EXIT_SUCCESS);
}
Как видите, это очень простой код, и при его отдельном запуске в системе он отлично работает. Цикл while предназначен только для демонстрации и может быть проигнорирован. Шаги обработчика и инициализации одинаковы.
Проблемы начались, когда я попытался интегрировать его с более крупной программой. Внезапно я получаю ошибку сегментации, если устанавливаю интервал таймера менее 10 мс.
Я попытался сократить операции в обработчике до простой строки 'curr_time = 0', думая, что это может иметь какое-то отношение к операциям с плавающей запятой в обработчике, но это не помогло.
Следует отметить, что я использую API выделения непрерывной памяти для буферов разделяемой памяти ARM‹->DSP, хотя я сомневаюсь, что это как-то связано с этим, поскольку я не выделяю новую память в обработчике.
Итак, кто-нибудь знает о возможных причинах ошибки сегментации?
clock()
не является асинхронным. Кроме того, переменная, изменяемая в обработчике сигналов (keep_going
), должна быть атомарной или иметь типvolatile sig_atomic_t
. - person EOF   schedule 23.08.2015man sigaction: [...]If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of sa_handler) specifies the signal-handling function for signum. This function receives the signal number as its first argument, a pointer to a siginfo_t as its second argument and a pointer to a ucontext_t (cast to void *) as its third argument.[...]
. - person EOF   schedule 23.08.2015