non periodic and blocking

Hi,

I'm working with Leopold in the networked application already mentioned, and I'd like to have a thing clarified. It's about the non periodic tasks and blocking functions (like the network related ones).

At first, I thought that I should implement the task so that it called recv (or recvfrom) and blocked waiting for anything that arrived, like we did with other unix applications. However some things I've read suggest that the updateHook() shouldn't block, by means of a timeout or whatever. Is this correct? And, in case it is, why is this suggested? Isn't the task going to expend more resources with an active poll like this? And what would happen if done the blocking way?

I think that my confusion comes because I don't really understand how non periodic tasks work. When is the updateHook of a non periodic task called? Which events do trigger it?

Thanks in advance.

Greetings,
Miguel.

non periodic and blocking

On Monday 28 April 2008 16:19:51 miguel wrote:
> Hi,
>
> I'm working with Leopold in the networked application already mentioned,
> and I'd like to have a thing clarified. It's about the non periodic tasks
> and blocking functions (like the network related ones).
>
> At first, I thought that I should implement the task so that it called recv
> (or recvfrom) and blocked waiting for anything that arrived, like we did
> with other unix applications. However some things I've read suggest that
> the updateHook() shouldn't block, by means of a timeout or whatever. Is
> this correct? And, in case it is, why is this suggested? Isn't the task
> going to expend more resources with an active poll like this? And what
> would happen if done the blocking way?
>
> I think that my confusion comes because I don't really understand how non
> periodic tasks work. When is the updateHook of a non periodic task called?
> Which events do trigger it?

In a non periodic taks, you may block in updateHook(). The 'problem' is that
when you block in updateHook(), no commands or events are processed by your
task, because that happens just before updateHook() is executed by the
ExecutionEngine. Thus if you loop forever in updateHook(), you'll never
process an incomming command.

You can work around that by specifying a timeout on the recv socket (
setsockopt() ) and return from updateHook() to allow to process an incomming
command/event/program script. In order to be sure that updateHook() is called
again by the Orocos thread, call
this->engine()->getActivity()->trigger();

That example is in the Component Builder's manual as well.

If your component does not use commands events etc. You can just loop forever
in updateHook().

Peter

non periodic and blocking

Thanks for your quick response.

El 28/04/2008, a las 17:22, Peter Soetens escribió:

> On Monday 28 April 2008 16:19:51 miguel wrote:
>> Hi,
>>
>> I'm working with Leopold in the networked application already
>> mentioned,
>> and I'd like to have a thing clarified. It's about the non periodic
>> tasks
>> and blocking functions (like the network related ones).
>>
>> At first, I thought that I should implement the task so that it
>> called recv
>> (or recvfrom) and blocked waiting for anything that arrived, like
>> we did
>> with other unix applications. However some things I've read suggest
>> that
>> the updateHook() shouldn't block, by means of a timeout or
>> whatever. Is
>> this correct? And, in case it is, why is this suggested? Isn't the
>> task
>> going to expend more resources with an active poll like this? And
>> what
>> would happen if done the blocking way?
>>
>> I think that my confusion comes because I don't really understand
>> how non
>> periodic tasks work. When is the updateHook of a non periodic task
>> called?
>> Which events do trigger it?
>
> In a non periodic taks, you may block in updateHook(). The 'problem'
> is that
> when you block in updateHook(), no commands or events are processed
> by your
> task, because that happens just before updateHook() is executed by the
> ExecutionEngine. Thus if you loop forever in updateHook(), you'll
> never
> process an incomming command.
>

I wasn't thinking of a forever loop, but of letting the recv calls
block. I guess that for this case, it's the same situation.

> You can work around that by specifying a timeout on the recv socket (
> setsockopt() ) and return from updateHook() to allow to process an
> incomming
> command/event/program script. In order to be sure that updateHook()
> is called
> again by the Orocos thread, call
> this->engine()->getActivity()->trigger();

