sem_timedwait question

Does anyone use this function? Per the POSIX spec, it takes an
absolute, not relative, timeout. If I want to timeout in 500 ms, it
seems like a hack to seed a timespec structure with the current time and
add 500 ms every time I want to call sem_timedwait.

Other RTOSes I’ve used had proprietary semaphore calls that took
timeouts in terms of OS ticks or relative time.

I’m porting a driver to QNX 6.1. This is my first foray into POSIX
coding.

The driver makes extensive use of this type of algortihm:

create empty semaphore
while(1)
invoke action that will generate an interrupt
wait for x ms for semaphore ← here’s my problem
if (timed out)
some error
else
get data from buffer

IRQ handler

  • get data, post semaphore

Is there a better, more QNX / POSIX-like way to accomplish this same
functionality w/out using semaphores?

Thanks,

DanG

Dan Giorgis <dang@tridium.com> wrote:

Does anyone use this function? Per the POSIX spec, it takes an
absolute, not relative, timeout. If I want to timeout in 500 ms, it
seems like a hack to seed a timespec structure with the current time and
add 500 ms every time I want to call sem_timedwait.

There was a really good reason for this, but it escapes me at the
moment. :frowning:

Other RTOSes I’ve used had proprietary semaphore calls that took
timeouts in terms of OS ticks or relative time.

I’m porting a driver to QNX 6.1. This is my first foray into POSIX
coding.

The driver makes extensive use of this type of algortihm:

create empty semaphore
while(1)
invoke action that will generate an interrupt
wait for x ms for semaphore ← here’s my problem
if (timed out)
some error
else
get data from buffer

IRQ handler

  • get data, post semaphore

Now, when you say “IRQ Handler” – are you talking about the INTERRUPT
SERVICE ROUTINE
? If so, you’re out of luck as far as posting a
semaphore from the ISR! You can’t do much in terms of kernel calls
in the ISR, so the “QNX-ish” strategy is to do the minimum in the ISR,
and then inform a thread that something has happened.

For you, what it sounds like you want, is:

while (1)
{
invoke active to generate interrupt
sts = InterruptWait_r (0, /* 64-bit nanosecond timeout value */);
if (sts == ETIMEDOUT) {
// some error
} else {
// get data from buffer
}
}

IRQ Handler:

  • set up a struct sigevent that gives SIGEV_INTR as its notification type
  • return NULL if you do not wish to wake up the thread, else return
    the struct sigevent.

Is there a better, more QNX / POSIX-like way to accomplish this same
functionality w/out using semaphores?

At the risk of pushing product on you, you might want to check out
www.parse.com/books/book_v3/

Cheers,
-RK

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Consulting and Training at www.parse.com
Email my initials at parse dot com.

Comments / questions below.

nospam93@parse.com wrote:

Dan Giorgis <> dang@tridium.com> > wrote:
Does anyone use this function? Per the POSIX spec, it takes an
absolute, not relative, timeout. If I want to timeout in 500 ms, it
seems like a hack to seed a timespec structure with the current time and
add 500 ms every time I want to call sem_timedwait.

There was a really good reason for this, but it escapes me at the
moment. > :frowning:

Other RTOSes I’ve used had proprietary semaphore calls that took
timeouts in terms of OS ticks or relative time.

I’m porting a driver to QNX 6.1. This is my first foray into POSIX
coding.

The driver makes extensive use of this type of algortihm:

create empty semaphore
while(1)
invoke action that will generate an interrupt
wait for x ms for semaphore ← here’s my problem
if (timed out)
some error
else
get data from buffer

IRQ handler

  • get data, post semaphore

Now, when you say “IRQ Handler” – are you talking about the INTERRUPT
SERVICE ROUTINE
? If so, you’re out of luck as far as posting a
semaphore from the ISR! You can’t do much in terms of kernel calls
in the ISR, so the “QNX-ish” strategy is to do the minimum in the ISR,
and then inform a thread that something has happened.

For you, what it sounds like you want, is:

while (1)
{
invoke active to generate interrupt
sts = InterruptWait_r (0, /* 64-bit nanosecond timeout value */);
if (sts == ETIMEDOUT) {
// some error
} else {
// get data from buffer
}
}

IRQ Handler:

  • set up a struct sigevent that gives SIGEV_INTR as its notification type
  • return NULL if you do not wish to wake up the thread, else return
    the struct sigevent.

Is there a better, more QNX / POSIX-like way to accomplish this same
functionality w/out using semaphores?

At the risk of pushing product on you, you might want to check out
www.parse.com/books/book_v3/

Cheers,
-RK

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Consulting and Training at > www.parse.com
Email my initials at parse dot com.

Thanks for the quick reply. I actually already own your book :slight_smile: and
would recommend it to others learning QNX.

My code uses the InterruptWait as described above and the semaphore is
posted by the thread (not the ISR).

I’m still interested in opinions about whether I should use
sem_timedwait(). Another thing that bothers me about sem_timedwait is
that the timeout is based on CLOCK_REALTIME. Since I want a fixed,
relative timeout that won’t be affected by system time changes, the
timeout should be based on CLOCK_MONOTONIC (if I understand my POSIX
clocks correctly).

\

  • DanG