periodic timer-triggered pthreads

Hello,

I am implementing a periodic time-triggered pthread under
use of a condvar. ( The timer triggers a signal and the signal
handler sends a cond_signal)
I encountered the following problem:
Two timers with the same interval (1sec in my case) started to
close to each other seem to make one timer event get lost.
A simple printf between the initializiation and setting of the timers
is enough to get the job done as expected.
Is there any (Posix-compliant) solution?
I saw examples in the technical articles handling timers with
pulses. Anyway, afaik it’s not guaranteed that these pulses get delivered?
How is the “standard” way of implementing periodic timers in the
same process without having the problem of loosing signals?

Thanks in advance,

Tobias

“Tobias Miksch” <miksch@uni-mannheim.de> wrote in message
news:bo87d9$3bv$1@inn.qnx.com

Hello,

I am implementing a periodic time-triggered pthread under
use of a condvar. ( The timer triggers a signal and the signal
handler sends a cond_signal)
I encountered the following problem:
Two timers with the same interval (1sec in my case) started to
close to each other seem to make one timer event get lost.
A simple printf between the initializiation and setting of the timers
is enough to get the job done as expected.
Is there any (Posix-compliant) solution?
I saw examples in the technical articles handling timers with
pulses. Anyway, afaik it’s not guaranteed that these pulses get delivered?
How is the “standard” way of implementing periodic timers in the
same process without having the problem of loosing signals?

Could you post your code?

Thanks in advance,

Tobias

Sure,
shortened (the actual code is placed in a class, the pthread is also
excluded due to the fact that not even the sighandler is executed):

//timercreation
// timer_t timer_id;
// struct itimerspec periodic_timer;
// struct sigaction sa;
// struct sigevent timer_event;
// int interval;

sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_SIGINFO;
sa.sa_sigaction= rttask_run;
sigaction(SIGRTMAX, &sa, NULL)

periodic_timer.it_value.tv_sec=interval;
periodic_timer.it_value.tv_nsec=0;
periodic_timer.it_interval.tv_sec=interval;
periodic_timer.it_interval.tv_nsec=0;

timer_event.sigev_notify = SIGEV_SIGNAL;
timer_event.sigev_signo = SIGRTMAX;
//this code is placed in a class , giving a this-pointer to
//the sighandler to know which object should be dealt with
timer_event.sigev_value.sival_ptr = this;

timer_create(CLOCK_REALTIME, &timer_event, &timer_id)
timer_settime(timer_id, 0 , &periodic_timer, NULL)

//timercreation end

//sighandler
void rttask_run(int sig, siginfo_t *extra, void *cruft) {
printf("\n Timer fired");
fflush(stdout);
}
//sighandler end

Two objects beeing instantiated short after each other with a periodicity of
1sec lets the signalhandler only be executed for the first instantiated
object. (The sighandler is only executed once, I guess the Signal gets
“overwritten”)
A printf between the instantiation of the two objects leads to
the desired call of the rttask_run for the two objects every second.

“Tobias Miksch” <miksch@uni-mannheim.de> wrote in message
news:bo8or9$f33$1@inn.qnx.com

Sure,
shortened (the actual code is placed in a class, the pthread is also
excluded due to the fact that not even the sighandler is executed):

//timercreation
// timer_t timer_id;
// struct itimerspec periodic_timer;
// struct sigaction sa;
// struct sigevent timer_event;
// int interval;

sigemptyset(&sa.sa_mask);
sa.sa_flags=SA_SIGINFO;
sa.sa_sigaction= rttask_run;
sigaction(SIGRTMAX, &sa, NULL)

periodic_timer.it_value.tv_sec=interval;
periodic_timer.it_value.tv_nsec=0;
periodic_timer.it_interval.tv_sec=interval;
periodic_timer.it_interval.tv_nsec=0;

timer_event.sigev_notify = SIGEV_SIGNAL;
timer_event.sigev_signo = SIGRTMAX;
//this code is placed in a class , giving a this-pointer to
//the sighandler to know which object should be dealt with
timer_event.sigev_value.sival_ptr = this;

timer_create(CLOCK_REALTIME, &timer_event, &timer_id)
timer_settime(timer_id, 0 , &periodic_timer, NULL)

//timercreation end

