Replacing Trigger()'d proxy with Pulse

I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.

So far, I have done a ChannelCreate() in the process that needs
triggered, and stored the chid and the pid of that process in variables
in shared memory.

In the process that is going to do the triggering (or pulsing), I use
the pid and chid from shared memory to do a ConnectAttach() creating a
locally stored coid. The example code that I have found through the
helpviewer shows the index parameter with an _NTO_SIDE_CHANNEL passed.
The description says to OR it with your choice of index. Also talks
about picking a value between some min and max defines. What does it
mean to just pass the side channel define without or’ing it to some
index, and how do you choose the index other than picking one out of the
blue between the min and max defines.

Also, in the MsgSendPulse() call (to replace the call to Trigger()), I
pass the coid as the first parameter, but how do I choose a priority,
code, and value to send?

I don’t want to pass any data over with this pulse. I just want it to
indicate to the receiving process, that its time to execute a certain
function. I can do this, just by knowing where this pulse came from,
and receiving it in my MsgReceive() loop (at which point it returns a 0
to indicate its a pulse, according the docs I read). Before I new where
the message came from because the pid of the sending process was
returned right? Now it has to go in the value parameter?

Is this stuff much more complicated to set up than in QNX4, or is it
just me, hit the learning curve with no breaks? ;o)

Scott

J. Scott Franko <jsfranko@switch.com> wrote:

I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.

So far, I have done a ChannelCreate() in the process that needs
triggered, and stored the chid and the pid of that process in variables
in shared memory.

In the process that is going to do the triggering (or pulsing), I use
the pid and chid from shared memory to do a ConnectAttach() creating a
locally stored coid. The example code that I have found through the
helpviewer shows the index parameter with an _NTO_SIDE_CHANNEL passed.
The description says to OR it with your choice of index. Also talks
about picking a value between some min and max defines. What does it
mean to just pass the side channel define without or’ing it to some
index, and how do you choose the index other than picking one out of the
blue between the min and max defines.

You must have a very old version of the docs, I’ve never heard of
min and max defines for the index. Just put _NTO_SIDE_CHANNEL.
Here’s a snippet from the current docs for ConnectAttach() that
explains why.

← starts here ---------------------------------------------->
Connections being treated as file descriptors can lead to unexpected
behaviour. Therefore, you should OR _NTO_SIDE_CHANNEL into index when
you create a connection. This results in the connection ID being
returned from a different space than file descriptors. The ID is greater
than any valid file descriptor. Once created there’s no difference in
the use of the messaging primitives on this ID. The C library creates
connections at various times without _NTO_SIDE_CHANNEL (e.g. during
open()), however, it’s unlikely that any applications would want to call
it this way. The following explains some behaviour that results if
_NTO_SIDE_CHANNEL is left off:

  • If file descriptor 0 is in use and file descriptor 1 isn’t in use, when
    you call ConnectAttach() with 0 specified for index, a connection id of
    1 is returned. Note that file descriptor 1 (i.e. connection id 1) is
    used as stdout which is what printf() writes to. So if your process
    makes any calls to printf(), NULL terminated character strings will be
    sent to the channel that you’ve connected to! Similar situations can
    happen with connection ids 0 (stdin) and 2 (stderr).

  • Depending on how a child process is created, it may inherit the parent’s
    file descriptors. Since connections are treated like file descriptors, a
    connection created by the parent without _NTO_SIDE_CHANNEL in index and
    without _NTO_COF_CLOEXEC in flags, causes a child process to inherit
    that connection during process creation. This inheritance is done during
    process creation by duplicating file descriptors. During duplication, an
    _IO_DUP message (the first 2 bytes are 0x115) is sent to the receiver on
    the other side of the connection. Note that the receiver won’t be
    expecting this message!
    ← ends here ------------------------------------------------>

Also, in the MsgSendPulse() call (to replace the call to Trigger()), I
pass the coid as the first parameter, but how do I choose a priority,
code, and value to send?

The ‘priority’ is like the proxy priority in QNX 4. It controls where
the pulse gets inserted into the receiver’s queue of messages to
receive.

