Understanding OS calls

The final word…

I didn’t intend this problem to become some kind of test of
the new support system, but somehow in the end it has turned
out to be just that.

Out of a total of 8 posts on my part, and 12 responses, no
answer to my question has appeared. This was over a period
of five days. This led to my begining to think that I was
crazy, or that QSSL had missed something big.

However I thankfully received tonight the solution from
Xiaodan Tang the correct answer, which I will gladly share.
The routine message_connect() will take the dispatch handle
as a parameter, and return with a connection id to the
channel that the dispatch…() routines are using. This
completely solves the mystery.

Thank you all for your assistance.


Mitchell Schoenbrun --------- maschoen@pobox.com

Mitchell Schoenbrun <maschoen@pobox.com> wrote:

The final word…

I didn’t intend this problem to become some kind of test of
the new support system, but somehow in the end it has turned
out to be just that.

Out of a total of 8 posts on my part, and 12 responses, no
answer to my question has appeared. This was over a period
of five days. This led to my begining to think that I was
crazy, or that QSSL had missed something big.

Yes unfortunately I’m one of the principal “talkers” on this
subject and have not been keeping up with the QUICS
discussions for the past week instead focusing on some
other projects. It was an interesting thread and I’m
hoping to whip together a summary with “the official word”
answers so that it can be posted to QDN and propagated
wide and far.

However I thankfully received tonight the solution from
Xiaodan Tang the correct answer, which I will gladly share.
The routine message_connect() will take the dispatch handle
as a parameter, and return with a connection id to the
channel that the dispatch…() routines are using. This
completely solves the mystery.

Sadly, this answer is sitting in our documentation in the
guise of the “Dispatch Technote”, an incredibly usefull
document for anyone doing resource manager work. It is
unfortunately a little lonely off on the side.

As Donna indicated, we are hoping to address some of
the confusion in the new resource manager bookset. Any
and all comments are welcome.

Thomas

Mitchell Schoenbrun <maschoen@pobox.com> wrote:

Previously, David Gibbs wrote in qdn.public.qnxrtp.os:

  1. Use a resource manager. (QNX4 IO manager equivalent) resmgr_attach()
    registers a name in the name space. Block with dispatch_block(), handle
    pulses with pulse_attach(), and get a connection to yourself so a timer
    or isr can send you pulses with message_connect().

This is precisely what I’m hoping to do. Now, after doing the
resmgr_attach() how do I “get a connection to yourself”.

You call message_connect(). Check the docs on message_connect().

-David

QNX Training Services
dagibbs@qnx.com

Mitchell Schoenbrun <maschoen@pobox.com> wrote:

The final word…



Xiaodan Tang the correct answer, which I will gladly share.
The routine message_connect() will take the dispatch handle
as a parameter, and return with a connection id to the
channel that the dispatch…() routines are using. This
completely solves the mystery.

I posted that in my response. I said:

…and get a connection to yourself so a timer
or isr can send you pulses with message_connect(). …

-David

QNX Training Services
dagibbs@qnx.com

Previously, David Gibbs wrote in qdn.public.qnxrtp.os:

I posted that in my response. I said:

…and get a connection to yourself so a timer
or isr can send you pulses with message_connect(). …

I had to read this a few times just now to figure it out.
The reason I missed it is that the predicate is so far from
the verb. I thought you were saying that you “send pulses
with message_connect()” which I ignored because it didn’t make
sense to me at the time.

How about:

… and get a connection to yourself with message_connect(),
so a timer or isr can send you pulses.


Admittedly by this time in the dialog I’d been getting quite
frustrated, and I should have looked more carefully.

Mitchell

Mitchell Schoenbrun --------- maschoen@pobox.com

Dean Douthat <ddouthat@faac.com> wrote:

I have to agree with Mitchell that the resmgr_* set of functions sounds
pretty heavy for connecting with “home built” rather than “store bought”
managers. Is prefix aliasing not available for this purpose?

Not as a seperate (prefix) command.

Will it be?
From the utilities reference on ln:

-P Create the link in the process manager’s in-memory prefix tree.

This is also available as the boot script built-in procmgr_symlink.

Also, in your description,
there is no mention of scatter/gather messaging; is this not present or just
not mentioned?