//sighandler
void rttask_run(int sig, siginfo_t *extra, void *cruft) {
printf("\n Timer fired");
fflush(stdout);
}
//sighandler end

Two objects beeing instantiated short after each other with a periodicity
of
1sec lets the signalhandler only be executed for the first instantiated
object. (The sighandler is only executed once, I guess the Signal gets
“overwritten”)
A printf between the instantiation of the two objects leads to
the desired call of the rttask_run for the two objects every second.

I will make an educated guess. I don’t beleive same signal can be queued.
Because the two timers are started roughly at the same time, the kernel
wants to generate both signal in the same tick resulting in the second
signal being lost. The printf inserts a small delay thus the kernel ends up
generating the event in different tick size.

I don’t know if that’s a bug or it’s by design or even if it’s POSIX
compliant. Does the same thing happen if you use two different signal
(SIGUSR1 and SIGUSR2 for example).

  • Mario

I will make an educated guess. I don’t beleive same signal can be queued.
Because the two timers are started roughly at the same time, the kernel
wants to generate both signal in the same tick resulting in the second
signal being lost. The printf inserts a small delay thus the kernel ends
up generating the event in different tick size.

I don’t know if that’s a bug or it’s by design or even if it’s POSIX
compliant. Does the same thing happen if you use two different signal
(SIGUSR1 and SIGUSR2 for example).

  • Mario

I also think the signal gets lost. But: With this behaviour I will always
have a problem with two timers getting fired too close to each other
within the same process. Think of a periodic one and an important one-shoot
timer beeing randomly triggered at the same time… one of them gets lost.
I did not try, but I think different signals would help. But: The number of
signals is very limited. This is not a practical solution for me.

-Tobias

Tobias Miksch <miksch@uni-mannheim.de> wrote:

I will make an educated guess. I don’t beleive same signal can be queued.
Because the two timers are started roughly at the same time, the kernel
wants to generate both signal in the same tick resulting in the second
signal being lost. The printf inserts a small delay thus the kernel ends
up generating the event in different tick size.

I don’t know if that’s a bug or it’s by design or even if it’s POSIX
compliant. Does the same thing happen if you use two different signal
(SIGUSR1 and SIGUSR2 for example).

  • Mario

TM > I also think the signal gets lost. But: With this behaviour I will always
TM > have a problem with two timers getting fired too close to each other
TM > within the same process. Think of a periodic one and an important one-shoot
TM > timer beeing randomly triggered at the same time… one of them gets lost.
TM > I did not try, but I think different signals would help. But: The number of
TM > signals is very limited. This is not a practical solution for me.

TM > -Tobias


Signals are capable of interrupting the thread. If this feature is
not required, use a Pulse instead. They will be queued. You can check
for them inside of a loop.


Bill Caroselli – Q-TPS Consulting
1-(708) 308-4956 <== Note: New Number
qtps@earthlink.net

Bill Caroselli wrote:

Signals are capable of interrupting the thread. If this feature is
not required, use a Pulse instead. They will be queued. You can check
for them inside of a loop.

Not the thread gets interrupted, the signalhandler (here: rttask_run)

doesn’t run!
A pulse is a QNX specific solution. I’d like to have a POSIX compliant
solution. Anyway, a pulse can get lost too.

signals generated by timers are not queued. This is
explicitly noted in the kernel.

I’m going to try and find out where this came from, whether
it is a POSIX defined behaviour or not.

Tobias Miksch <miksch@uni-mannheim.de> wrote:

Hello,

I am implementing a periodic time-triggered pthread under
use of a condvar. ( The timer triggers a signal and the signal
handler sends a cond_signal)
I encountered the following problem:
Two timers with the same interval (1sec in my case) started to
close to each other seem to make one timer event get lost.
A simple printf between the initializiation and setting of the timers
is enough to get the job done as expected.
Is there any (Posix-compliant) solution?
I saw examples in the technical articles handling timers with
pulses. Anyway, afaik it’s not guaranteed that these pulses get delivered?
How is the “standard” way of implementing periodic timers in the
same process without having the problem of loosing signals?

Thanks in advance,

Tobias


cburgess@qnx.com

“Tobias Miksch” <miksch@uni-mannheim.de> wrote in message
news:bob41m$5gm$1@inn.qnx.com

Bill Caroselli wrote:

Signals are capable of interrupting the thread. If this feature is
not required, use a Pulse instead. They will be queued. You can check
for them inside of a loop.

Not the thread gets interrupted, the signalhandler (here: rttask_run)
doesn’t run!
A pulse is a QNX specific solution. I’d like to have a POSIX compliant
solution. Anyway, a pulse can get lost too.

Nope, pulse can’t get lost, unless you run out of ram.

Colin Burgess <cburgess@qnx.com> wrote:

signals generated by timers are not queued. This is
explicitly noted in the kernel.
I’m going to try and find out where this came from, whether
it is a POSIX defined behaviour or not.

Yes, see “timer_settime()”, POSIX 14.2.4.2, which says “Only a
single signal shall be queued to the process for a given timer
at any point in time. When a timer for which a signal is still
pending expires, no signal shall be queued, and a timer overrun
shall occur”. But it then goes on to suggest that you can use
“timer_getoverrun()” to detect this has happened …

Hmm, but isn’t he using two different timers?

John Garvey <jgarvey@qnx.com> wrote:

Colin Burgess <> cburgess@qnx.com> > wrote:
signals generated by timers are not queued. This is
explicitly noted in the kernel.
I’m going to try and find out where this came from, whether
it is a POSIX defined behaviour or not.

Yes, see “timer_settime()”, POSIX 14.2.4.2, which says “Only a
single signal shall be queued to the process for a given timer
at any point in time. When a timer for which a signal is still
pending expires, no signal shall be queued, and a timer overrun
shall occur”. But it then goes on to suggest that you can use
“timer_getoverrun()” to detect this has happened …


cburgess@qnx.com

Colin Burgess wrote:

Hmm, but isn’t he using two different timers?

John Garvey <> jgarvey@qnx.com> > wrote:
Colin Burgess <> cburgess@qnx.com> > wrote:
signals generated by timers are not queued. This is
explicitly noted in the kernel.
I’m going to try and find out where this came from, whether
it is a POSIX defined behaviour or not.

Yes, see “timer_settime()”, POSIX 14.2.4.2, which says “Only a
single signal shall be queued to the process for a given timer
at any point in time. When a timer for which a signal is still
pending expires, no signal shall be queued, and a timer overrun
shall occur”. But it then goes on to suggest that you can use
“timer_getoverrun()” to detect this has happened …


Yes, two (and in the future more) timers. One timer for each pthread.

But they are all bound to the same signal and signalhandler.
I think I have no choice but to check all timers and see if one of them had
an overrun to awaken its thread.

-Tobias

“Tobias Miksch” <miksch@uni-mannheim.de> wrote in message
news:bodfbd$p6f$1@inn.qnx.com

Colin Burgess wrote:

Hmm, but isn’t he using two different timers?

John Garvey <> jgarvey@qnx.com> > wrote:
Colin Burgess <> cburgess@qnx.com> > wrote:
signals generated by timers are not queued. This is
explicitly noted in the kernel.
I’m going to try and find out where this came from, whether
it is a POSIX defined behaviour or not.

Yes, see “timer_settime()”, POSIX 14.2.4.2, which says “Only a
single signal shall be queued to the process for a given timer
at any point in time. When a timer for which a signal is still
pending expires, no signal shall be queued, and a timer overrun
shall occur”. But it then goes on to suggest that you can use
“timer_getoverrun()” to detect this has happened …


Yes, two (and in the future more) timers. One timer for each pthread.
But they are all bound to the same signal and signalhandler.
I think I have no choice but to check all timers and see if one of them
had
an overrun to awaken its thread.

Consider the staging:

A given timer will only queue one signal at any point in time, according
to the timer overrun behavior described.

If more than one timer is used, and one of the timer fires when the
signal is already queued, or the signal is pending for any other reason,
POSIX indicates that it is undefined whether the signal will queue, except
where realtime signals are supported (they are); in the latter case, the
signal
will only queue if the SA_SIGINFO flag is set for that signal (sigaction).

I didn’t see any indication in your example, but you said the signal
handler would call pthread_cond_signal. If indeed you are losing
signals – bearing in mind the timer overrun condition, which is POSIX
conformant – you might simply encounter difficulty at the next stage:

pthread_cond_signal may lose signals if a corresponding mutex (the
one used in pthread_cond_wait) is not held when the signal is sent.
However, mutex primitives, are definitely not async-signal safe. For
that matter, neither is the condvar function, but it is generally accepted
to be async-signal safe in most if not all implementations.

To be quite honest, the way I see it, the only truly conforming way
I can see to write an application is to assign a realtime signal to each
target thread, and have the thread perform a sigwait to wait for its
signal – and have no other threads performing sigwait whatsoever.
In any case, this avoids a signal-catching function altogether.

-Tobias

Hi Mario…

Under certain circumstances (not only RAM related), pulses do get lost.
What happens when you have a tread pool, for example? This is a main
reason why I do not rely on pulses. I’ll check the references to make
sure, however…

I wonder what RK and David Gibbs have to say?


Regards…

Miguel.


Mario Charest wrote:

“Tobias Miksch” <> miksch@uni-mannheim.de> > wrote in message
news:bob41m$5gm$> 1@inn.qnx.com> …

Bill Caroselli wrote:


Signals are capable of interrupting the thread. If this feature is
not required, use a Pulse instead. They will be queued. You can check
for them inside of a loop.


Not the thread gets interrupted, the signalhandler (here: rttask_run)
doesn’t run!
A pulse is a QNX specific solution. I’d like to have a POSIX compliant
solution. Anyway, a pulse can get lost too.


Nope, pulse can’t get lost, unless you run out of ram.

\

Steve Furr wrote:

Consider the staging:

A given timer will only queue one signal at any point in time, according
to the timer overrun behavior described.

If more than one timer is used, and one of the timer fires when the
signal is already queued, or the signal is pending for any other reason,
POSIX indicates that it is undefined whether the signal will queue,
except where realtime signals are supported (they are); in the latter
case, the signal
will only queue if the SA_SIGINFO flag is set for that signal (sigaction).

I didn’t see any indication in your example, but you said the signal
handler would call pthread_cond_signal. If indeed you are losing
signals – bearing in mind the timer overrun condition, which is POSIX
conformant – you might simply encounter difficulty at the next stage:

pthread_cond_signal may lose signals if a corresponding mutex (the
one used in pthread_cond_wait) is not held when the signal is sent.
However, mutex primitives, are definitely not async-signal safe. For
that matter, neither is the condvar function, but it is generally accepted
to be async-signal safe in most if not all implementations.

To be quite honest, the way I see it, the only truly conforming way
I can see to write an application is to assign a realtime signal to each
target thread, and have the thread perform a sigwait to wait for its
signal – and have no other threads performing sigwait whatsoever.
In any case, this avoids a signal-catching function altogether.

Your solution would then imply the use of “pthread_sleepon_signal”, which is
not Posix afaik.

Hmm. I was always wondering why there is no Posix definition/standard
for periodic tasks. These are vital for control systems i’m dealing with.
Is there an alternative scheduler for QNX performing RM or EDF scheduling?
Or the possibility to write a scheduler (sched_other) yourself?

-Tobias

“Tobias Miksch” <miksch@uni-mannheim.de> wrote in message
news:boqbjc$ndk$1@inn.qnx.com

Steve Furr wrote:


Consider the staging:

A given timer will only queue one signal at any point in time, according
to the timer overrun behavior described.

If more than one timer is used, and one of the timer fires when the
signal is already queued, or the signal is pending for any other reason,
POSIX indicates that it is undefined whether the signal will queue,
except where realtime signals are supported (they are); in the latter
case, the signal
will only queue if the SA_SIGINFO flag is set for that signal
(sigaction).

I didn’t see any indication in your example, but you said the signal
handler would call pthread_cond_signal. If indeed you are losing
signals – bearing in mind the timer overrun condition, which is POSIX
conformant – you might simply encounter difficulty at the next stage:

pthread_cond_signal may lose signals if a corresponding mutex (the
one used in pthread_cond_wait) is not held when the signal is sent.
However, mutex primitives, are definitely not async-signal safe. For
that matter, neither is the condvar function, but it is generally
accepted
to be async-signal safe in most if not all implementations.

To be quite honest, the way I see it, the only truly conforming way
I can see to write an application is to assign a realtime signal to each
target thread, and have the thread perform a sigwait to wait for its
signal – and have no other threads performing sigwait whatsoever.
In any case, this avoids a signal-catching function altogether.