So this schedules the calling task's updateHook for execution again,
leaving the orocos engine time to do its job with the events,
commands, etc. Am I right?

Can't doing this suck all the spare CPU time (not spent by higher
priority tasks), leaving lower priority tasks with no possibility of
being scheduled for execution? Does the orocos engine take care of
this or do I have to do it myself setting timeouts big enough to have
the networking task suspended so other lower priority tasks can acces
the CPU?

> That example is in the Component Builder's manual as well.
>
> If your component does not use commands events etc. You can just
> loop forever
> in updateHook().
>

Well it doesn't right now, but it'll be better not to exclude the
possibility to use them in the future.

> Peter
>

non periodic and blocking

On Monday 28 April 2008 18:14:26 Miguel Prada Sarasola wrote:
> > You can work around that by specifying a timeout on the recv socket (
> > setsockopt() ) and return from updateHook() to allow to process an
> > incomming
> > command/event/program script. In order to be sure that updateHook()
> > is called
> > again by the Orocos thread, call
> > this->engine()->getActivity()->trigger();
>
> So this schedules the calling task's updateHook for execution again,
> leaving the orocos engine time to do its job with the events,
> commands, etc. Am I right?

Yes. You call trigger() and then return from updateHook(). It will be
re-entered shortly after.

>
> Can't doing this suck all the spare CPU time (not spent by higher
> priority tasks), leaving lower priority tasks with no possibility of
> being scheduled for execution? Does the orocos engine take care of
> this or do I have to do it myself setting timeouts big enough to have
> the networking task suspended so other lower priority tasks can acces
> the CPU?

You need to do it yourself. NonPeriodic means full control over the thread.
If you set the timeout to low, you will burn CPU cycles...

>
> > That example is in the Component Builder's manual as well.
> >
> > If your component does not use commands events etc. You can just
> > loop forever
> > in updateHook().
>
> Well it doesn't right now, but it'll be better not to exclude the
> possibility to use them in the future.

If you are planning to use this component as a 'pure device driver', which for
example converts Orocos Data port values to the socket and back, you might
get along _without_ commands and events. Use another component ('logic') to
do the command and event processing and communicates to the device driver
component using data ports. The device driver component then reads/writes the
data ports in the updateHook() function.

Peter

non periodic and blocking

El 28/04/2008, a las 23:47, Peter Soetens
<peter [dot] soetens [..] ...> escribió:

> On Monday 28 April 2008 18:14:26 Miguel Prada Sarasola wrote:
>>> You can work around that by specifying a timeout on the recv
>>> socket (
>>> setsockopt() ) and return from updateHook() to allow to process an
>>> incomming
>>> command/event/program script. In order to be sure that updateHook()
>>> is called
>>> again by the Orocos thread, call
>>> this->engine()->getActivity()->trigger();
>>
>> So this schedules the calling task's updateHook for execution again,
>> leaving the orocos engine time to do its job with the events,
>> commands, etc. Am I right?
>
> Yes. You call trigger() and then return from updateHook(). It will be
> re-entered shortly after.
>
>>
>> Can't doing this suck all the spare CPU time (not spent by higher
>> priority tasks), leaving lower priority tasks with no possibility of
>> being scheduled for execution? Does the orocos engine take care of
>> this or do I have to do it myself setting timeouts big enough to have
>> the networking task suspended so other lower priority tasks can acces
>> the CPU?
>
> You need to do it yourself. NonPeriodic means full control over the
> thread.
> If you set the timeout to low, you will burn CPU cycles...
>
>>
>>> That example is in the Component Builder's manual as well.
>>>
>>> If your component does not use commands events etc. You can just
>>> loop forever
>>> in updateHook().
>>
>> Well it doesn't right now, but it'll be better not to exclude the
>> possibility to use them in the future.
>
> If you are planning to use this component as a 'pure device driver',
> which for
> example converts Orocos Data port values to the socket and back, you
> might
> get along _without_ commands and events. Use another component
> ('logic') to
> do the command and event processing and communicates to the device
> driver
> component using data ports. The device driver component then reads/
> writes the
> data ports in the updateHook() function.

