On 04/11/2018 03:54 PM, Mauro Salvini wrote:
> Hi,
> 
> I'm facing an unexpected behavior of rt_task_wait_period().
> 
> xenomai: 3.0.3
> ipipe: 4.1.18-arm-9 on kernel 4.1.36 from NXP
> arch: ARM
> SOC: iMX6sx
> 
> Running simple attached program (compiled and linked using "xeno-config 
> --alchemy --cflags" and "xeno-config --alchemy --ldflags"),
> rt_task_wait_period() never returns (instead return -EWOULDBLOCK) if
> rt_task_set_period() not called.
> 
> Output with SET_PERIOD defined:
> Main 0
> WAIT PERIOD DONE!
> WAIT PERIOD DONE!
> Main 2
> WAIT PERIOD DONE!
> WAIT PERIOD DONE!
> Main 4
> WAIT PERIOD DONE!
> WAIT PERIOD DONE!
> Main 6
> ...
> 
> Output with SET_PERIOD not defined:
> Main 0
> Main 0
> Main 0
> Main 0
> Main 0
> ...
> 
> Tested also with xenomai 3.0.6 from git on latest commit (on same ipipe
> and kernel).
> 
> Am I wrong somewhere?

Please try this and let me know if the situation gets any better:

diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c
index cde15485a..d9e9267c9 100644
--- a/lib/copperplate/threadobj.c
+++ b/lib/copperplate/threadobj.c
@@ -1625,25 +1625,28 @@ int threadobj_set_periodic(struct threadobj *thobj,
 {                              /* thobj->lock held */
        struct itimerspec its;
        struct sigevent sev;
+       timer_t timer;
        int ret;
 
        __threadobj_check_locked(thobj);
 
-       if (thobj->periodic_timer == NULL) {
+       timer = thobj->periodic_timer;
+       if (timer == NULL) {
                memset(&sev, 0, sizeof(sev));
                sev.sigev_signo = SIGPERIOD;
                sev.sigev_notify = SIGEV_SIGNAL|SIGEV_THREAD_ID;
                sev.sigev_notify_thread_id = threadobj_get_pid(thobj);
-               ret = __RT(timer_create(CLOCK_COPPERPLATE, &sev,
-                                       &thobj->periodic_timer));
+               ret = __RT(timer_create(CLOCK_COPPERPLATE, &sev, &timer));
                if (ret)
                        return __bt(-errno);
-       }
+               thobj->periodic_timer = timer;
+       } else if (!timespec_scalar(idate) && !timespec_scalar(period))
+               thobj->periodic_timer = NULL;
 
        its.it_value = *idate;
        its.it_interval = *period;
 
-       ret = __RT(timer_settime(thobj->periodic_timer, TIMER_ABSTIME, &its, 
NULL));
+       ret = __RT(timer_settime(timer, TIMER_ABSTIME, &its, NULL));
        if (ret)
                return __bt(-errno);
 
@@ -1656,6 +1659,9 @@ int threadobj_wait_period(unsigned long *overruns_r)
        siginfo_t si;
        int sig;
 
+       if (current->periodic_timer == NULL)
+               return -EWOULDBLOCK;
+
        for (;;) {
                current->run_state = __THREAD_S_DELAYED;
                sig = __RT(sigwaitinfo(&sigperiod_set, &si));

-- 
Philippe.

_______________________________________________
Xenomai mailing list
Xenomai@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai

Reply via email to