Threads and timers 101

Hello QNX World,
I’ve just started using QNX, to write a pretty plain-jane real-time
app. After all the promises of gobs of support coming out of the
woodwork, my sales rep has gone silent; the recommended thrird party
(CBT) training outfit won’t return emails, and my friendly, highly
knowledgeable “peers” (in a sister division) have also vanished into a
black hole. I find myself stuck in first gear.
Question 1) _beginthread and _endthread: Like a good beginner I
followed the example in the on-line “Help” for _beginthread, and even
got it to compile. But the linker can’t find these two functions in the
libraries. The only LIBPATH I know of is /usr/lib. Is there another
one lurking?

Q2) timer_create and timer_settime: I’d really like to be able to start
a RUNNING timer, at a nice fixed frequency. For my first shot I’d be
happy with 1 Hz, then I’ll delve into nanoseconds later. Whether I use
the friendly Help sample (which sets up a simple proxy) or swipe some
code from an older project using signals, all I can get is the first
“tick” to go off (defined in the .it_value fields). The program then
politely exits, regardless of the (non-zero!!) values in the
…it_interval fields.

Can anyone get me to square 2?

Fred Schreiber
Software Engineering Manager
EMS Development Corp.
(631) 345-6200 x321

Sounds like you’re talking about QNX4, and this newsgroup is specific to QNX6.
You may get a better response by posting in qdn.public.qnx4, although more
likely than not someone will also be able to help you here.

If I recall, threads are not native to QNX4, and there are a number of caveats
involved in their use (although it is possible). My suggestion would be to go
with a single-threaded design if you are indeed using QNX4, or switch to QNX6
if you really want multi-threading. Here is a sample that might help you:



pid_t Tproxy;
timer_t Timer;


void init_timer( void )
{
struct itimerspec ts;
struct sigevent event;

/*
** Attach a proxy for the timer to trigger
*/

if( ( Tproxy = qnx_proxy_attach( 0, 0, 0, -1 ) ) == -1 )
fatal( “error %d attaching timer proxy”, errno );

/*
** Fill in a sigevent structure with the proxy ID, create the timer
*/

memset( &event, 0, sizeof( event ) );
event.sigev_signo = -Tproxy;

if( ( Timer = timer_create( CLOCK_REALTIME, &event ) ) == -1 )
fatal( “error %d creating timer”, errno );

/*
** Set the initial and interval values for the timer
*/

memset( &ts, 0, sizeof( ts ) );
ts.it_value.tv_sec = SECONDS;
ts.it_value.tv_nsec = NANOSECS;
ts.it_interval.tv_sec = SECONDS;
ts.it_interval.tv_nsec = NANOSECS;

if( timer_settime( Timer, 0, &ts, NULL ) == -1 )
fatal( “error %d setting timer value”, errno );
}



void timer_proxy( void )
{
/*
** Handle a timer “tick” here
*/
}



void main( void )
{
init_timer( );

/*
** Main loop
*/

for( ; ; )
{
my_msg_t msg;
pid_t pid;

/*
** Receive a message
*/

memset( &msg, 0, MY_MSGSZ );
if( ( pid = Receive( 0, &msg, MY_MSGSZ ) ) == -1 )
continue;

/*
** Check for a timer proxy
*/

if( pid == Tproxy )
{
timer_proxy( );
continue;
}

/*
** Process message here
*/

/* And so on */
}
}



“Fred Schreiber” <fschreiber@emsdevelopment.com> wrote in message
news:3A3F8B64.3CA50A71@emsdevelopment.com
| Hello QNX World,
| I’ve just started using QNX, to write a pretty plain-jane real-time
| app. After all the promises of gobs of support coming out of the
| woodwork, my sales rep has gone silent; the recommended thrird party
| (CBT) training outfit won’t return emails, and my friendly, highly
| knowledgeable “peers” (in a sister division) have also vanished into a
| black hole. I find myself stuck in first gear.
| Question 1) _beginthread and _endthread: Like a good beginner I
| followed the example in the on-line “Help” for _beginthread, and even
| got it to compile. But the linker can’t find these two functions in the
| libraries. The only LIBPATH I know of is /usr/lib. Is there another
| one lurking?
|
| Q2) timer_create and timer_settime: I’d really like to be able to start
| a RUNNING timer, at a nice fixed frequency. For my first shot I’d be
| happy with 1 Hz, then I’ll delve into nanoseconds later. Whether I use
| the friendly Help sample (which sets up a simple proxy) or swipe some
| code from an older project using signals, all I can get is the first
| “tick” to go off (defined in the .it_value fields). The program then
| politely exits, regardless of the (non-zero!!) values in the
| .it_interval fields.
|
| Can anyone get me to square 2?

Fred Schreiber
Software Engineering Manager
EMS Development Corp.
(631) 345-6200 x321

If you are using Neutrino, your libraries should be in /usr/nto/x86/lib, I
think. Don’t use “gcc”, use “qcc” - if you are using the “qcc” front end
this and many other options are accounted for automatically.

Fred Schreiber wrote:

Hello QNX World,
I’ve just started using QNX, to write a pretty plain-jane real-time
app. After all the promises of gobs of support coming out of the
woodwork, my sales rep has gone silent; the recommended thrird party
(CBT) training outfit won’t return emails, and my friendly, highly
knowledgeable “peers” (in a sister division) have also vanished into a
black hole. I find myself stuck in first gear.
Question 1) _beginthread and _endthread: Like a good beginner I
followed the example in the on-line “Help” for _beginthread, and even
got it to compile. But the linker can’t find these two functions in the
libraries. The only LIBPATH I know of is /usr/lib. Is there another
one lurking?

Q2) timer_create and timer_settime: I’d really like to be able to start
a RUNNING timer, at a nice fixed frequency. For my first shot I’d be
happy with 1 Hz, then I’ll delve into nanoseconds later. Whether I use
the friendly Help sample (which sets up a simple proxy) or swipe some
code from an older project using signals, all I can get is the first
“tick” to go off (defined in the .it_value fields). The program then
politely exits, regardless of the (non-zero!!) values in the
.it_interval fields.

Can anyone get me to square 2?

Fred Schreiber
Software Engineering Manager
EMS Development Corp.
(631) 345-6200 x321

Jim Bormann <jim_bormann@yahoo.com> wrote:

If you are using Neutrino, your libraries should be in /usr/nto/x86/lib, I
think. Don’t use “gcc”, use “qcc” - if you are using the “qcc” front end
this and many other options are accounted for automatically.

From the functions he is mentioning, he is running/developping for
QNX4, rather than Neutrino.

Hello QNX World,

Question 1) _beginthread and _endthread: Like a good beginner I
followed the example in the on-line “Help” for _beginthread, and even
got it to compile. But the linker can’t find these two functions in the
libraries. The only LIBPATH I know of is /usr/lib. Is there another
one lurking?

QNX4 doesn’t have a complete thread model, and if you can avoid using threads
under QNX4, I would strongly recommend doing so. QNX4 designs generally work
better with cooperating processes, rather than with threads.

Also, both _beginthread() and _endthread() live in libc – the standard
C library that would, normally, be found by default.

Possible issues:
– did you include the appropriate header, process.h?
– is this a .c file, or a C++ file extension? (.cpp or .C)
– did you use cc to compile & link, or did you try to invoke the
underlying tools (wcc386/wpp386 & wlink) yourself? Invoking the
underlying tools yourself is not a supported option.

Q2) timer_create and timer_settime: I’d really like to be able to start
a RUNNING timer, at a nice fixed frequency. For my first shot I’d be
happy with 1 Hz, then I’ll delve into nanoseconds later. Whether I use
the friendly Help sample (which sets up a simple proxy) or swipe some
code from an older project using signals, all I can get is the first
“tick” to go off (defined in the .it_value fields). The program then
politely exits, regardless of the (non-zero!!) values in the
.it_interval fields.

What is your program doing after it gets that notification? If it doesn’t
loop & wait for another notification, it won’t get one. If getting hit
by a signal from the timer, exiting is the normal result of getting hit
by a signal. And, the OS automatically cleans up the timer resource
when your process exits.

Here is a quick sample:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/kernel.h>
#include <sys/proxy.h>

main()
{
struct sigevent event;
struct itimerspec itime;
pid_t pid, proxy;
timer_t timerID;
short i;

proxy = qnx_proxy_attach( 0, NULL, 0, -1 );
event.sigev_signo = -proxy;
timerID = timer_create( CLOCK_REALTIME, &event );

memset( &itime, 0, sizeof(struct itimerspec) );
itime.it_value.tv_sec = 2;
itime.it_interval.tv_sec = 2;
timer_settime( timerID, 0, &itime, NULL );

while(1) {
pid = Receive( 0, NULL, 0 );
printf(“got a proxy\n”);

}
}

Save as timer.c
Compile with “cc -otimer timer.c”

Can anyone get me to square 2?

Hopefully this will get you to square 2.

-David

QNX Training Services
dagibbs@qnx.com

David Gibbs <dagibbs@qnx.com> wrote:

Jim Bormann <> jim_bormann@yahoo.com> > wrote:
If you are using Neutrino, your libraries should be in /usr/nto/x86/lib, I
think. Don’t use “gcc”, use “qcc” - if you are using the “qcc” front end
this and many other options are accounted for automatically.

From the functions he is mentioning, he is running/developping for
QNX4, rather than Neutrino.

And, because of that, this doesn’t really belong in qnxrtp – which
is for the “real time platform” based on Neutrino. For further
questions, you’d best try one of the qnx4 groups.

-David

QNX Training Services
dagibbs@qnx.com

Add the following function and call it prior to setting the timer. It will
catch the signal caused when the timer expires.

sigalrm()
{
signal (SIGALRM, sigalrm);
}

  • KenR

Q2) timer_create and timer_settime: I’d really like to be able to start
a RUNNING timer, at a nice fixed frequency. For my first shot I’d be
happy with 1 Hz, then I’ll delve into nanoseconds later. Whether I use
the friendly Help sample (which sets up a simple proxy) or swipe some
code from an older project using signals, all I can get is the first
“tick” to go off (defined in the .it_value fields). The program then
politely exits, regardless of the (non-zero!!) values in the
.it_interval fields.