I like this approach. Just one more thing. Is there any way, similar
to select() facility to block waiting for data both at a socket and a
data port? It'd be great to be able to do this for a bi-directional
socket implementation, without polling.

>
> Peter

non periodic and blocking

On Tuesday 29 April 2008 00:52:48 Miguel Prada Sarasola wrote:
> > If you are planning to use this component as a 'pure device driver',
> > which for
> > example converts Orocos Data port values to the socket and back, you
> > might
> > get along _without_ commands and events. Use another component
> > ('logic') to
> > do the command and event processing and communicates to the device
> > driver
> > component using data ports. The device driver component then reads/
> > writes the
> > data ports in the updateHook() function.
>
> I like this approach. Just one more thing. Is there any way, similar
> to select() facility to block waiting for data both at a socket and a
> data port? It'd be great to be able to do this for a bi-directional
> socket implementation, without polling.

No. But I understand the shortcommings of the current scheme. Polling is the
simplest solution today. You could try to go for a blocking buffer (you can
only read-block on one buffer, so no select either) with an extra thread (or
even component) but I wouldn't advise this for beginners. You need to setup
the blocking buffer manually and manage the extra thread manually as well.

Peter

non periodic and blocking

A Dimarts 29 Abril 2008, Peter Soetens va escriure:
> On Tuesday 29 April 2008 00:52:48 Miguel Prada Sarasola wrote:
> > > If you are planning to use this component as a 'pure device driver',
> > > which for
> > > example converts Orocos Data port values to the socket and back, you
> > > might
> > > get along _without_ commands and events. Use another component
> > > ('logic') to
> > > do the command and event processing and communicates to the device
> > > driver
> > > component using data ports. The device driver component then reads/
> > > writes the
> > > data ports in the updateHook() function.
> >
> > I like this approach. Just one more thing. Is there any way, similar
> > to select() facility to block waiting for data both at a socket and a
> > data port? It'd be great to be able to do this for a bi-directional
> > socket implementation, without polling.
>
> No. But I understand the shortcommings of the current scheme. Polling is
> the simplest solution today. You could try to go for a blocking buffer (you
> can only read-block on one buffer, so no select either) with an extra
> thread (or even component) but I wouldn't advise this for beginners. You
> need to setup the blocking buffer manually and manage the extra thread
> manually as well.

But Peter,

exists the way to wait until some new data has arrived to a data port? In the
same way as acts the receive command which blocks until new data is available
in the socket.

Leo (Miguel)

non periodic and blocking

On Tuesday 29 April 2008 15:34:37 Leopold Palomo-Avellaneda wrote:
> > No. But I understand the shortcommings of the current scheme. Polling is
> > the simplest solution today. You could try to go for a blocking buffer
> > (you can only read-block on one buffer, so no select either) with an
> > extra thread (or even component) but I wouldn't advise this for
> > beginners. You need to setup the blocking buffer manually and manage the
> > extra thread manually as well.
>
> But Peter,
>
> exists the way to wait until some new data has arrived to a data port? In
> the same way as acts the receive command which blocks until new data is
> available in the socket.

The you need to setup a blocking buffer with size = 1 using BufferPort instead of a DataPort. A Pull() will then block until someone Push()'es data into that buffer.

To initialise such a BufferPort, you'll need to write in the receiving component (RTT 1.4 or later):

BufferPort mybufPort("MyBuffer", 1 );
mybufPort = new BufferLockFree( 1 );

Which installs a BlockingPolicy for reading that buffer (with size 1) but without a timeout.
A write will not block, but return false if the buffer is full.

Peter

non periodic and blocking

Hi again,