The ‘code’ is typically used as a pulse message type. This is the
same as putting a message in a proxy message buffer for the proxy
to send. The difference is that if your receiver is receiving
more than one different type of pulse then you must use the code
as a pulse message type. In QNX 4 you didn’t need to do this
sort of thing since the receiver could use the proxy id to distinguish
between different types of proxies. The code must be in the
range _PULSE_CODE_MINAVAIL to _PULSE_CODE_MAXAVAIL.

In QNX 4 the proxy data was fixed at the time you created the
proxy. In Neutrino, ‘value’ is your data and it can be different
each time the pulse is sent.

I don’t want to pass any data over with this pulse. I just want it to
indicate to the receiving process, that its time to execute a certain
function. I can do this, just by knowing where this pulse came from,
and receiving it in my MsgReceive() loop (at which point it returns a 0
to indicate its a pulse, according the docs I read). Before I new where
the message came from because the pid of the sending process was
returned right? Now it has to go in the value parameter?

The code parameter. See my comments above re this.

Is this stuff much more complicated to set up than in QNX4, or is it
just me, hit the learning curve with no breaks? ;o)

Scott

Steven Dufresne wrote:

J. Scott Franko <> jsfranko@switch.com> > wrote:
I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.

So far, I have done a ChannelCreate() in the process that needs
triggered, and stored the chid and the pid of that process in variables
in shared memory.

In the process that is going to do the triggering (or pulsing), I use
the pid and chid from shared memory to do a ConnectAttach() creating a
locally stored coid. The example code that I have found through the
helpviewer shows the index parameter with an _NTO_SIDE_CHANNEL passed.
The description says to OR it with your choice of index. Also talks
about picking a value between some min and max defines. What does it
mean to just pass the side channel define without or’ing it to some
index, and how do you choose the index other than picking one out of the
blue between the min and max defines.

You must have a very old version of the docs, I’ve never heard of
min and max defines for the index. Just put _NTO_SIDE_CHANNEL.
Here’s a snippet from the current docs for ConnectAttach() that
explains why.

I may have confused index having min/max values, with pulse code, now that I
have re-read the excerpts you posted. What I’m trying to figure out here, is
that the docs say to OR _NTO_SIDE_CHANNEL into your index. If you all the
calls to ConnectAttach just pass _NTO_SIDE_CHANNEL across as the index, what
need is their for the index parameter? Or, are there other criteria for
choosing an index? All examples just pass _NTO_SIDE_CHANNEL, but the doc
excerpt below says to OR it in, without describing what the index is for or
how to choose one. I’m just looking for clarification in the docs. Right now
I’ve got it coded to pass the side channel (whatever the heck a side channel
is)…

  • starts here ----------------------------------------------
    Connections being treated as file descriptors can lead to unexpected
    behaviour. Therefore, you should OR _NTO_SIDE_CHANNEL into index when
    you create a connection. This results in the connection ID being
    returned from a different space than file descriptors. The ID is greater

Would I ever want a coid in the same space as the file descripters? I
understand that I might now want it to conflict with stdin/stdout, but why do
I have a choice here? Could this be explained a little better in the docs?

than any valid file descriptor. Once created there’s no difference in
the use of the messaging primitives on this ID. The C library creates
connections at various times without _NTO_SIDE_CHANNEL (e.g. during
open()), however, it’s unlikely that any applications would want to call
it this way. The following explains some behaviour that results if
_NTO_SIDE_CHANNEL is left off:

  • If file descriptor 0 is in use and file descriptor 1 isn’t in use, when
    you call ConnectAttach() with 0 specified for index, a connection id of
    1 is returned. Note that file descriptor 1 (i.e. connection id 1) is
    used as stdout which is what printf() writes to. So if your process
    makes any calls to printf(), NULL terminated character strings will be
    sent to the channel that you’ve connected to! Similar situations can
    happen with connection ids 0 (stdin) and 2 (stderr).

  • Depending on how a child process is created, it may inherit the parent’s
    file descriptors. Since connections are treated like file descriptors, a
    connection created by the parent without _NTO_SIDE_CHANNEL in index and
    without _NTO_COF_CLOEXEC in flags, causes a child process to inherit
    that connection during process creation. This inheritance is done during
    process creation by duplicating file descriptors. During duplication, an
    _IO_DUP message (the first 2 bytes are 0x115) is sent to the receiver on
    the other side of the connection. Note that the receiver won’t be
    expecting this message!

  • ends here ------------------------------------------------

