proxies and pulses

I’m trying to port some code from QNX 4 to QNX 6.

I apologize if this is overly descriptive or particularly lacking. I’m new
to realtime programming in QNX, and I really haven’t a clue as to what is
obvious and what needs to be specifically stated.

The code creates two threads, a semaphore and a control thread. Inside the
semaphore thread, the semaphore is initialized using sem_init(). In the QNX
4 code, this was followed with a call to qnx_proxy_attach() to obtain the
process proxy id. Followed by a call to the scheduler, an initilization of
the sigevent and the semaphore tiimer, and calls to timer_create() and
timer_settime(). The thread “closed” with a while loop containing a call to
Receive(semaphore_proxy_id, 0, 0), and sem_post().

But proxies don’t exist in QNX 6, so I’ve been trying to use pulses with
limited success. I’ve substituted the code above with the following:

semaphore_channel_id = ChannelCreate(0);
ConnectAttach(0, semaphore_thread_id, semaphore_channel_id, 0, 0); // where
semaphore_thread_id is the process id obtained from the scheduler
param.sched_priority = 21;
sched_setscheduler(semaphore_thread_id, SCHED_FIFO, &param);
semaphore_event.sigev_signo = SIGEV_PULSE;
semaphore_timer_id = TimerCreate(CLOCK_REALTIME, &semaphore_event);
semaphore_timer_specs.nsec = 1L;
semaphore_timer_specs.interval_nsec = DTNSL;
TimerSettime(semaphore_timer_id, 0, &semaphore_timer_specs, NULL);
while (TRUE) {
MsgReceive(semaphore_channel_id, &msg, 1000, NULL); // msg is an
uninitialized int, and I chose 1000 arbitrarily
if ((sem_post(&_semaphore)) == -1){
printf (“Unable to post semaphore!\n”);
exit (1);
}
}

If there’s anything glaringly wrong with what I’m doing, please let me know.
I’m not even sure if the concept is correct.
Is creating a channel the correct way to go about this?
Should I be using MsgReceive()?
Am I not initilizing something correctly?
Am I using the timer functions correctly?

The code causes QNX to crash. I think the problem has to do with
MsgReceive(), but since it relies on the channel being created and
initilized correctly, I can’t be sure.

Also, if anyone knows of a good source that explains how to create threads
and setup timers like this in QNX 6, that would be very helpful. Are there
any books that explains this process?

Thanks in advance.

-Tom

Tom Worsnopp <GreyCloak@northwestern.edu> wrote:

I’m trying to port some code from QNX 4 to QNX 6.

In the online docs, take a look at the documentation for
sigevent – it describes the possible contents for the structure.

You may also find it helpful to read through the System Architecture
manual.

But proxies don’t exist in QNX 6, so I’ve been trying to use pulses with
limited success. I’ve substituted the code above with the following:

semaphore_channel_id = ChannelCreate(0);
ConnectAttach(0, semaphore_thread_id, semaphore_channel_id, 0, 0); // where
semaphore_thread_id is the process id obtained from the scheduler

Use 0 for “my pid”. Any time you call ConnectAttach() explicitly yourself
you should also always pass _NTO_SIDE_CHANNEL for the index, giving:

coid = ConnectAttach(0, 0, sem_chid, _NTO_SIDE_CHANNEL, 0 );

param.sched_priority = 21;
sched_setscheduler(semaphore_thread_id, SCHED_FIFO, &param);
semaphore_event.sigev_signo = SIGEV_PULSE;

Look at using SIGEV_PULSE_INIT() macro. You have a VERY incompletely
filled in pulse event structure here – in fact you don’t. You’ve
got a signal request that will try to give you a signal with whatever
number the macro SIGEV_PULSE happens to be.

semaphore_timer_id = TimerCreate(CLOCK_REALTIME, &semaphore_event);

Use the Posix timer functions – timer_create() not the kernel ones.

semaphore_timer_specs.nsec = 1L;
semaphore_timer_specs.interval_nsec = DTNSL;

How long is DTNSL?

TimerSettime(semaphore_timer_id, 0, &semaphore_timer_specs, NULL);

Use the Posix timer functions – timer_settime() not the kernel ones.

while (TRUE) {
MsgReceive(semaphore_channel_id, &msg, 1000, NULL); // msg is an
uninitialized int, and I chose 1000 arbitrarily

In receiving pulses, you should expect to receive a struct _pulse.
If msg is an int, you’ve just said receive up to 1000 bytes into
a 4 byte area – not a good idea.

You may, in fact, want to use MsgReceivePulse() instead of MsgReceive()
is you’re only getting pulses here.

if ((sem_post(&_semaphore)) == -1){
printf (“Unable to post semaphore!\n”);
exit (1);
}
}

If there’s anything glaringly wrong with what I’m doing, please let me know.
I’m not even sure if the concept is correct.