El 30/04/2008, a las 9:40, Peter Soetens escribió:
>
> The you need to setup a blocking buffer with size = 1 using
> BufferPort instead of a DataPort. A Pull() will then block until
> someone Push()'es data into that buffer.
>
> To initialise such a BufferPort, you'll need to write in the
> receiving component (RTT 1.4 or later):
>
> BufferPort mybufPort("MyBuffer", 1 );
> mybufPort = new BufferLockFree( 1 );
>
> Which installs a BlockingPolicy for reading that buffer (with size
> 1) but without a timeout.
> A write will not block, but return false if the buffer is full.

I've been using the blocking buffered ports with the desired results,
but now I've encountered a little problem.

As the pop instruction blocks waiting for anything to arrive to the
buffer, with the corresponding task blocking and not returning from
update hook, this component won't listen when it's told to stop(). The
obvious solution I can think of is sending a dummy package through the
port when I want the task to handle any of these calls, which probably
isn't the most 'elegant' solution.

Is there any function or method I can call to force the pop method to
return the control to the calling task, even if there's no message to
read?

Thanks.

non periodic and blocking

Hi Miguel,

On Monday 30 June 2008 13:03:22 Miguel Prada Sarasola wrote:
>
> As the pop instruction blocks waiting for anything to arrive to the
> buffer, with the corresponding task blocking and not returning from
> update hook, this component won't listen when it's told to stop(). The
> obvious solution I can think of is sending a dummy package through the
> port when I want the task to handle any of these calls, which probably
> isn't the most 'elegant' solution.
>
> Is there any function or method I can call to force the pop method to
> return the control to the calling task, even if there's no message to
> read?

You've analysed the correctly the following bug #418:

So you need to override stop() in your component (in addition to the classical
stopHook() ):

bool stop() {
if ( this->isRunning() ) {
stop_flag = true; // check for this flag after each mybuf.Pull()
mybuf.Push( dummy_value );
}
return TaskContext::stop();
}

Peter

non periodic and blocking

El 30/06/2008, a las 13:57, Peter Soetens escribió:

> Hi Miguel,
>
> On Monday 30 June 2008 13:03:22 Miguel Prada Sarasola wrote:
>>
>> As the pop instruction blocks waiting for anything to arrive to the
>> buffer, with the corresponding task blocking and not returning from
>> update hook, this component won't listen when it's told to stop().
>> The
>> obvious solution I can think of is sending a dummy package through
>> the
>> port when I want the task to handle any of these calls, which
>> probably
>> isn't the most 'elegant' solution.
>>
>> Is there any function or method I can call to force the pop method to
>> return the control to the calling task, even if there's no message to
>> read?
>
> You've analysed the correctly the following bug #418:
>
>
> So you need to override stop() in your component (in addition to the
> classical
> stopHook() ):
>
> bool stop() {
> if ( this->isRunning() ) {
> stop_flag = true; // check for this flag after each mybuf.Pull()
> mybuf.Push( dummy_value );
> }
> return TaskContext::stop();
> }

Great, that's what I'll do.

Thanks for the quick response, Peter and Herman.

Miguel.

non periodic and blocking

On Mon, 30 Jun 2008, Miguel Prada Sarasola wrote:

> El 30/04/2008, a las 9:40, Peter Soetens escribió:
>>
>> The you need to setup a blocking buffer with size = 1 using BufferPort
>> instead of a DataPort. A Pull() will then block until someone Push()'es
>> data into that buffer.
>>
>> To initialise such a BufferPort, you'll need to write in the receiving
>> component (RTT 1.4 or later):
>>
>> BufferPort mybufPort("MyBuffer", 1 );
>> mybufPort = new BufferLockFree( 1 );
>>
>> Which installs a BlockingPolicy for reading that buffer (with size 1) but
>> without a timeout.
>> A write will not block, but return false if the buffer is full.
>
> I've been using the blocking buffered ports with the desired results, but now
> I've encountered a little problem.
>
> As the pop instruction blocks waiting for anything to arrive to the buffer,
> with the corresponding task blocking and not returning from update hook, this
> component won't listen when it's told to stop(). The obvious solution I can
> think of is sending a dummy package through the port when I want the task to
> handle any of these calls, which probably isn't the most 'elegant' solution.
>
> Is there any function or method I can call to force the pop method to return
> the control to the calling task, even if there's no message to read?
>
_if_ your architecture is such that it uses blocking ports, the only
consistent solution is indeed to send an "abort yourself()" message on
those ports.