Also, in the MsgSendPulse() call (to replace the call to Trigger()), I
pass the coid as the first parameter, but how do I choose a priority,
code, and value to send?

The ‘priority’ is like the proxy priority in QNX 4. It controls where
the pulse gets inserted into the receiver’s queue of messages to
receive.

In QNX4, we use a -1 on the qnx_proxy_attach to obtain the same priority as
the calling process. In NTO, the priority is on the MsgSendPulse (like
Trigger), and the docs don’t describe a way to do the same thing. The mention
the use of sched_get_priority_min and _max, but they don’t mention the use of
-1. There was no calls in QNX4 to get min/max depending on scheduling
method. Again, more choices, and I don’t see enough info in the docs to help
me make the choice.

The ‘code’ is typically used as a pulse message type. This is the
same as putting a message in a proxy message buffer for the proxy
to send. The difference is that if your receiver is receiving
more than one different type of pulse then you must use the code
as a pulse message type. In QNX 4 you didn’t need to do this
sort of thing since the receiver could use the proxy id to distinguish
between different types of proxies. The code must be in the
range _PULSE_CODE_MINAVAIL to _PULSE_CODE_MAXAVAIL.

In QNX 4 the proxy data was fixed at the time you created the
proxy. In Neutrino, ‘value’ is your data and it can be different
each time the pulse is sent.

I don’t want to pass any data over with this pulse. I just want it to
indicate to the receiving process, that its time to execute a certain
function. I can do this, just by knowing where this pulse came from,
and receiving it in my MsgReceive() loop (at which point it returns a 0
to indicate its a pulse, according the docs I read). Before I new where
the message came from because the pid of the sending process was
returned right? Now it has to go in the value parameter?

The code parameter. See my comments above re this.

So If I wanted, I could pass the pid of the MsgSendPulse process over as the
code, and pass the value as zero?

Is this stuff much more complicated to set up than in QNX4, or is it
just me, hit the learning curve with no breaks? ;o)

Scott

I’ll add your questions to my todo list… I’ll talk to Steven to see
how we can enhance the docs accordingly.
-Donna

J. Scott Franko <jsfranko@switch.com> wrote:

Steven Dufresne wrote:

J. Scott Franko <> jsfranko@switch.com> > wrote:
I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.


I may have confused index having min/max values, with pulse code, now that I
have re-read the excerpts you posted. What I’m trying to figure out here, is
that the docs say to OR _NTO_SIDE_CHANNEL into your index. If you all the
calls to ConnectAttach just pass _NTO_SIDE_CHANNEL across as the index, what
need is their for the index parameter? Or, are there other criteria for
choosing an index? All examples just pass _NTO_SIDE_CHANNEL, but the doc
excerpt below says to OR it in, without describing what the index is for or
how to choose one. I’m just looking for clarification in the docs. Right now
I’ve got it coded to pass the side channel (whatever the heck a side channel
is)…

[snip]

Would I ever want a coid in the same space as the file descripters? I
understand that I might now want it to conflict with stdin/stdout, but why do
I have a choice here? Could this be explained a little better in the docs?

J. Scott Franko <jsfranko@switch.com> wrote:

Steven Dufresne wrote:
J. Scott Franko <> jsfranko@switch.com> > wrote:
I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.
snip
What I’m trying to figure out here, is
that the docs say to OR _NTO_SIDE_CHANNEL into your index. If you all the
calls to ConnectAttach just pass _NTO_SIDE_CHANNEL across as the index, what
need is their for the index parameter? Or, are there other criteria for
choosing an index? All examples just pass _NTO_SIDE_CHANNEL, but the doc
excerpt below says to OR it in, without describing what the index is for or
how to choose one. I’m just looking for clarification in the docs. Right now
I’ve got it coded to pass the side channel (whatever the heck a side channel
is)…
snip
Would I ever want a coid in the same space as the file descripters? I
understand that I might now want it to conflict with stdin/stdout, but why do
I have a choice here? Could this be explained a little better in the docs?

open() is the only thing that does not set _NTO_SIDE_CHANNEL (open()
calls ConnectAttach()). In all other cases, put _NTO_SIDE_CHANNEL
to avoid the problems mentioned in the docs. I’ll ask docs to
remove the OR. In fact, if you give the _NTO_SIDE_CHANNEL bits
then the kernel does:

if (index & _NTO_SIDE_CHANNEL)
index = _NTO_SIDE_CHANNEL;

Why isn’t _NTO_SIDE_CHANNEL the default? Because the API is frozen
so much to our regret, we cannot make it the default (or get rid
of the parameter altogether). The reason for the docs mentioning
all the bad things that happen when you don’t put _NTO_SIDE_CHANNEL
is so that if anyone forgets to put _NTO_SIDE_CHANNEL, hopefully
they’ll remember having read the explanation and put _NTO_SIDE_CHANNEL.

Also, in the MsgSendPulse() call (to replace the call to Trigger()), I
pass the coid as the first parameter, but how do I choose a priority,
code, and value to send?

The ‘priority’ is like the proxy priority in QNX 4. It controls where
the pulse gets inserted into the receiver’s queue of messages to
receive.

In QNX4, we use a -1 on the qnx_proxy_attach to obtain the same priority as
the calling process. In NTO, the priority is on the MsgSendPulse (like
Trigger), and the docs don’t describe a way to do the same thing. The mention
the use of sched_get_priority_min and _max, but they don’t mention the use of
-1. There was no calls in QNX4 to get min/max depending on scheduling
method. Again, more choices, and I don’t see enough info in the docs to help
me make the choice.

It sounds like in QNX 4 you are doing:

Process 1 Process 2


proxy = qnx_proxy_attach(…, -1)
Send() proxy to process 2 Receive() and store away proxy
while (1) {
pid = Receive() Trigger(proxy)
if (pid == proxy)

}

To acheive the same thing in QNX Neutrino:

Process 1 Process 2


SIGEV_PULSE_INIT(&event, coid, -1, …)
MsgSend() event to process 2 MsgReceive() and store away
rcvid and event
while (1) {
rcvid = MsgReceive() MsgDeliverEvent(rcvid, &event)
if (rcvid == 0)

}

Note that in QNX Neutrino, the receiver of the pulse floats to the
priority of the pulse. If you do as above and set the priority
to -1 then it is irrelevant. Actually in general the receiver of
any message floats to the priority of the sender. This was setable
in QNX 4 via the _PPF_PRIO_FLOAT flag for qnx_pflags(). If you don’t
want this then turn it off on the receiver’s channel using the
_NTO_CHF_PRIO_FIXED flag for ChannelCreate().

The ‘code’ is typically used as a pulse message type. This is the
same as putting a message in a proxy message buffer for the proxy
to send. The difference is that if your receiver is receiving
more than one different type of pulse then you must use the code
as a pulse message type. In QNX 4 you didn’t need to do this
sort of thing since the receiver could use the proxy id to distinguish
between different types of proxies. The code must be in the
range _PULSE_CODE_MINAVAIL to _PULSE_CODE_MAXAVAIL.

In QNX 4 the proxy data was fixed at the time you created the
proxy. In Neutrino, ‘value’ is your data and it can be different
each time the pulse is sent.

I don’t want to pass any data over with this pulse. I just want it to
indicate to the receiving process, that its time to execute a certain
function. I can do this, just by knowing where this pulse came from,
and receiving it in my MsgReceive() loop (at which point it returns a 0
to indicate its a pulse, according the docs I read). Before I new where
the message came from because the pid of the sending process was
returned right? Now it has to go in the value parameter?