Lots of stuff. I’ve pointed you at a couple pieces of the docs that
might help on the QNX side.

The code causes QNX to crash. I think the problem has to do with
MsgReceive(), but since it relies on the channel being created and
initilized correctly, I can’t be sure.

Does it cause the OS to crash and reboot, or just your program?
If the OS, it is likely the bad values in the TimerCreate() or
TimerSettime() calls. If it is just your program, there’s lot
of choices.

Also, if anyone knows of a good source that explains how to create threads
and setup timers like this in QNX 6, that would be very helpful. Are there
any books that explains this process?

The QNX 6 timer and threads implementation is basically Posix. We extend the
timer/sigevent interface a little to support pulses, though. Look for
books on Posix or Posix threads programming.

-David

QNX Training Services
I do not answer technical questions by email.

Thank you so much for your reply. Your feedback has been very helpful.

It was the OS that was crashing, but after implementing the changes it
hasn’t.

DSTNL = 4995040L, approximately 5 milliseconds

MsgReceivePulse() still isn’t receiving a pulse, as far as I can tell, but
I’m working on it.

The thing that I’m most unsure of, at this point is the meaning of the last
two arguments passed to the SIGEV_PULSE_INIT() macro. I setup the macro as
follows:

SIGEV_PULSE_INIT(&semaphore_event, semaphore_connection_id, 21,
_PULSE_CODE_MINAVAIL, NULL);

Where semaphore_event is the sigev that is used in timer_create(),
semaphore_connection_id is the coid obtained from the ConnectAttach, and 21
is the same priority as the semaphore thread.
_PULSE_CODE_MINAVAIL was chosen arbitrarily, since I’m not sure what “code”
I’d need here. And NULL was chosen b/c I didn’t expect the “pulse handler”
to actually do anything with the pulse other than acknowledge its
occurrence.

Thanks again. =]

-Tom


“David Gibbs” <dagibbs@qnx.com> wrote in message
news:a2k61o$blk$1@nntp.qnx.com

Tom Worsnopp <> GreyCloak@northwestern.edu> > wrote:
I’m trying to port some code from QNX 4 to QNX 6.

In the online docs, take a look at the documentation for
sigevent – it describes the possible contents for the structure.

You may also find it helpful to read through the System Architecture
manual.

But proxies don’t exist in QNX 6, so I’ve been trying to use pulses with
limited success. I’ve substituted the code above with the following:

semaphore_channel_id = ChannelCreate(0);
ConnectAttach(0, semaphore_thread_id, semaphore_channel_id, 0, 0); //
where
semaphore_thread_id is the process id obtained from the scheduler

Use 0 for “my pid”. Any time you call ConnectAttach() explicitly yourself
you should also always pass _NTO_SIDE_CHANNEL for the index, giving:

coid = ConnectAttach(0, 0, sem_chid, _NTO_SIDE_CHANNEL, 0 );

param.sched_priority = 21;
sched_setscheduler(semaphore_thread_id, SCHED_FIFO, &param);
semaphore_event.sigev_signo = SIGEV_PULSE;

Look at using SIGEV_PULSE_INIT() macro. You have a VERY incompletely
filled in pulse event structure here – in fact you don’t. You’ve
got a signal request that will try to give you a signal with whatever
number the macro SIGEV_PULSE happens to be.

semaphore_timer_id = TimerCreate(CLOCK_REALTIME, &semaphore_event);

Use the Posix timer functions – timer_create() not the kernel ones.

semaphore_timer_specs.nsec = 1L;
semaphore_timer_specs.interval_nsec = DTNSL;

How long is DTNSL?

TimerSettime(semaphore_timer_id, 0, &semaphore_timer_specs, NULL);

Use the Posix timer functions – timer_settime() not the kernel ones.

while (TRUE) {
MsgReceive(semaphore_channel_id, &msg, 1000, NULL); // msg is an
uninitialized int, and I chose 1000 arbitrarily

In receiving pulses, you should expect to receive a struct _pulse.
If msg is an int, you’ve just said receive up to 1000 bytes into
a 4 byte area – not a good idea.

You may, in fact, want to use MsgReceivePulse() instead of MsgReceive()
is you’re only getting pulses here.

if ((sem_post(&_semaphore)) == -1){
printf (“Unable to post semaphore!\n”);
exit (1);
}
}

If there’s anything glaringly wrong with what I’m doing, please let me
know.
I’m not even sure if the concept is correct.

Lots of stuff. I’ve pointed you at a couple pieces of the docs that
might help on the QNX side.

The code causes QNX to crash. I think the problem has to do with
MsgReceive(), but since it relies on the channel being created and
initilized correctly, I can’t be sure.

Does it cause the OS to crash and reboot, or just your program?
If the OS, it is likely the bad values in the TimerCreate() or
TimerSettime() calls. If it is just your program, there’s lot
of choices.

