threads and signal handling

Hi,

we have difficulties to stop and continue threads of a process.
The problem is that pthread_kill(thread_id, SIGTSTP) stops also the
calling main thread of the process.

Is possible to correct that signal handling in 6.2 ??

Regards

Armin


here the details … code below.

sigtest

thread start …
[1] + Stopped sigtest
→ strange behavior of the shell …

pidin | grep sigtest

802856 1 ./sigtest 10o STOPPED
802856 2 ./sigtest 10o STOPPED

→ also the main thread 1 stops …

kill -25 802856

thread started … 2

kill -25 802856

→ signal SIGCONT send to the process

[1] + Stopped sigtest ???
thread continued … ???

kill -25 802856

[1] + Stopped sigtest


Here is the example code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <termios.h>
#include <pthread.h>
#include <sys/neutrino.h>

pthread_t thread_id;
int resume;

void * thread1 (void *arg)
{
for(;:wink:
{
// thread stops by itself
pthread_kill( thread_id, SIGTSTP);
}
}

int main(int argc, char **argv)
{
// allow access to IO resources
ThreadCtl(_NTO_TCTL_IO, 0);

// Start the thread.
printf(" thread start … \n");
pthread_create (&thread_id, NULL,thread1, NULL);
printf(" thread started … %d \n", thread_id);

for(;:wink:
{
pthread_kill( thread_id, SIGCONT);
printf(" thread continued …\n");
}
return (0);

}

Armin Steinhoff <a-steinhoff@web_.de> wrote:

we have difficulties to stop and continue threads of a process.
The problem is that pthread_kill(thread_id, SIGTSTP) stops also the
calling main thread of the process.

And any other threads as well. An unhandled SIGTSTP stops the entire
process. That’s the correct behaviour.

Is possible to correct that signal handling in 6.2 ??

It is correct already.


Wojtek Lerch QNX Software Systems Ltd.

Wojtek Lerch wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:
we have difficulties to stop and continue threads of a process.
The problem is that pthread_kill(thread_id, SIGTSTP) stops also the
calling main thread of the process.

And any other threads as well. An unhandled SIGTSTP stops the entire
process. That’s the correct behaviour.

This is only correct if SIGTSTP has been sent to the process … but I’m
sendig that
signal to a specific THREAD !

Is possible to correct that signal handling in 6.2 ??

It is correct already.

No … the semantic of an pthread_kill(tread_id, SIGTSTP) is handled
differently by other
UNIX systems!

Armin

Armin Steinhoff <a-steinhoff@web_.de> wrote:

Wojtek Lerch wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:
we have difficulties to stop and continue threads of a process.
The problem is that pthread_kill(thread_id, SIGTSTP) stops also the
calling main thread of the process.

And any other threads as well. An unhandled SIGTSTP stops the entire
process. That’s the correct behaviour.

This is only correct if SIGTSTP has been sent to the process … but I’m
sendig that
signal to a specific THREAD !

This is what the latest POSIX standard says about it:

Note that pthread_kill() only causes the signal to be handled in the
context of the given thread; the signal action (termination or
stopping) affects the process as a whole.

You can find this and more in

http://www.opengroup.org/onlinepubs/007904975/functions/pthread_kill.html

Is possible to correct that signal handling in 6.2 ??

It is correct already.

No … the semantic of an pthread_kill(tread_id, SIGTSTP) is handled
differently by other
UNIX systems!

Perhaps, but for some reason POSIX decided that they’re wrong.


Wojtek Lerch QNX Software Systems Ltd.

Armin Steinhoff <a-steinhoff@web_.de> wrote:

This means at the end it makes no sense to send a STOP signal to a
thread ?? … just to stop its execution?!

I’m afraid so. Unless you don’t mind that all the other threads stop too…

Is there an other way to stop and continue a thread ??

Asynchronously – not that I know of. (I’m not exactly the main pthread
expert here though – there might be something that I’ve never heard
about…)

\

Wojtek Lerch QNX Software Systems Ltd.

Wojtek Lerch wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:
Wojtek Lerch wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:
we have difficulties to stop and continue threads of a process.
The problem is that pthread_kill(thread_id, SIGTSTP) stops also the
calling main thread of the process.

And any other threads as well. An unhandled SIGTSTP stops the entire
process. That’s the correct behaviour.

This is only correct if SIGTSTP has been sent to the process … but I’m
sendig that
signal to a specific THREAD !

This is what the latest POSIX standard says about it:

Note that pthread_kill() only causes the signal to be handled in the
context of the given thread; the signal action (termination or
stopping) affects the process as a whole.

You can find this and more in

http://www.opengroup.org/onlinepubs/007904975/functions/pthread_kill.html

This means at the end it makes no sense to send a STOP signal to a
thread ?? … just to stop its execution?!

Is possible to correct that signal handling in 6.2 ??

It is correct already.

No … the semantic of an pthread_kill(tread_id, SIGTSTP) is handled
differently by other
UNIX systems!

Perhaps, but for some reason POSIX decided that they’re wrong.

Is there an other way to stop and continue a thread ??

Thanks

Armin

Armin Steinhoff <a-steinhoff@web_.de> wrote:

Perhaps, but for some reason POSIX decided that they’re wrong.

Is there an other way to stop and continue a thread ??

I can think of a couple of kludges, but I don’t think there is
anything that will do this cleanly.

I find when someone asks to do something that the OS doesn’t support,
or doesn’t support directly, the most useful question I can ask before
going further is:

What are you trying to accomplish/why are you trying to do this?

Possible kludges:

– create a FIFO READY thread at priority 2, to “suspend” a thread,
drop it to priority 1, to “resume” a thread, return it to a priority
above 2. SIDE EFFECT: 100% CPU useage all the time. Better not want
to go into any sort of low-power mode.

– attach a signal handler for, say, SIGRTMIN+5. In this signal handler,
do a sigwaitinfo() for SIGRTMIN+6. To “suspend” a thread, hit that
thread with a SIGRTMIN+5 (pthread_kill()); to resume that thread, hit
it with a SIGRTMIN+6. SIDE EFFECT: can/will unexpectedly unblock a
thread from a blocking state.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:

Perhaps, but for some reason POSIX decided that they’re wrong.

Is there an other way to stop and continue a thread ??

I can think of a couple of kludges, but I don’t think there is
anything that will do this cleanly.

OK … IMHO the best way would be to implement ‘pthread_suspend’ and
‘pthread_resume’ … it makes sense even if these calls are not POSIX.

There are a lot of non-POSIX library calls available for QNX6 …

I find when someone asks to do something that the OS doesn’t support,
or doesn’t support directly, the most useful question I can ask before
going further is:

What are you trying to accomplish/why are you trying to do this?

I’m involved in a port of a pSOS/VxWorks based soft PLC to QNX6 … both
operating systems have the possibility to suspend/resume threads for an
application specific internal scheduling.

Possible kludges:

– create a FIFO READY thread at priority 2, to “suspend” a thread,
drop it to priority 1, to “resume” a thread, return it to a priority
above 2. SIDE EFFECT: 100% CPU useage all the time. Better not want
to go into any sort of low-power mode.

Seems to be the only secure way … low-power mode is a minor issue.

– attach a signal handler for, say, SIGRTMIN+5. In this signal handler,
do a sigwaitinfo() for SIGRTMIN+6. To “suspend” a thread, hit that
thread with a SIGRTMIN+5 (pthread_kill()); to resume that thread, hit
it with a SIGRTMIN+6. SIDE EFFECT: can/will unexpectedly unblock a
thread from a blocking state.

Thanks for your proposals

Armin

Wojtek Lerch wrote:

[ clip …]

You can find this and more in

http://www.opengroup.org/onlinepubs/007904975/functions/pthread_kill.html

Is possible to correct that signal handling in 6.2 ??

It is correct already.

No … the semantic of an pthread_kill(tread_id, SIGTSTP) is handled
differently by other UNIX systems!

Perhaps, but for some reason POSIX decided that they’re wrong.

Well … their implementations seem to be wrong, but they are USEFUL :slight_smile:
QNX6 provides a lot of very useful library calls which are not POSIX.

Armin

Armin Steinhoff <a-steinhoff@web_.de> wrote:

David Gibbs wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:

Perhaps, but for some reason POSIX decided that they’re wrong.

Is there an other way to stop and continue a thread ??

I can think of a couple of kludges, but I don’t think there is
anything that will do this cleanly.

Read chapter 6.6.3 in “Programming with POSIX Threads” by Butenhof.

OK … IMHO the best way would be to implement ‘pthread_suspend’ and
‘pthread_resume’ … it makes sense even if these calls are not POSIX.

There are a lot of non-POSIX library calls available for QNX6 …

If I remember correctly, the Solaris thr_suspend/thr_continue style
functions were rejected by the pthread standard authors. I would
guess (I would have to dig up the old draft standard to verify) they
were rejected because these calls alter the scheduling algorithm which
could negatively effect thread synchronization (lock a mutex then
get suspended). Or worse, the suspend/continue calls would get used for
synchronization – scheduling shouldn’t be used for thread synchronization.

So IHMO, poor APIs shouldn’t be added to the QNX6 library.

kirk wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:
David Gibbs wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:

Perhaps, but for some reason POSIX decided that they’re wrong.

Is there an other way to stop and continue a thread ??

I can think of a couple of kludges, but I don’t think there is
anything that will do this cleanly.

Read chapter 6.6.3 in “Programming with POSIX Threads” by Butenhof.

OK … read also the docs of SignalKill(). That calls isn’t POSIX …
but applied to a thread ID it performs in the same crazy POSIX way as
the pthread_kill() call. Why?

OK … IMHO the best way would be to implement ‘pthread_suspend’ and
‘pthread_resume’ … it makes sense even if these calls are not POSIX.

There are a lot of non-POSIX library calls available for QNX6 …

If I remember correctly, the Solaris thr_suspend/thr_continue style
functions were rejected by the pthread standard authors. I would
guess (I would have to dig up the old draft standard to verify) they
were rejected because these calls alter the scheduling algorithm which
could negatively effect thread synchronization (lock a mutex then
get suspended). Or worse, the suspend/continue calls would get used for
synchronization

Why not ?? Everyone is free to do also NONSENS with the available
pthread calls!

Following you logic … I have to say that pthread calls are dangerous
and useless :slight_smile:

– scheduling shouldn’t be used for thread synchronization.

This is not the issue … the point is the application specific
scheduling of threads.

We have also to compete against platfoms like pSOS, VxWorks and Windows
XY! That’s just a piece of the (non POSIX) reality …

So IHMO, poor APIs shouldn’t be added to the QNX6 library.

I can’t see what could be poor with e.g. pthread_suspend and
pthread_resume.

Armin

Armin Steinhoff <a-steinhoff@web_.de> wrote:



What are you trying to accomplish/why are you trying to do this?

I’m involved in a port of a pSOS/VxWorks based soft PLC to QNX6 … both
operating systems have the possibility to suspend/resume threads for an
application specific internal scheduling.

It may require too much work/analysis…but why are they doing this?
That is, what are they trying to accomplish when they “suspend” a thread?

Is this something that normal pre-emption won’t accomplish? Are they
using this to control access to a resource? At the point that the
thread suspend is being done, why is a thread being suspended? What
effect does this achieve towards proper completion of the tasks
involved? Can this effect, or an equivalent one be obtained in
a more consistent way with the tools available with QNX?

Possible kludges:

– create a FIFO READY thread at priority 2, to “suspend” a thread,
drop it to priority 1, to “resume” a thread, return it to a priority
above 2. SIDE EFFECT: 100% CPU useage all the time. Better not want
to go into any sort of low-power mode.

Seems to be the only secure way … low-power mode is a minor issue.

Hm…also any “normal” measure of idle time for your CPU will be wrong.
If you need to measure idle time, you’ll have to do it by hand – idle
time will be time used by your priority 2 thread, not by the system idle
thread.

Thanks for your proposals

You’re welcome.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Armin Steinhoff <a-steinhoff@web_.de> wrote:

So IHMO, poor APIs shouldn’t be added to the QNX6 library.

I can’t see what could be poor with e.g. pthread_suspend and
pthread_resume.

Thread1: lock mutex1

Thread2: suspend thread1
lock mutex1

Ooops, deadlock.

Hard to accomplish? Well… maybe not…lots of pieces of the C
library use mutexes for safety…e.g. malloc().

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:

What are you trying to accomplish/why are you trying to do this?

I’m involved in a port of a pSOS/VxWorks based soft PLC to QNX6 … both
operating systems have the possibility to suspend/resume threads for an
application specific internal scheduling.

It may require too much work/analysis…but why are they doing this?

The cyclic threads have to run in a defined sequence and dependency.

That is, what are they trying to accomplish when they “suspend” a thread?

control of the execution of cyclic threads.

Is this something that normal pre-emption won’t accomplish?

No

Are they using this to control access to a resource?

CPU + IO data + internal resources.

At the point that the thread suspend is being done, why is a thread being suspended?

It happens e.g. if the execution of an other thread has priority from
the application point of view.

What
effect does this achieve towards proper completion of the tasks
involved?

These threads don’t terminate (hope fully) because they have to do
cyclic tasks with a defined cycle time.

Can this effect, or an equivalent one be obtained in
a more consistent way with the tools available with QNX?

No … but I have still to discuss if a creation of threads and
gracefully shutdowns could be an alternative for suspending and and
resuming.

Regards

Armin

Armin Steinhoff <a-steinhoff@web_.de> wrote:


David Gibbs wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:

Perhaps, but for some reason POSIX decided that they’re wrong.

Is there an other way to stop and continue a thread ??

I can think of a couple of kludges, but I don’t think there is
anything that will do this cleanly.

OK … IMHO the best way would be to implement ‘pthread_suspend’ and
‘pthread_resume’ … it makes sense even if these calls are not POSIX.

There are a lot of non-POSIX library calls available for QNX6 …

It’s not just a library issue. This functionality would need to be
supported in the kernel. I presume you would like a guarantee that when
pthread_suspend() returns, its victim has been stopped already – I
imagine that this might be non-trivial to implement in the SMP version
of the kernel. It’s hard for me to guess how much exactly this would
cost in terms of speed and size of the kernel, but the thing is that
everybody would have to pay the price for a functionality that is
considered unnecessary by the POSIX committee and been has requested by
only one person so far…


Wojtek Lerch QNX Software Systems Ltd.

Armin Steinhoff <a-steinhoff@web_.de> wrote:


Can this effect, or an equivalent one be obtained in
a more consistent way with the tools available with QNX?

No … but I have still to discuss if a creation of threads and
gracefully shutdowns could be an alternative for suspending and and
resuming.

Thread creation & termination is a relatively expensive operation
compared with almost any of the synchronisation methods.

Hm…the problem I see is suspending a thread at any arbitrary
point in the thread’s code path. Most synchronisation methods
require the cooperation of the thread – but have the advantage
that it “synchronises” when it is safe.

You talk about cyclical threads – I’m not sure I understand exactly
what you mean by that… it sounds like a thread that has to run
everyone so often… on a regular basis. And, you talk about an
order series of these. Is the suspend/resume being used by some
sort of controller thread to give each of these cyclical threads
its turn to run?

What happens if you suspend a thread in the middle of an operation?
When it has half-updated a data structure or something like that?
What controls are there to prevent this from happening?

For me, this is an interesting problem… but it feels like I don’t
understand enough of what is happening in your application to really
talk about it… to really figure out what is going on, which is why
I may seem to ask questions that don’t make much sense.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Wojtek Lerch wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:

David Gibbs wrote:

Armin Steinhoff <a-steinhoff@web_.de> wrote:

Perhaps, but for some reason POSIX decided that they’re wrong.

Is there an other way to stop and continue a thread ??

I can think of a couple of kludges, but I don’t think there is
anything that will do this cleanly.

OK … IMHO the best way would be to implement ‘pthread_suspend’ and
‘pthread_resume’ … it makes sense even if these calls are not POSIX.

There are a lot of non-POSIX library calls available for QNX6 …

It’s not just a library issue. This functionality would need to be
supported in the kernel. I presume you would like a guarantee that when
pthread_suspend() returns, its victim has been stopped already – I
imagine that this might be non-trivial to implement in the SMP version
of the kernel. It’s hard for me to guess how much exactly this would
cost in terms of speed and size of the kernel, but the thing is that
everybody would have to pay the price for a functionality that is
considered unnecessary by the POSIX committee

This commitee has also designed that sensless pthread_kill() … they
are
not the source of unfailable designs.

and been has requested by only one person so far…

It’s not my personal request … we have to compete against VxWorks.

So we have to say stay with VxWorks it’s not possible with QNX6??

The reality has sometimes nothing to do with POSIX :slight_smile:

Armin