Just not mentioned. MsgSend(), MsgSendv(), MsgSendvs(), MsgSendsv(),
MsgReceive(), MsgReceivev(), etc…

-David

QNX Training Services
dagibbs@qnx.com

Mitchell Schoenbrun <maschoen@pobox.com> wrote:

Previously, David Gibbs wrote in qdn.public.qnxrtp.os:

I posted that in my response. I said:

…and get a connection to yourself so a timer
or isr can send you pulses with message_connect(). …

I had to read this a few times just now to figure it out.
The reason I missed it is that the predicate is so far from
the verb. I thought you were saying that you “send pulses
with message_connect()” which I ignored because it didn’t make
sense to me at the time.

How about:

… and get a connection to yourself with message_connect(),
so a timer or isr can send you pulses.

Ah … now I see why you missed it. S’alright.

Sorry for the delay in posting… I’d been out of the office for
a week and a half ending yesterday.

-David


QNX Training Services
dagibbs@qnx.com

i usually look at message_attach() and pulse_attach() for doing things outside
of the normal dispatch interface.
those are nice convenience callback functions that eliminate most of the
setup overhead… and still give me a multithreaded resmgr.

Igor Kovalenko <Igor.Kovalenko@motorola.com> wrote:

Mitchell Schoenbrun wrote:

Thanks for all the moral support guys. The theoretical
just got a little tragic last night. Here is what I
ran into.

I want to do something that I can write in my sleep in QNX4.
I have a manager that receives user messages but needs to
wake up occaisionally on its own. Under QNX4 I create a
proxy and attach it to a timer. The timer fires, triggers
the proxy and my Receive() wakes up.


You don’t really need pulse. Signals in Neutrino can carry data just
like pulses (they are implemented by same kernel object). They are also
more lightweight (tax your system less) and generally should be
preferred to pulses unless you have a good reason to do otherwise.

Now under Neutrino the fun starts. I’ll start with the
timer. I setup a timer to send a pulse periodically. One of
the first things I have to do is give the event structure a
connection id (coid). Ok, that’s fair, the timer needs to
know what connection to send the pulse over.

But now I have a catch 22. I could use ConnectCreate() to
create a channel, and then ConnectAttach() to create the coid.
But now I have a coid which cannot be found out by my clients.