Also, if anyone knows of a good source that explains how to create
threads
and setup timers like this in QNX 6, that would be very helpful. Are
there
any books that explains this process?

The QNX 6 timer and threads implementation is basically Posix. We extend
the
timer/sigevent interface a little to support pulses, though. Look for
books on Posix or Posix threads programming.

-David

QNX Training Services
I do not answer technical questions by email.

Tom Worsnopp <GreyCloak@northwestern.edu> wrote:

Thank you so much for your reply. Your feedback has been very helpful.

It was the OS that was crashing, but after implementing the changes it
hasn’t.

Do you have the original source code that crashed the OS still available?
If so, I’d like to get a copy to test here, and probably issue a PR
against.

DSTNL = 4995040L, approximately 5 milliseconds

Ok… just make sure it wasn’t some really tiny number… that might have
caused a bit of ugliness.

MsgReceivePulse() still isn’t receiving a pulse, as far as I can tell, but
I’m working on it.

When receiving a pulse, your receive buffer must be at least as large as
a struct _pulse. If it is not, the pulse will be discarded, and your
MsgReceivePulse() call will return a failure (-1).

The thing that I’m most unsure of, at this point is the meaning of the last
two arguments passed to the SIGEV_PULSE_INIT() macro. I setup the macro as
follows:

SIGEV_PULSE_INIT(&semaphore_event, semaphore_connection_id, 21,
_PULSE_CODE_MINAVAIL, NULL);

Where semaphore_event is the sigev that is used in timer_create(),
semaphore_connection_id is the coid obtained from the ConnectAttach, and 21
is the same priority as the semaphore thread.
_PULSE_CODE_MINAVAIL was chosen arbitrarily, since I’m not sure what “code”
I’d need here. And NULL was chosen b/c I didn’t expect the “pulse handler”
to actually do anything with the pulse other than acknowledge its
occurrence.

An incoming pulse is identified by a struct _pulse – and it can carry
up to 40 bits of data (39 user bits). This is broken down into a 8-bit
“code” field (usually used to identify what “type” of pulse it is, with
the high-bit reserved for OS messages) and a 32-bit “value” field, usually
used as additional data for this pulse.

You should be careful about assuming where your pulse comes from – right
now you may have only one source, but others may happen in the future.
The pulse code is generally used to determine where the pulse came from.

-David

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

I don’t have the original code, but I could reconstruct it for you if it
would be useful. Since it wasn’t working, I just replaced it.

Regarding the pulse code, you said that it is usually used to identify what
“type” of pulse it is. Where can I find out what types there are? Or is it
ok for me to just assign the code to MINAVAIL, and then if there are
different pulses to be handled, to assign MINAVAIL+1, MINAVAIL+2, etc. to
those?

Thanks.

-Tom


“David Gibbs” <dagibbs@qnx.com> wrote in message
news:a2n2f4$fmk$1@nntp.qnx.com

Tom Worsnopp <> GreyCloak@northwestern.edu> > wrote:
Thank you so much for your reply. Your feedback has been very helpful.

It was the OS that was crashing, but after implementing the changes it
hasn’t.

Do you have the original source code that crashed the OS still available?
If so, I’d like to get a copy to test here, and probably issue a PR
against.

DSTNL = 4995040L, approximately 5 milliseconds

Ok… just make sure it wasn’t some really tiny number… that might have
caused a bit of ugliness.

MsgReceivePulse() still isn’t receiving a pulse, as far as I can tell,
but
I’m working on it.

When receiving a pulse, your receive buffer must be at least as large as
a struct _pulse. If it is not, the pulse will be discarded, and your
MsgReceivePulse() call will return a failure (-1).

The thing that I’m most unsure of, at this point is the meaning of the
last
two arguments passed to the SIGEV_PULSE_INIT() macro. I setup the macro
as
follows:

SIGEV_PULSE_INIT(&semaphore_event, semaphore_connection_id, 21,
_PULSE_CODE_MINAVAIL, NULL);

Where semaphore_event is the sigev that is used in timer_create(),
semaphore_connection_id is the coid obtained from the ConnectAttach, and
21
is the same priority as the semaphore thread.
_PULSE_CODE_MINAVAIL was chosen arbitrarily, since I’m not sure what
“code”
I’d need here. And NULL was chosen b/c I didn’t expect the “pulse
handler”
to actually do anything with the pulse other than acknowledge its
occurrence.

An incoming pulse is identified by a struct _pulse – and it can carry
up to 40 bits of data (39 user bits). This is broken down into a 8-bit
“code” field (usually used to identify what “type” of pulse it is, with
the high-bit reserved for OS messages) and a 32-bit “value” field, usually
used as additional data for this pulse.

You should be careful about assuming where your pulse comes from – right
now you may have only one source, but others may happen in the future.
The pulse code is generally used to determine where the pulse came from.

-David

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

Tom Worsnopp <GreyCloak@northwestern.edu> wrote:

I don’t have the original code, but I could reconstruct it for you if it
would be useful. Since it wasn’t working, I just replaced it.

If it wouldn’t be too much trouble to recreate a self-contained sample,
I would appreciate it. If it crashes the OS, rather than just the program
doing the bad stuff it is probably something we want to investigate.

Regarding the pulse code, you said that it is usually used to identify what
“type” of pulse it is. Where can I find out what types there are? Or is it
ok for me to just assign the code to MINAVAIL, and then if there are
different pulses to be handled, to assign MINAVAIL+1, MINAVAIL+2, etc. to
those?

It is expected that you will assign to MINAVAIL, MINAVAI+1, etc.
Often, you will do stuff like:
#define TIMER_PULSE_CODE PULSE_CODE_MINAVAIL
#define ISR_PULSE_CODE PULSE_CODE_MINAVAIL+1
#define IO_NOTIFY_PULSE_CODE PULSE_CODE_MINAVAIL+2



There are a set of already defined pulses used by the system – they
are pulses with the high bit set. That is, they are outside the
range of PULSE_CODE_MINAVAIL to PULSE_CODE_MAXAVAIL. For examples
of some of the assigned pulses, check out the ChannelCreate() docs
where you can specify various flags to receive particular pulses.

-David

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

I’ve attached a copy of the code that crashes the OS. I think I’ve supplied
all of the definitions, etc. that are needed to compile and run it. I’ll
include the makefile, too. It was running from within a PhAB-generated GUI,
so you may need to modify the makefile before it’ll compile.

If you need anything else, let me know.

-Tom


“David Gibbs” <dagibbs@qnx.com> wrote in message
news:a2pd6n$6jh$1@nntp.qnx.com

Tom Worsnopp <> GreyCloak@northwestern.edu> > wrote:
I don’t have the original code, but I could reconstruct it for you if it
would be useful. Since it wasn’t working, I just replaced it.

If it wouldn’t be too much trouble to recreate a self-contained sample,
I would appreciate it. If it crashes the OS, rather than just the program
doing the bad stuff it is probably something we want to investigate.

Regarding the pulse code, you said that it is usually used to identify
what
“type” of pulse it is. Where can I find out what types there are? Or
is it
ok for me to just assign the code to MINAVAIL, and then if there are
different pulses to be handled, to assign MINAVAIL+1, MINAVAIL+2, etc.
to
those?

It is expected that you will assign to MINAVAIL, MINAVAI+1, etc.
Often, you will do stuff like:
#define TIMER_PULSE_CODE PULSE_CODE_MINAVAIL
#define ISR_PULSE_CODE PULSE_CODE_MINAVAIL+1
#define IO_NOTIFY_PULSE_CODE PULSE_CODE_MINAVAIL+2



There are a set of already defined pulses used by the system – they
are pulses with the high bit set. That is, they are outside the
range of PULSE_CODE_MINAVAIL to PULSE_CODE_MAXAVAIL. For examples
of some of the assigned pulses, check out the ChannelCreate() docs
where you can specify various flags to receive particular pulses.

-David

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