The code parameter. See my comments above re this.

So If I wanted, I could pass the pid of the MsgSendPulse process over as the
code, and pass the value as zero?

Sure. The only hitch I can see is if at some time the receiver would
be receiving pulses from the kernel (see ChannelCreate() flags).
Who knows? Probably best to hedge your bets for the future and
make up a code to use for all your pulses and put the pid in value.
Even putting pid may not be such a good idea. What if receiver
can receive message from different nodes of the native Neutrino
network? In that case there might be pulse senders on two different
nodes but with the same pid. It may not apply to you but just in case…

Is this stuff much more complicated to set up than in QNX4, or is it
just me, hit the learning curve with no breaks? ;o)

Scott

Steven Dufresne wrote:

J. Scott Franko <> jsfranko@switch.com> > wrote:
Steven Dufresne wrote:
J. Scott Franko <> jsfranko@switch.com> > wrote:
I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.
snip
What I’m trying to figure out here, is
that the docs say to OR _NTO_SIDE_CHANNEL into your index. If you all the
calls to ConnectAttach just pass _NTO_SIDE_CHANNEL across as the index, what
need is their for the index parameter? Or, are there other criteria for
choosing an index? All examples just pass _NTO_SIDE_CHANNEL, but the doc
excerpt below says to OR it in, without describing what the index is for or
how to choose one. I’m just looking for clarification in the docs. Right now
I’ve got it coded to pass the side channel (whatever the heck a side channel
is)…
snip
Would I ever want a coid in the same space as the file descripters? I
understand that I might now want it to conflict with stdin/stdout, but why do
I have a choice here? Could this be explained a little better in the docs?

open() is the only thing that does not set _NTO_SIDE_CHANNEL (open()
calls ConnectAttach()). In all other cases, put _NTO_SIDE_CHANNEL
to avoid the problems mentioned in the docs. I’ll ask docs to
remove the OR. In fact, if you give the _NTO_SIDE_CHANNEL bits
then the kernel does:

if (index & _NTO_SIDE_CHANNEL)
index = _NTO_SIDE_CHANNEL;

Why isn’t _NTO_SIDE_CHANNEL the default? Because the API is frozen
so much to our regret, we cannot make it the default (or get rid
of the parameter altogether). The reason for the docs mentioning
all the bad things that happen when you don’t put _NTO_SIDE_CHANNEL
is so that if anyone forgets to put _NTO_SIDE_CHANNEL, hopefully
they’ll remember having read the explanation and put _NTO_SIDE_CHANNEL.

Also, in the MsgSendPulse() call (to replace the call to Trigger()), I
pass the coid as the first parameter, but how do I choose a priority,
code, and value to send?

The ‘priority’ is like the proxy priority in QNX 4. It controls where
the pulse gets inserted into the receiver’s queue of messages to
receive.

In QNX4, we use a -1 on the qnx_proxy_attach to obtain the same priority as
the calling process. In NTO, the priority is on the MsgSendPulse (like
Trigger), and the docs don’t describe a way to do the same thing. The mention
the use of sched_get_priority_min and _max, but they don’t mention the use of
-1. There was no calls in QNX4 to get min/max depending on scheduling
method. Again, more choices, and I don’t see enough info in the docs to help
me make the choice.

It sounds like in QNX 4 you are doing:

Process 1 Process 2


proxy = qnx_proxy_attach(…, -1)
Send() proxy to process 2 Receive() and store away proxy
while (1) {
pid = Receive() Trigger(proxy)
if (pid == proxy)

}

This is almost exactly what we do except that instead of Send()'ing the proxy id to
process 2, we store it in a shared_memory that both processes map to. The
Trigger()'ing process gets it from there.

To acheive the same thing in QNX Neutrino:

Process 1 Process 2


