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