begin 666 utla.c
M+RHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
MBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJB-“B\J(” @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @("HO#0HO
B!#<F5A=&5D(" @,#$M,30M,C P
M,B @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" J+PT*+RH@36]D:69I960@(# Q+3$V+3(P,#(@(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @B-
M"B\J(%1O;2!7;W)S;F]P<" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @("HO#0HO
B @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" J+PT*+RHJBHJBHJBHJBHJBHJBHJ
MBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
M
BHJBHJBHJB-"@T+RHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
M
BHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
MB-“B\J(” @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @("HO#0HO
B @(" @
M(" @(" @(" @(" @(" @(" @(" @(" C:6YC;‘5D92!&:6QE<R @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" J+PT*+RH@(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @B-"B\JBHJBHJBHJBHJBHJBHJBHJBHJBHJ
MBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
M
BHO#0HC9&5F:6YE(%]?1T-#7T)524Q424X-"B-I;F-L=61E(#QS=&1I;RYH
M/@T*(VEN8VQU9&4@/’-T9&QI8BYH/@T*(VEN8VQU9&4@/‘5N:7-T9"YH/@T*
M(VEN8VQU9&4@/&UA=&@N:#X-"@T*+RH@2&5A9&5R<R!R97%U:7)E9"!F;W(@
M44Y8+7)E;&%T960@9G5N8W1I;VYS("HO#0HC:6YC;‘5D92 <’)O8V5S<RYH
M/@T*(VEN8VQU9&4@/’-T9&1E9BYH/@T*(VEN8VQU9&4@/’-I9VYA;“YH/@T*
M(VEN8VQU9&4@/‘1I;64N:#X-"B-I;F-L=61E(#QS>7,O<V-H960N:#X-"B-I
M;F-L=61E(#QE<G)N;RYH/@T*(VEN8VQU9&4@/’-E;6%P:&]R92YH/@T*(VEN
M8VQU9&4@/&UA;&QO8RYH/@T*(VEN8VQU9&4@/’-Y<R]M;6%N+F@^#0HC:6YC
M;'5D92 <WES+VYE=71R:6YO+F@^#0HC:6YC;'5D92 <‘1H<F5A9"YH/@T*
M(VEN8VQU9&4@/’-Y<R]N971M9W(N:#X-@T*+RH@4&A!0B!H96%D97)S(“HO
M#0HC:6YC;'5D92 B86)L:6)S+F@B#0HC:6YC;'5D92 B86)I;7!O<G0N:”(-
M"B-I;F-L=61E(")P<F]T;RYH(@T*#0HOBHJBHJBHJBHJBHJBHJBHJ
M
BHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
MBHJBHJBHJ+PT+RH@(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @B-
M"B\J(" @(" @(" @(" @(" @(" @(" @(" @(" @($=L;V)A;’,@(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @("HO#0HO
B @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" J+PT*+RHJBHJBHJBHJBHJBHJBHJ
MBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
M
BHJBHJBHJB-"G1Y<&5D968@<W1R=6-T>PT"61O=6)L92!A;F=L95LS
M73L-"@ED;W5B;&4@96QB;W=?<&]S6S)=.PT*“61O=6)L92!E;F1P=%]P;W-;
M,ET#0I7T1!5$$[#0H-“E194$5?1U5)7T1!5$$@9W5I7V1A
M=&$[#0H-“G-E;5]T(%]S96UA<&AO<F4[#0IP=&AR96%D7W0@<V5M87!H;W)E
M7W1H<F5A9%]I9#L-“G!T:’)E861?=”!C;VYT<F]L7W1H<F5A9%]I9#L-”@T*
M+RH@07!P;&EC871I;VX@3W!T:6]N<R!S=’)I;F<@B-“F-O;G-T(&-H87(@
M07!/<'1I;VYS6UT@/2!!0E]/4%1)3TY3(”(B.R O
B!!9&0@>6]U<B!O<'1I
M;VYS(&EN('1H92 B(B J+PT*#0HOBHJBHJBHJBHJBHJBHJBHJBHJ
MBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
M
BHJBHJ+PT+RH@(” @(” @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @B-“B\J
M(” @(" @(" @(" @(" @(" @(" @(" @(" @4’)O=&]T>7!E<R @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @("HO#0HO
B @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" J+PT*+RHJBHJBHJBHJBHJBHJBHJBHJ
M
BHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
MBHJBHJB-"@T=F]I9"!S=&%R=%1H<F5A9’,H3L-"G9O:60@<W1A<G13
M96UA<&AO<F54:’)E860H
3L-“G9O:60@<W1A<G1#;VYT<F]L5&AR96%D*“D[
M#0H-“B\JBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
M
BHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHO#0HOB @(” @
M(” @(” @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" J+PT*+RH@(" @(" @(" @(" @(" @
M(" @(" @(" @(" @36%I;B @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @B-“B\J(” @(" @(" @(" @(" @(" @(" @(" @(" @
M(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @(" @
M("HO#0HO
BHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ
MBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHJ+PT*:6YT(‘5T
M;&$H:6YT(&%R9V,L(&-H87(@F%R9W9;72E[#0H@("\J(%!H04(@4W1U9F8@
M=&@(F5L:6UI;F%T92 G=6YR969E<F5N8V5D)R!W87)N:6YG<R(@B-"B @
M87)G8R ](&%R9V,L(&%R9W8@/2!A<F=V.PT
#0H@(’-T87)T5&AR96%D<R@I
M.PT
(" -“B @+RH@36]R92!0:$%”(%-T=69F("HO#0H@(’)E=‘5R;B@@4’1?
M0T].5$E.544@3L-“GT-”@T+RHJBHJBHJBHJBHJBHJ+PT+RH@4W1A
M<G0@5&AR96%D<R J+PT*+RHJBHJBHJBHJBHJBHJ+PT=F]I9"!S=&%R
M=%1H<F5A9’,H7L-“B @<W1R=6-T(%]C;&]C:W!E<FEO9”!C;&]C:U]P97)I
M;V0[#0H@(&-H87()B!S96UA<&AO<F5?<W1A8VL[#0H@(&-H87()B!C;VYT
M<F]L7W-T86-K.PT
("!I;G0@<W1A8VM?<VEZ92 ](#(P-#@[#0H@(’!T:’)E
M861?871T<E]T(&%T=’([#0H@(’-T<G5C="!S8VAE9%]P87)A;2!P87)A;3L-
M"@D)"0T
(" O
B!S970@:6YT97)N86P@8VQO8VL@<F%T92 J+PT*("!C;&]C
M:U]P97)I;V0N;G-E8R ](#4P,# P,#L-“B @:68H0VQO8VM097)I;V0H0TQ/
M0TM?4D5!3%1)344L)F-L;V-K7W!E<FEO9"Q.54Q,+# I(#T](“TQ2![#0H@
M(" @<’)I;G1F
”)F86EL960@=&@<V5T(&-L;V-K(’!E<FEO9%QN(BD[#0H@
M(” @97AI="@P3L-"B @?0T#0H@(’!A<F%M+G-C:&5D7W!R:6]R:71Y(#T@
M,C4[#0H@(’-C:&5D7W-E=’-C:&5D=6QE<B@P+%-#2$5$7T9)1D\L)G!A<F%M
M3L-“B @#0H@(”\J(’-T87)T(’-I;75L871I;VY?<V5M87!H;W)E7W1H<F5A
M9" M(‘1H92!T:’)E860@=&AA="!P;W-T<R!T:&4@<V5M87!H;W)E("HO#0H@
M(’-E;6%P:&]R95]S=&%C:R ](&UA;&QO8R H<W1A8VM?<VEZ92D[#0H@(’!T
M:’)E861?871T<E]I;FET
"9A=‘1R3L-"B @<‘1H<F5A9%]A=‘1R7W-E=’-T
M86-K861D<B@F871T<BP@)G-E;6%P:&]R95]S=&%C:RD[#0H@(’!T:’)E861?
M871T<E]S971S=&%C:W-I>F4H)F%T=’(L(’-T86-K7W-I>F4I.PT
("!P=&AR
M96%D7V-R96%T92@F<V5M87!H;W)E7W1H<F5A9%]I9"P@)F%T=’(L(“AV;VED
MBES=&%R=%-E;6%P:&]R951H<F5A9"P@,“D[#0H@(’!A<F%M+G-C:&5D7W!R
M:6]R:71Y(#T@,CD[#0H@(’-C:&5D7W-E=’-C:&5D=6QE<BAS96UA<&AO<F5?
M=&AR96%D7VED+”!30TA%1%]&249/+" F<&%R86TI.PT
(” -“B @+RH@<W1A
M<G0@<VEM=6QA=&EO;B!T:’)E860@+2!T:&4@=&AR96%D(‘1H870@<G5N<R!T
M:&4@8V]N=’)O;”!L;V]P(“HO#0H@(&-O;G1R;VQ?<W1A8VL@/2 H8VAA<B J
M2!C86QL;V,@#$L.“IS=&%C:U]S:7IE3L-"B @<'1H<F5A9%]A=‘1R7W-E
M=’-T86-K861D<B@F871T<BP@)F-O;G1R;VQ?<W1A8VLI.PT
(”!P=&AR96%D
M7V%T=’)?<V5T<W1A8VMS:7IE*“9A='1R+” XG-T86-K7W-I>F4I.PT(”!P
M=&AR96%D7V-R96%T92@F8V]N=’)O;%]T:’)E861?:60L(“9A='1R+” H=F]I
M9"HI<W1A<G1#;VYT<F]L5&AR96%D+" P3L-"B @<&%R86TN<V-H961?<’)I
M;W)I='D@/2 R.#L-"B @<V-H961?<V5T<V-H961U;&5R
&-O;G1R;VQ?=&AR
M96%D7VED+"!30TA%1%]&249/+" F<&%R86TI.PT*("!I9B H8V]N=’)O;%]T
M:’)E861?:60@/3T@+3$I(‘L-“B @(”!P<FEN=&8@")#;W5L9&XG="!S=&%R
M="!C;VYT<F]L('1H<F5A9"%<;B(I.PT
(" @(&5X:70@#$I.PT("!]#0I]
M#0H-"@T*+RHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHO#0HOB @
M(" @4V5M87!H;W)E(%1H<F5A9" @(" @(" @B-"B\JBHJ
BHJBHJBHJ
MBHJBHJBHJBHJBHJBHJ+PT*=F]I9"!S=&%R=%-E;6%P:&]R951H<F5A
M9"@I>PT*(" OB!T:&ES(‘1H<F5A9"!I<R!T:&4@<V5M87!H;W)E(’!O<W1E
M<B!T:&%T(’-I;75L871I;VY?=&AR96%D(’=A:71S(&9O<B J+PT
("!T:6UE
M<E]T(’-E;6%P:&]R95]T:6UE<E]I9#L-“B @<W1R=6-T(’-I9V5V96YT(’-E
M;6%P:&]R95]E=F5N=#L-“B @<W1R=6-T(%]I=&EM97(@<V5M87!H;W)E7W1I
M;65R7W-P96-S.PT*(”!I;G0@<V5M87!H;W)E7V-H86YN96Q?:60[#0H@(&EN
M=”!M<V<[#0H@(’-T<G5C="!S8VAE9%]P87)A;2!P87)A;3L-“B @#0H@(&EF
M(”@H<V5M7VEN:70H)E]S96UA<&AO<F4L(#$L(# I2 ]/2 M,2D@>PT(" @
M(’!R:6YT9B H(E-E;6%P:&]R92!I;FET:6%L:7IA=&EO;B!F86EL=7)E(5QN
M(BD[#0H@(" @97AI=" H,2D[#0H@(‘T-"B @#0H@(’-E;6%P:&]R95]C:&%N
M;F5L7VED(#T@0VAA;FYE;$-R96%T92@P3L-“B @0V]N;F5C=$%T=&%C:”@P
M+"!S96UA<&AO<F5?=&AR96%D7VED+"!S96UA<&AO<F5?8VAA;FYE;%]I9"P@
M,“P@,“D[#0H@(’!A<F%M+G-C:&5D7W!R:6]R:71Y(#T@,CD[#0H@(’-C:&5D
M7W-E=’-C:&5D=6QE<BAS96UA<&AO<F5?=&AR96%D7VED+”!30TA%1%]&249/
M+” F<&%R86TI.PT
("!S96UA<&AO<F5?979E;G0N<VEG979?<VEG;F@/2!3
M24=%5E]054Q313L-“B @<V5M87!H;W)E7W1I;65R7VED(#T@5&EM97)#<F5A
M=&4H0TQ/0TM?4D5!3%1)344L(“9S96UA<&AO<F5?979E;G0I.PT*(”!S96UA
M<&AO<F5?=&EM97)?<W!E8W,N;G-E8R ](#%,.PT*(”!S96UA<&AO<F5?=&EM
M97)?<W!E8W,N:6YT97)V86Q?;G-E8R ](#0Y.34P-#!,.PT*("!4:6UE<E-E
M=‘1I;64H<V5M87!H;W)E7W1I;65R7VED+" P+" F<V5M87!H;W)E7W1I;65R
M7W-P96-S+"!.54Q,3L-“B @#0H@(’=H:6QE(”@Q2![#0H@(" @37-G4F5C
M96EV92AS96UA<&AO<F5?8VAA;FYE;%]I9"P@)FUS9RP@,3 P,“P@3E5,3"D[
M#0H@(” @:68@“AS96U?<&]S=”@F7W-E;6%P:&]R92DI(#T]("TQ7L-“B @
M(” @(’!R:6YT9B H(E5N86)L92!T;R!P;W-T(’-E;6%P:&]R92%<;B(I.PT*
M(" @(" @97AI=" H,2D[#0H@(" @?0T*("!]#0I]#0H-“B\JBHJBHJBHJ
M
BHJBHJBHJBHJBHJBHJBHJ+PT*+RH@(” @($-O;G1R;VP@5&AR96%D
M(" @(" @(" J+PT*+RHJBHJBHJBHJBHJBHJBHJBHJBHJBHJBHO
M#0IV;VED(’-T87)T0V]N=’)O;%1H<F5A9"@I>PT*(" OB!T:&ES(‘1H<F5A
M9"!I<R!T:&4@<VEM=6QA=&EO;B!T:’)E860@=&AA="!E>&5C=71E<R!A=" Q
M+T14(&AE<G1Z(’=A:71I;F<@9F]R(’-I;75L871I;VY?<V5M87!H;W)E7W1H
M<F5A9" J+PT
("!W:&EL92 H,2D@>PT*(" @("\J(’=A:70@9F]R(’-I;75L
M871I;VY?<V5M87!H;W)E7W1H<F5A9"!T;R!P;W-T(“HO#0H@(” @<V5M7W=A
::70H)E]S96UA<&AO<F4I.PT*("!]#0I]#0H
end

begin 666 Makefile.dat
M(PHC($%P<&QI8V%T:6]N($UA:V5F:6QE(" @“B,"FEF9&5F($1"1PI$0D=?
M4D5,14%312 ]("U/,R M9F]M:70M9G)A;64M<&]I;G1E<@I$0D=?1$5"54<@
M/2 M3R M9V1W87)F+3(1$5"54<])"A$0D=?)"A$0D<I0IE;F1I9@H
:69N
M9&5F($1%0E5’“D1%0E5’(#T@+6<96YD:68"FEF;F1E9B!/4%1)30I/4%1)
M32 ](“U/“F5N9&EF”@II;F-L=61E"2XN+V%B3V9I;&5S"FEN8VQU9&4@+BXO
M:6YD3V9I;&5S”@II;F-L=61E"2XN+V%B4V9I;&5S"FEN8VQU9&4@+BXO:6YD
M4V9I;&5S”@II;F-L=61E"2XN+V%B2&9I;&5S"FEN8VQU9&4@+BXO:6YD2&9I
M;&5S”@II;F-L=61E"2XN+V%B5V9I;&5S"FEN8VQU9&4)+BXO86),9FEL97,*
M"E!,051&3U)-/6=C8U]N=&]X.#84$A!0D]05%,]( H0T,@(#T@<6-C"D-8
M6" ](’%C8PI,1" @/2!Q8V,"D-&3$%'4R @/2 M9R M5B0H4$Q!5$9/4DTI
M("UW-2 D
$]05$E-2 D$1%0E5’2 D%!(04)/4%132 M22X0UA81DQ!
M1U,@/2 D*$-&3$%‘4RD3$1&3$%'4R ]("U6)"A03$%41D]232D@+4)S=&%T
M:6,@)"A$14)51RD@+6P@<&AE>&QI8B D
$%“3$E"2 D%!(04)/4%130I3
M1$9,04=3(#T@+58D
%!,051&3U)-2 @(" @(" @(" D$1%0E5’2 M;"!P
M:&5X;&EB(“0H04),24(I(“0H4$A!0D]05%,I”@I64$%42” ](“XN”@HC"B,@
M07!P;&EC871I;VX@4’)O9W)A;0HC"@IS:’(Z"20H04)/0DHI(“0H35E/0DHI
M”@D))"A,1"D@+6<@)"A!0D]"2BD@)"A-64]"2BD@)"A31$9,04=3
2 M32 M
M;R!U=&QA”@D)=7-E;7-G(‘5T;&$@+BXO57-E;7-G"@D)<&AA8F)I;F0@=71L
M82 D*$%"34]$0H87!P.@DD*$%"3T)*2 D$U93T)0H)"20H3$0I("UG
M("0H04)/0DHI("0H35E/0DHI("0H3$1&3$%'4RD@+4T@+6@=71L80H)"75S
M96US9R!U=&QA("XN+U5S96US9PH)"7!H86)B:6YD('5T;&$@)"A!0DU/1"D

M"F-L96%N.@H)“7)M(“UF(“HN;R J+F5R<B J+FUA<”!U=&QA”@II;G-T86QL
M.@H)“2UC<” M=FYF('5T;&$@+W5S<B]P:&]T;VXO8FEN”@HC"B,@2&5A9&5R
M<PHC"@HD
$%"3T)*2 D$U93T)*3H))"A-64A$4BD"B,(R!0<F]T;W1Y
M<&4@1V5N97)A=&EO;@HC"@IP<F]T;SH
"0EA<’!R;W1O("UP("0H04)34D,I
4("0H35E34D,I(#X@<’)O=&\N: H
end

Tom Worsnopp <GreyCloak@northwestern.edu> wrote:

I’ve attached a copy of the code that crashes the OS. I think I’ve supplied
all of the definitions, etc. that are needed to compile and run it. I’ll
include the makefile, too. It was running from within a PhAB-generated GUI,
so you may need to modify the makefile before it’ll compile.

If you need anything else, let me know.

I’ll take a shot at running this.

-David

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

Tom Worsnopp <GreyCloak@northwestern.edu> wrote:

Just looking through the code.

/* set internal clock rate */
clock_period.nsec = 500000;
if(ClockPeriod(CLOCK_REALTIME,&clock_period,NULL,0) == -1) {

The comment suggests something might be unclear – ClockPeriod sets
a system-wide value, not an internal to a thread or process value.

Basically, it resets the frequency of the timer interrupt (irq 0
on x86).

Hm…also no main() in the program… I’m gonna try utla() as
main().

-David

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

Tom Worsnopp <GreyCloak@northwestern.edu> wrote:

I’ve attached a copy of the code that crashes the OS. I think I’ve supplied
all of the definitions, etc. that are needed to compile and run it. I’ll
include the makefile, too. It was running from within a PhAB-generated GUI,
so you may need to modify the makefile before it’ll compile.

Ok, tested it. It doesn’t crash the OS. It preempts you.

What it does is end up running a thread at a higher
priority than the GUI, or anything else you would normally run.
This thread ends up using all the CPU at priority 29 or so,
and so you never get a chance to run anything else. The OS
is still happy, doing what it is supposed to do.

Thanks for sending the sample code.

-David

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

Actually /set internal clock rate/ isn’t a related comment. When I was
reconstructing the code to send you, that got left behind from the QNX4 code
I have been porting (the comment wasn’t really correct for the QNX4 code,
either).

utla() was acting as the main() function…but based on your next message,
you found that out

Btw, I’ve got working code now. Thanks for all of your help. =]

-Tom

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:a2q2ev$mpc$1@nntp.qnx.com

Tom Worsnopp <> GreyCloak@northwestern.edu> > wrote:

Just looking through the code.

/* set internal clock rate */
clock_period.nsec = 500000;
if(ClockPeriod(CLOCK_REALTIME,&clock_period,NULL,0) == -1) {

The comment suggests something might be unclear – ClockPeriod sets
a system-wide value, not an internal to a thread or process value.

Basically, it resets the frequency of the timer interrupt (irq 0
on x86).

Hm…also no main() in the program… I’m gonna try utla() as
main().

-David

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