Personally, I am not at all in favour for activities that block themselves
on one single kind of IPC. Exactly for the kind of problems that you
encounter now, at the moment that you want to shut down activities...

Probably we should develop a solid Orocos example where event-driven
shutdown can happen in a deterministic way, even when using blocking IPC...

Herman

Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm

non periodic and blocking

El 30/04/2008, a las 9:40, Peter Soetens escribió:

> On Tuesday 29 April 2008 15:34:37 Leopold Palomo-Avellaneda wrote:
>>> No. But I understand the shortcommings of the current scheme.
>>> Polling is
>>> the simplest solution today. You could try to go for a blocking
>>> buffer
>>> (you can only read-block on one buffer, so no select either) with an
>>> extra thread (or even component) but I wouldn't advise this for
>>> beginners. You need to setup the blocking buffer manually and
>>> manage the
>>> extra thread manually as well.
>>
>> But Peter,
>>
>> exists the way to wait until some new data has arrived to a data
>> port? In
>> the same way as acts the receive command which blocks until new
>> data is
>> available in the socket.
>
> The you need to setup a blocking buffer with size = 1 using
> BufferPort instead of a DataPort. A Pull() will then block until
> someone Push()'es data into that buffer.
>
> To initialise such a BufferPort, you'll need to write in the
> receiving component (RTT 1.4 or later):
>
> BufferPort mybufPort("MyBuffer", 1 );
> mybufPort = new BufferLockFree( 1 );
>
> Which installs a BlockingPolicy for reading that buffer (with size
> 1) but without a timeout.
> A write will not block, but return false if the buffer is full.
>
> Peter
>

Great. One more thing. We'd like that if new data has to be written
and there's already data in the buffer, the old data gets discarded
and the new data is written at the bufferport. Is there any way to
configure the port to act like this or do we have to do it manually
calling clear before writing to it?

Miguel (Leo)

non periodic and blocking

On Wednesday 30 April 2008 12:52:54 Miguel Prada Sarasola wrote:
>
> Great. One more thing. We'd like that if new data has to be written
> and there's already data in the buffer, the old data gets discarded
> and the new data is written at the bufferport. Is there any way to
> configure the port to act like this or do we have to do it manually
> calling clear before writing to it?

For now, the easiest way is to call clear() before Push(). The buffer
implementation could be extended such that the oldest value is dropped, but
this is currently not the case. You could open a bug report for that feature
(or provide a patch :-).

Peter

non periodic and blocking

On Wed, 30 Apr 2008, Peter Soetens wrote:

> On Wednesday 30 April 2008 12:52:54 Miguel Prada Sarasola wrote:
>>
>> Great. One more thing. We'd like that if new data has to be written
>> and there's already data in the buffer, the old data gets discarded
>> and the new data is written at the bufferport. Is there any way to
>> configure the port to act like this or do we have to do it manually
>> calling clear before writing to it?
>
> For now, the easiest way is to call clear() before Push(). The buffer
> implementation could be extended such that the oldest value is dropped, but
> this is currently not the case. You could open a bug report for that feature
> (or provide a patch :-).
>
I thought we had already the policy option to overwrite the buffer with the
newest data...?

Herman

non periodic and blocking

On Wednesday 30 April 2008 14:26:53 Herman Bruyninckx wrote:
>
> I thought we had already the policy option to overwrite the buffer with the
> newest data...?

This is how a DataObject behaves, it always has the value of the latest Set()
operation. But you can not block on data objects.

Peter