timeout vs deadline

Discussions and support about ChibiOS/RT, the free embedded RTOS.
iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

timeout vs deadline

Postby iggarpe » Fri Aug 21, 2015 6:02 pm

Hi,

I keep stumbling upon the following design pattern: operation X comprises two sequential operations A and B that must wait on some synchronization primitive. The timeout is specified for operation X.

In such scenario this is what I usually do:

Code: Select all

int32_t deadline = chTimeNow() + timeout;
...
timeout = deadline - chTimeNow();            // Operation A
if (timeout <= 0) return RDY_TIMEOUT;
chSemWaitTimeout
...
timeout = deadline - chTimeNow();            // Operation B
if (timeout <= 0) return RDY_TIMEOUT;
chSemWaitTimeout
...


Another place where I find this pattern is with condition variables. I want to specify the total timeout until the condition is met (for example, myvar >= 0), the CondVar may be signaled an indeterminate number of times by changes to myvar that do not meet myvar >= 0, so the loop will keep waiting for an indeterminate amount of time.

Code: Select all

int32_t deadline = chTimeNow() + timeout;
while (myvar < 0) {
    timeout = deadline - chTimeNow();
    if (timeout <= 0) break;
    if (chCondWaitTimeout(&cond, timeout) == RDY_TIMEOUT) break;
}


Note that the time variables are int32_t instead of systime_t, because a signed var is needed in order to check for negative values of the timeout variable.

Almost every single time I've had to wait on a CondVar with a timeout, the requierement specifies the *total* timeout and thus the code above is required. Eventually I just wrote a chCondWaitDeadline wrapper around chCondWaitTimeout, and I wonder whether such a ser of alternative "Deadline" functions would be a worthy addition to the ChibiOS/RT API.

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: timeout vs deadline

Postby Giovanni » Fri Aug 21, 2015 6:09 pm

Hi,

I think that the above code has issues of atomocity because the system time can advance between the check and the call to "wait". Probably this should be done in a way similar to chthdSleepUntilWindowed() (and this would mean no need for signed variables).

Giovanni

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: timeout vs deadline

Postby Giovanni » Fri Aug 21, 2015 8:48 pm

It could be something like:

Code: Select all

  systime_t start = chVTGetSystemTimeX();
  systime_t end = start + timeout;
  chSysLock();
  while (CONDITION) {
    systime_t time = chVTGetSystemTimeX();
    if (chVTIsTimeWithinX(time, start, end)) {
     msg_t msg = chXXXXWaitTimeoutS(..., end - time);
      if (msg != MSG_TIMEOUT) {
        continue;
      }
    }
    // timeout.
    break;
  }
  chSysUnlock();


Adding something like this to all wait functions would increase complexity even more. Probably we should consider adding a "RTOS library" on top of RT and NIL containing all constructs that can be created starting from the normal API.

iggarpe
Posts: 129
Joined: Sun Sep 30, 2012 8:32 pm

Re: timeout vs deadline

Postby iggarpe » Tue Aug 25, 2015 2:34 pm

Giovanni wrote:I think that the above code has issues of atomocity because the system time can advance between the check and the call to "wait". Probably this should be done in a way similar to chthdSleepUntilWindowed() (and this would mean no need for signed variables).
Giovanni


It's true that the time counter may advance between "timeout = deadline - chTimeNow();" and the moment chCondWaitTimeout is called, but that would result in a tiny timeout inaccuracy which is most of the time totally acceptable (remember, the point was to avoid the total timeout potentially being much larger than specified). And if it weren't acceptable chSysLock comes to the rescue:

Code: Select all

int32_t deadline = chTimeNow() + timeout;
while (myvar < 0) {
    chSysLock();
    timeout = deadline - chTimeNow();
    if (timeout <= 0 || chCondWaitTimeoutS(&cond, timeout) == RDY_TIMEOUT) {
        chSysUnlock();
        break;
    }
}


Return to “ChibiOS/RT”

Who is online

Users browsing this forum: No registered users and 5 guests