Ok, back to the drawing board, I do a resmgr_attach(), but
where’s the channel id? It’s buried inside resmgr_attach().
Is it in the dispatch_t structure, probably, but I can’t find
this defined anywhere in /usr/include/*.


Hmm. I’d try to use name_attach() and name_locate() myself to get coid.
Perhaps name_locate() can locate a name attached by resmgr_attach() too,
who knows…
Might work, although I did not try it. Indeed, you can’t use open() for
that without help of another thread.

If resmgr_block() could wait on two coid’s then things would
be ok. Well it could do this by using select() I think, but
it doesn’t. I could write this code myself, but again I don’t
have the channel id to wait on for the client messages.


I did that using ionotify(), with similar scenario. Had a program
waiting on both timer and incoming data on a socket in a single event
loop. The timer handler then sent data to that socket (it was sort of
benchmark).

Maybe what I need to do is create a thread, have the thread
open the name space, and then have the timer send the pulse
to that way. It seems awful kludgy to need an extra thread
just to have a pulse wakeup a manager.

I hope I’ve missed something simple here. Can someone help
me out.


Yes it is kludgy as a way to obtain coid, but then using pulse to get
timer events is unnecessary overhead in the first place, if your timer
handler is very simple. Otherwise you might as well think and conclude
that having a separate thread might not be such a bad idea. You can’t
handle incoming messages while you’re handling timer and vice versa. If
your program gets to run on SMP then thread would be good. In any case
you might get better determinism under heavy load with separate thread.

  • Igor


Randy Martin randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579

Randy Martin a écrit :

i usually look at message_attach() and pulse_attach() for doing things outside
of the normal dispatch interface.
those are nice convenience callback functions that eliminate most of the
setup overhead… and still give me a multithreaded resmgr.

Igor Kovalenko <> Igor.Kovalenko@motorola.com> > wrote:
Mitchell Schoenbrun wrote:

Thanks for all the moral support guys. The theoretical
just got a little tragic last night. Here is what I
ran into.

I want to do something that I can write in my sleep in QNX4.
I have a manager that receives user messages but needs to
wake up occaisionally on its own. Under QNX4 I create a
proxy and attach it to a timer. The timer fires, triggers
the proxy and my Receive() wakes up.


You don’t really need pulse. Signals in Neutrino can carry data just
like pulses (they are implemented by same kernel object). They are also
more lightweight (tax your system less) and generally should be
preferred to pulses unless you have a good reason to do otherwise.

Now under Neutrino the fun starts. I’ll start with the
timer. I setup a timer to send a pulse periodically. One of
the first things I have to do is give the event structure a
connection id (coid). Ok, that’s fair, the timer needs to
know what connection to send the pulse over.

But now I have a catch 22. I could use ConnectCreate() to
create a channel, and then ConnectAttach() to create the coid.
But now I have a coid which cannot be found out by my clients.

Ok, back to the drawing board, I do a resmgr_attach(), but
where’s the channel id? It’s buried inside resmgr_attach().
Is it in the dispatch_t structure, probably, but I can’t find
this defined anywhere in /usr/include/*.


Hmm. I’d try to use name_attach() and name_locate() myself to get coid.
Perhaps name_locate() can locate a name attached by resmgr_attach() too,
who knows…
Might work, although I did not try it. Indeed, you can’t use open() for
that without help of another thread.

If resmgr_block() could wait on two coid’s then things would
be ok. Well it could do this by using select() I think, but
it doesn’t. I could write this code myself, but again I don’t
have the channel id to wait on for the client messages.


I did that using ionotify(), with similar scenario. Had a program
waiting on both timer and incoming data on a socket in a single event
loop. The timer handler then sent data to that socket (it was sort of
benchmark).

Maybe what I need to do is create a thread, have the thread
open the name space, and then have the timer send the pulse
to that way. It seems awful kludgy to need an extra thread
just to have a pulse wakeup a manager.

I hope I’ve missed something simple here. Can someone help
me out.


Yes it is kludgy as a way to obtain coid, but then using pulse to get
timer events is unnecessary overhead in the first place, if your timer
handler is very simple. Otherwise you might as well think and conclude
that having a separate thread might not be such a bad idea. You can’t
handle incoming messages while you’re handling timer and vice versa. If
your program gets to run on SMP then thread would be good. In any case
you might get better determinism under heavy load with separate thread.

  • Igor


Randy Martin > randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems > www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579

Of course Randy, After so many answers without this one, I was beginning to think
that I didn’t understand the subject. But what Michael want to do is really simple
like that.
The pseudo code is something like

main()
{
dpp = dispatch_create();

// if you need a resource manager

iofunc_attr_init(&attr, S_IFREG | 0xxx, 0, 0);

iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs, _RESMGR_IO_NFUNCS,
&io_funcs);
io_funcs.read = your_read; // if a client is supposed to read() from you
io_funcs.write = your_write; // if a client is supposed to write to you
io_funcs.msg = your_msg; // if a client is supposed to MsgSend() to you

resmgr_attach(dpp, &resmgr_attr, attach_name, _FTYPE_ANY, 0, &connect_funcs,
&io_funcs, &attr);

// if you need a pulse say, triggered by a timer to your dispatch interface,
just write:

pulse_code = pulse_attach(dpp, MSG_FLAG_ALLOC_PULSE, 0, your_function, NULL);

// note the dpp parameter
coid = message_connect(dpp, MSG_FLAG_SIDE_CHANNEL);

SIGEV_PULSE_INIT(&event, coid, SIGEV_PULSE_PRIO_INHERIT, pulse_code, 0);

timer_create(CLOCK_REALTIME, &event, &timerID);

itime.it_value.tv_sec = 1;
itime.it_value.tv_nsec = 0;
itime.it_interval.tv_sec = 1;
itime.it_interval.tv_nsec = 0;

timer_settime(timerID, 0, &itime, NULL);

ctp = resmgr_context_alloc(dpp);

while(1)
{
resmgr_block(ctp);

resmgr_handler(ctp);
}
}