#include #include #include #include #include #include #include #include #include #define __NR_sched_set_affinity 241 #define __NR_sched_get_affinity 242 int32_t sig_occured = 0; int32_t sig_count = 0; int32_t Sig; int32_t exit_flg = 0; int32_t thread_running = 0; uint32_t pri_mask = 0x01; uint32_t sec_mask = 0x02; sigset_t pri_sset; sigset_t sec_sset; timer_t timerid; pthread_t thread_id; struct itimerspec RTC_value; struct sigevent sig_event; struct sigaction sigaction_block; struct sched_param sparam; void RTC_isr() { sig_occured = 1; } void *thread_code(void *args) { uint64_t nsecs; // // Pin self to a different processor // syscall(__NR_sched_set_affinity, 0, sizeof(sec_mask), &sec_mask); // // Set self to SCHED_FIFO // sparam.sched_priority = 30; pthread_setschedparam(thread_id, SCHED_FIFO, &sparam); Sig = SIGRTMIN; sigaction_block.sa_handler = (__sighandler_t)RTC_isr; sigaction_block.sa_flags = SA_RESTART; if (sigaction(Sig, &sigaction_block, NULL) < 0) { perror("sigaction failed: "); goto out; } sig_event.sigev_signo = Sig; sig_event.sigev_notify = SIGEV_SIGNAL; if (timer_create(CLOCK_MONOTONIC, &sig_event, &timerid) < 0) { perror("timer_create failed: "); goto out; } // // UNBlock signals // sigfillset(&sec_sset); pthread_sigmask(SIG_UNBLOCK, &sec_sset, NULL); // // start the 60 Hz repeating timer running // nsecs = (uint64_t) (1000000000LL / 60); RTC_value.it_value.tv_sec = nsecs / 1000000000LL; RTC_value.it_value.tv_nsec = nsecs % 1000000000LL; RTC_value.it_interval.tv_sec = RTC_value.it_value.tv_sec; RTC_value.it_interval.tv_nsec = RTC_value.it_value.tv_nsec; if (timer_settime(timerid, 0, &RTC_value, NULL) < 0) { perror("timer_settime failed: "); goto out; } thread_running = 1; while (!exit_flg) { if (sig_occured) { sig_occured = 0; sig_count++; }} out: if (timerid) timer_delete(timerid); return (0); } int32_t main(int argc, char **argv) { int32_t i = 0; int32_t sleep_cnt = 0; // // Pin self to a processor // syscall(__NR_sched_set_affinity, 0, sizeof(pri_mask), &pri_mask); // // Set self to SCHED_FIFO // sparam.sched_priority = 35; sched_setscheduler(0, SCHED_FIFO, &sparam); // // Block signals to self // sigfillset(&pri_sset); sigprocmask(SIG_BLOCK, &pri_sset, NULL); pthread_create(&thread_id, NULL, thread_code, NULL); while(!thread_running) usleep(100); while (sleep_cnt < 10) { sleep(1); sleep_cnt++; } exit_flg = 1; pthread_cancel(thread_id); printf("Thread process received %d signals\n", sig_count); exit (0); }