SIGEV_PULSE_INIT(&event, coid, -1, …)
MsgSend() event to process 2 MsgReceive() and store away
rcvid and event
while (1) {
rcvid = MsgReceive() MsgDeliverEvent(rcvid, &event)
if (rcvid == 0)

}

Instead of the above method, which has the overhead of filling an event structure (I
don’t need to pass data), I chose the other method explained in the docs:

Process 1
Process 2



shared_mem_ptr->out_chan = ChannelCreate(0); out_coid =
ConnectAttach(ND_LOCAL_NODE,
rcvid=MsgReceive(out_chan…);
shared_mem_ptr->process_table[out].pid,
if (rcvid == 0)
shared_mem_ptr->out_chan,
{ /* output data */
_NTO_SIDE_CHANNEL,

}
0);


MsgSendPulse(out_coid, -1, 0,

shared_mem_ptr->process_table[CSE_PROC].pid);

Is this ok?


Note that in QNX Neutrino, the receiver of the pulse floats to the
priority of the pulse. If you do as above and set the priority
to -1 then it is irrelevant. Actually in general the receiver of
any message floats to the priority of the sender. This was setable
in QNX 4 via the _PPF_PRIO_FLOAT flag for qnx_pflags(). If you don’t
want this then turn it off on the receiver’s channel using the
_NTO_CHF_PRIO_FIXED flag for ChannelCreate().

The ‘code’ is typically used as a pulse message type. This is the
same as putting a message in a proxy message buffer for the proxy
to send. The difference is that if your receiver is receiving
more than one different type of pulse then you must use the code
as a pulse message type. In QNX 4 you didn’t need to do this
sort of thing since the receiver could use the proxy id to distinguish
between different types of proxies. The code must be in the
range _PULSE_CODE_MINAVAIL to _PULSE_CODE_MAXAVAIL.

In QNX 4 the proxy data was fixed at the time you created the
proxy. In Neutrino, ‘value’ is your data and it can be different
each time the pulse is sent.

I don’t want to pass any data over with this pulse. I just want it to
indicate to the receiving process, that its time to execute a certain
function. I can do this, just by knowing where this pulse came from,
and receiving it in my MsgReceive() loop (at which point it returns a 0
to indicate its a pulse, according the docs I read). Before I new where
the message came from because the pid of the sending process was
returned right? Now it has to go in the value parameter?

The code parameter. See my comments above re this.

So If I wanted, I could pass the pid of the MsgSendPulse process over as the
code, and pass the value as zero?

Sure. The only hitch I can see is if at some time the receiver would
be receiving pulses from the kernel (see ChannelCreate() flags).
Who knows? Probably best to hedge your bets for the future and
make up a code to use for all your pulses and put the pid in value.
Even putting pid may not be such a good idea. What if receiver
can receive message from different nodes of the native Neutrino
network? In that case there might be pulse senders on two different
nodes but with the same pid. It may not apply to you but just in case…

Is this stuff much more complicated to set up than in QNX4, or is it
just me, hit the learning curve with no breaks? ;o)

Scott

J. Scott Franko <jsfranko@switch.com> wrote:


Steven Dufresne wrote:

J. Scott Franko <> jsfranko@switch.com> > wrote:
Steven Dufresne wrote:
J. Scott Franko <> jsfranko@switch.com> > wrote:
I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.
snip
In QNX4, we use a -1 on the qnx_proxy_attach to obtain the same priority as
the calling process. In NTO, the priority is on the MsgSendPulse (like
Trigger), and the docs don’t describe a way to do the same thing. The mention
the use of sched_get_priority_min and _max, but they don’t mention the use of
-1. There was no calls in QNX4 to get min/max depending on scheduling
method. Again, more choices, and I don’t see enough info in the docs to help
me make the choice.

It sounds like in QNX 4 you are doing:

Process 1 Process 2


proxy = qnx_proxy_attach(…, -1)
Send() proxy to process 2 Receive() and store away proxy
while (1) {
pid = Receive() Trigger(proxy)
if (pid == proxy)

}

This is almost exactly what we do except that instead of Send()'ing the proxy id to
process 2, we store it in a shared_memory that both processes map to. The
Trigger()'ing process gets it from there.