Your solution would then imply the use of “pthread_sleepon_signal”, which
is
not Posix afaik.

To the contrary, I was saying to use sigwait().

The key is to use signals exclusively as the wakeup mechanism on the
thread and forego other IPC. To do so, each thread requires its own
unique realtime signal.

Consider the following (untested, not necessarily syntactically correct)
example.

e.g. (hypothetical RMS scheduling – some content elided, including error
handling)

static void *
periodic_task(void *data)
{
task_data_t *task_data = (task_data_t *)data;
sigset_t sigset;
siginfo_t info;

sigemptyset(&sigset);
sigaddset(&sigset, task_data->signum); // My unique realtime signal

… /* things like setting up thread cancellation /
do {
if (sigwaitinfo(&set, &info) == 0) {
/
start of critical timing (data race) window /
over = timer_getoverrun(task_data->timerid);
/
end of critical timing window – if this timer fires again
during this interval, overrun data may be inconsistent */
if (over > 0) {
(task_data->miss_f)(task_data,over);
/
Probably should return something and terminate/continue
accordingly */
} else {
(*task_data->task)(task_data->call_data);
}
}
} while (1);

}

int
rms_create_periodic_task(struct timespec *release, struct timespec
*interval, struct timespec *cost, void *call_data,
void (*task)(void *), void (*deadline_miss)(void *, int))
{
task_data_t *task_data = rms_new_task_data();
pthread_attr_t attr;
struct sched_param sched;


task_data->call_data = call_data;
task_data->signum = rms_get_signal_number(); /* get an available
realtime signal in range (RTMIN,RTMAX) */
task_data->miss_f = deadline_miss;
task_data->task_f = task;

if (rms_schedule(interval, cost,&task_data->sched_priority) == 0) {
pthread_attr_setschedpolicy (&attr, SCHED_FIFO);
pthread_attr_setschedparam(&attr, &task_data->sched_priority);
pthread_create(&task_data->tid, &attr, periodic_task, task_data);
}

}

With respect to other scheduling mechanisms, it is important not to forget
sporadic scheduling, which is applicable to RMS or other static priority
scheduling
that requires limits on processing within a periodic interval, and is useful
for
either sporadic or aperiodic tasks.

Hmm. I was always wondering why there is no Posix definition/standard
for periodic tasks. These are vital for control systems i’m dealing with.
Is there an alternative scheduler for QNX performing RM or EDF scheduling?
Or the possibility to write a scheduler (sched_other) yourself?

-Tobias

“Steve Furr” <furr@qnx.com> wrote in message
news:boh5ks$j12$1@nntp.qnx.com

[…]

pthread_cond_signal may lose signals if a corresponding mutex (the
one used in pthread_cond_wait) is not held when the signal is sent.

Aren’t you supposed to obtain that mutex before signaling a condvar? Then
how it can be ‘not held’, unless you deliberately chose not to?

However, mutex primitives, are definitely not async-signal safe. For
that matter, neither is the condvar function, but it is generally accepted
to be async-signal safe in most if not all implementations.

To be quite honest, the way I see it, the only truly conforming way
I can see to write an application is to assign a realtime signal to each
target thread, and have the thread perform a sigwait to wait for its
signal – and have no other threads performing sigwait whatsoever.
In any case, this avoids a signal-catching function altogether.

Trouble with making portable and reliably implementation based on queued
signals is that various systems put various limit on maximum depth of the
queue. I believe POSIX says it must be at least 32 items deep, which is all
that some systems provide. You can overrun that easy enough…

I was trying to come up with a portable design like that once, but it was
hard to fit. Aside from the problems discussed before, you may need to do
some I/O in one form or another, which brings the question how does one
integrate it. None of 3rd party software written for Unix that you may need
to integrate into your scheme supports requesting notifications in form of
sigevents. They all stick to the good old poll(). The only mechanism defined
by POSIX to support notifications on I/O like that is AIO… but that is not
available (and currently tough to do) on QNX. Which is a shame, because it
would go along with sigwait() very nicely - you could then wait for all
major types of events in one blocking point. And since QNX does not limit
the depth of the signal queue (right?) the pie would only get sweeter.

So, we need a kernel call, like MsgMapClientBuffer(). Anyone up for the
challenge? :slight_smile:

– igor