To acheive the same thing in QNX Neutrino:

Process 1 Process 2


SIGEV_PULSE_INIT(&event, coid, -1, …)
MsgSend() event to process 2 MsgReceive() and store away
rcvid and event
while (1) {
rcvid = MsgReceive() MsgDeliverEvent(rcvid, &event)
if (rcvid == 0)

}


Instead of the above method, which has the overhead of filling an event structure (I
don’t need to pass data), I chose the other method explained in the docs:

Process 1
Process 2



shared_mem_ptr->out_chan = ChannelCreate(0); out_coid =
ConnectAttach(ND_LOCAL_NODE,
rcvid=MsgReceive(out_chan…);
shared_mem_ptr->process_table[out].pid,
if (rcvid == 0)
shared_mem_ptr->out_chan,
{ /* output data */
_NTO_SIDE_CHANNEL,

}
0);



MsgSendPulse(out_coid, -1, 0,

shared_mem_ptr->process_table[CSE_PROC].pid);

Is this ok?

Sure. The above suggestion with MsgDeliverEvent() was to show you
how to have the priority work as it did in QNX 4 since I that’s
what you were asking about. Either method is fine.

Scott

Steven D.

Steven Dufresne wrote:

J. Scott Franko <> jsfranko@switch.com> > wrote:

Steven Dufresne wrote:

J. Scott Franko <> jsfranko@switch.com> > wrote:
Steven Dufresne wrote:
J. Scott Franko <> jsfranko@switch.com> > wrote:
I want to replace a Trigger()'d proxy used in our QNX4 code, with the
recommended new pulse in NTO.
snip
In QNX4, we use a -1 on the qnx_proxy_attach to obtain the same priority as
the calling process. In NTO, the priority is on the MsgSendPulse (like
Trigger), and the docs don’t describe a way to do the same thing. The mention
the use of sched_get_priority_min and _max, but they don’t mention the use of
-1. There was no calls in QNX4 to get min/max depending on scheduling
method. Again, more choices, and I don’t see enough info in the docs to help
me make the choice.

It sounds like in QNX 4 you are doing:

Process 1 Process 2


proxy = qnx_proxy_attach(…, -1)
Send() proxy to process 2 Receive() and store away proxy
while (1) {
pid = Receive() Trigger(proxy)
if (pid == proxy)

}

This is almost exactly what we do except that instead of Send()'ing the proxy id to
process 2, we store it in a shared_memory that both processes map to. The
Trigger()'ing process gets it from there.



To acheive the same thing in QNX Neutrino:

Process 1 Process 2


SIGEV_PULSE_INIT(&event, coid, -1, …)
MsgSend() event to process 2 MsgReceive() and store away
rcvid and event
while (1) {
rcvid = MsgReceive() MsgDeliverEvent(rcvid, &event)
if (rcvid == 0)

}


Instead of the above method, which has the overhead of filling an event structure (I
don’t need to pass data), I chose the other method explained in the docs:

Process 1
Process 2



shared_mem_ptr->out_chan = ChannelCreate(0); out_coid =
ConnectAttach(ND_LOCAL_NODE,
rcvid=MsgReceive(out_chan…);
shared_mem_ptr->process_table[out].pid,
if (rcvid == 0)
shared_mem_ptr->out_chan,
{ /* output data */
_NTO_SIDE_CHANNEL,

}
0);

MsgSendPulse(out_coid, -1, 0,

shared_mem_ptr->process_table[CSE_PROC].pid);

Is this ok?

Sure. The above suggestion with MsgDeliverEvent() was to show you
how to have the priority work as it did in QNX 4 since I that’s
what you were asking about. Either method is fine.

Yeah, that’s what I was asking about. I guess this could be another one for the
Documentation folks. The -1 priority trick is not detailed in the doc pages for these
functions that have priority as a parameter.

I think I’ve finally got it. Thanks for all your help. This was a painfully long thread
to respond to, wasn’t it!? ;o)

Scott

Steven D.