comp.lang.ada
 help / color / mirror / Atom feed
* Ravenscar - release multiple tasks when an event occurs
@ 2020-05-03 10:43 Simon Wright
  2020-05-03 11:50 ` Niklas Holsti
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Simon Wright @ 2020-05-03 10:43 UTC (permalink / raw)


I have several sensor tasks (in general, 2 at the moment) which will of
course be created and start execution during elaboration.

I'd like to ensure that they don't actually start reading and reporting
input data until the system is in a state to receive them.

With the Ravenscar profile it's not obvious how to do this (only one
entry per PO, only one task allowed to queue). I suppose I could just
ignore the inputs until the system's ready to receive them! but has
anyone a scheme which is less clunky?

An alternative would be to try for the Jorvik profile, which does allow
multiple tasks to queue on one entry.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 10:43 Ravenscar - release multiple tasks when an event occurs Simon Wright
@ 2020-05-03 11:50 ` Niklas Holsti
  2020-05-05 16:02   ` Simon Wright
  2020-05-03 14:45 ` Jere
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Niklas Holsti @ 2020-05-03 11:50 UTC (permalink / raw)


On 2020-05-03 13:43, Simon Wright wrote:
> I have several sensor tasks (in general, 2 at the moment) which will of
> course be created and start execution during elaboration.

Depends on the value specified for pragma Partition_Elaboration_Policy. 
If it is Sequential, the tasks start only after (most of) elaboration is 
completed -- RM H.6.

> I'd like to ensure that they don't actually start reading and reporting
> input data until the system is in a state to receive them.

How/when does the system reach that state? At end of elaboration, or at 
some much later time? Should other tasks execute before that state is 
reached?

> With the Ravenscar profile it's not obvious how to do this (only one
> entry per PO, only one task allowed to queue).

You can of course create a special protected object for each sensor task 
that has an entry "wait until system in good state" and a procedure 
"declare system in good state" to open that entry.

Or you could do the same with Suspension_Objects from 
Ada.Synchronous_Task_Control (but Gnat implements them as protected 
objects anyway, I think).

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 10:43 Ravenscar - release multiple tasks when an event occurs Simon Wright
  2020-05-03 11:50 ` Niklas Holsti
@ 2020-05-03 14:45 ` Jere
  2020-05-05 16:05   ` Simon Wright
  2020-05-03 15:09 ` J-P. Rosen
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Jere @ 2020-05-03 14:45 UTC (permalink / raw)


On Sunday, May 3, 2020 at 6:43:31 AM UTC-4, Simon Wright wrote:
> I have several sensor tasks (in general, 2 at the moment) which will of
> course be created and start execution during elaboration.
> 
> I'd like to ensure that they don't actually start reading and reporting
> input data until the system is in a state to receive them.
> 
> With the Ravenscar profile it's not obvious how to do this (only one
> entry per PO, only one task allowed to queue). I suppose I could just
> ignore the inputs until the system's ready to receive them! but has
> anyone a scheme which is less clunky?
> 
> An alternative would be to try for the Jorvik profile, which does allow
> multiple tasks to queue on one entry.

I don't have any experience using ravenscar, so this is somewhat of 
a question as well as a potential option.  I know you cannot do
relative delays, but can you do absolute delays?  If so, could that 
then give you the option to have a single protected object with a
get function and set procedure (no entries) and you just spin lock
at the beginning of all your tasks looking for that protected 
object to change state? 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 10:43 Ravenscar - release multiple tasks when an event occurs Simon Wright
  2020-05-03 11:50 ` Niklas Holsti
  2020-05-03 14:45 ` Jere
@ 2020-05-03 15:09 ` J-P. Rosen
  2020-05-05 16:11   ` Simon Wright
  2020-05-03 15:13 ` Jeffrey R. Carter
  2020-05-05 16:22 ` Simon Wright
  4 siblings, 1 reply; 12+ messages in thread
From: J-P. Rosen @ 2020-05-03 15:09 UTC (permalink / raw)


Le 03/05/2020 à 12:43, Simon Wright a écrit :
> I have several sensor tasks (in general, 2 at the moment) which will of
> course be created and start execution during elaboration.
> 
> I'd like to ensure that they don't actually start reading and reporting
> input data until the system is in a state to receive them.
> 
> With the Ravenscar profile it's not obvious how to do this (only one
> entry per PO, only one task allowed to queue). I suppose I could just
> ignore the inputs until the system's ready to receive them! but has
> anyone a scheme which is less clunky?
Two cases:
1) You have a fixed, well known number of tasks. Declare as many locks
as there are tasks (PO or suspension objects), and have your main
program signal each of them when ready.

2) you want to easily add new tasks as the system evolves, or perhaps
the number of tasks is read from a configuration file that describes the
interfaces. You can do the same thing, but have a linked list of locks,
and some kind of registration process (which you are likely to need anyway).

Note that the notion of (logical) linked list does not imply dynamic
allocation. F.e., you could have a two state process: a first call where
you provide an access to your own PO, and receive an access to the PO of
the task that registered before you. Then, a second call that blocks on
your own PO. When awaken, each task is in charge of waking up the next
one...

> An alternative would be to try for the Jorvik profile, which does allow
> multiple tasks to queue on one entry.
> 
Ravenscar is intended for very strict constraints: everything, and
especially all timings and scheduling, must be fully statically
determinable.

If you don't need such stringent requirements, a more permissive profile
might be more appropriate. I.e. check your requirements first, then
choose a profile.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 10:43 Ravenscar - release multiple tasks when an event occurs Simon Wright
                   ` (2 preceding siblings ...)
  2020-05-03 15:09 ` J-P. Rosen
@ 2020-05-03 15:13 ` Jeffrey R. Carter
  2020-05-05 16:12   ` Simon Wright
  2020-05-05 16:22 ` Simon Wright
  4 siblings, 1 reply; 12+ messages in thread
From: Jeffrey R. Carter @ 2020-05-03 15:13 UTC (permalink / raw)


On 5/3/20 12:43 PM, Simon Wright wrote:
> I have several sensor tasks (in general, 2 at the moment) which will of
> course be created and start execution during elaboration.
> 
> I'd like to ensure that they don't actually start reading and reporting
> input data until the system is in a state to receive them.

1. Have 2 POs, 1 per task
2. Have 1 PO with a function that indicates when the tasks may begin. The tasks 
poll the function until then
3. Use the Jorvik profile, as you mentioned
4. Don't try to prove anything about the concurrency of the system and use Ada's 
full tasking

-- 
Jeff Carter
"To Err is human, to really screw up, you need C++!"
Stéphane Richard
63

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 11:50 ` Niklas Holsti
@ 2020-05-05 16:02   ` Simon Wright
  2020-05-05 16:16     ` Niklas Holsti
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Wright @ 2020-05-05 16:02 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> On 2020-05-03 13:43, Simon Wright wrote:
>> I have several sensor tasks (in general, 2 at the moment) which will of
>> course be created and start execution during elaboration.
>
> Depends on the value specified for pragma
> Partition_Elaboration_Policy. If it is Sequential, the tasks start
> only after (most of) elaboration is completed -- RM H.6.

Indeed, I'd forgotten that.

The top level of the code has SPARK_Mode, and I'm fairly sure that
requires Sequential. I have Partition_Elaboration_Policy (Sequential),
anyway.

>> I'd like to ensure that they don't actually start reading and reporting
>> input data until the system is in a state to receive them.
>
> How/when does the system reach that state? At end of elaboration, or
> at some much later time? Should other tasks execute before that state
> is reached?

Some later time, and indeed other tasks do execute first.

>> With the Ravenscar profile it's not obvious how to do this (only one
>> entry per PO, only one task allowed to queue).
>
> You can of course create a special protected object for each sensor
> task that has an entry "wait until system in good state" and a
> procedure "declare system in good state" to open that entry.
>
> Or you could do the same with Suspension_Objects from
> Ada.Synchronous_Task_Control (but Gnat implements them as protected
> objects anyway, I think).

I think those suffer from the same problem.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 14:45 ` Jere
@ 2020-05-05 16:05   ` Simon Wright
  0 siblings, 0 replies; 12+ messages in thread
From: Simon Wright @ 2020-05-05 16:05 UTC (permalink / raw)


Jere <jhb.chat@gmail.com> writes:

> On Sunday, May 3, 2020 at 6:43:31 AM UTC-4, Simon Wright wrote:
>> I have several sensor tasks (in general, 2 at the moment) which will of
>> course be created and start execution during elaboration.
>> 
>> I'd like to ensure that they don't actually start reading and reporting
>> input data until the system is in a state to receive them.
>> 
>> With the Ravenscar profile it's not obvious how to do this (only one
>> entry per PO, only one task allowed to queue). I suppose I could just
>> ignore the inputs until the system's ready to receive them! but has
>> anyone a scheme which is less clunky?
>> 
>> An alternative would be to try for the Jorvik profile, which does allow
>> multiple tasks to queue on one entry.
>
> I don't have any experience using ravenscar, so this is somewhat of 
> a question as well as a potential option.  I know you cannot do
> relative delays, but can you do absolute delays?  If so, could that 
> then give you the option to have a single protected object with a
> get function and set procedure (no entries) and you just spin lock
> at the beginning of all your tasks looking for that protected 
> object to change state? 

With Ravenscar, you can _only_ do absolute delays. Jorvik (not yet in
the compiler, GNAT_Extended_Ravenscar is the equivalent) allows relative
delays too.

I think it would be unwise to spin lock! A loop with a short delay would
do.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 15:09 ` J-P. Rosen
@ 2020-05-05 16:11   ` Simon Wright
  2020-05-05 17:02     ` Niklas Holsti
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Wright @ 2020-05-05 16:11 UTC (permalink / raw)


"J-P. Rosen" <rosen@adalog.fr> writes:

> Two cases:

> 2) you want to easily add new tasks as the system evolves, or perhaps
> the number of tasks is read from a configuration file that describes the
> interfaces. You can do the same thing, but have a linked list of locks,
> and some kind of registration process (which you are likely to need anyway).

This is more like it: the C version of the code creates the task when it
finds the hardware it needs to deal with, which of course isn't possible
in Ravenscar (or Jorvik).

Fairly extravagant for an embedded system to have tasks you're never
going to use, of course!

> Note that the notion of (logical) linked list does not imply dynamic
> allocation. F.e., you could have a two state process: a first call where
> you provide an access to your own PO, and receive an access to the PO of
> the task that registered before you. Then, a second call that blocks on
> your own PO. When awaken, each task is in charge of waking up the next
> one...

Good one ..

>> An alternative would be to try for the Jorvik profile, which does
>> allow multiple tasks to queue on one entry.
>> 
> Ravenscar is intended for very strict constraints: everything, and
> especially all timings and scheduling, must be fully statically
> determinable.
>
> If you don't need such stringent requirements, a more permissive profile
> might be more appropriate. I.e. check your requirements first, then
> choose a profile.

Supporting GNAT_Extended_Ravenscar in Cortex GNAT RTS doesn't look to be
too difficult.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 15:13 ` Jeffrey R. Carter
@ 2020-05-05 16:12   ` Simon Wright
  0 siblings, 0 replies; 12+ messages in thread
From: Simon Wright @ 2020-05-05 16:12 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:

> 4. Don't try to prove anything about the concurrency of the system and
> use Ada's full tasking

A thought! but not an option for code running on an STM32F4 processor.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-05 16:02   ` Simon Wright
@ 2020-05-05 16:16     ` Niklas Holsti
  0 siblings, 0 replies; 12+ messages in thread
From: Niklas Holsti @ 2020-05-05 16:16 UTC (permalink / raw)


On 2020-05-05 19:02, Simon Wright wrote:
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
> 
>> On 2020-05-03 13:43, Simon Wright wrote:
>>> I have several sensor tasks (in general, 2 at the moment) which will of
>>> course be created and start execution during elaboration.
>>
>> Depends on the value specified for pragma
>> Partition_Elaboration_Policy. If it is Sequential, the tasks start
>> only after (most of) elaboration is completed -- RM H.6.
> 
> Indeed, I'd forgotten that.
> 
> The top level of the code has SPARK_Mode, and I'm fairly sure that
> requires Sequential. I have Partition_Elaboration_Policy (Sequential),
> anyway.
> 
>>> I'd like to ensure that they don't actually start reading and reporting
>>> input data until the system is in a state to receive them.
>>
>> How/when does the system reach that state? At end of elaboration, or
>> at some much later time? Should other tasks execute before that state
>> is reached?
> 
> Some later time, and indeed other tasks do execute first.

Ok. I had in mind a solution where the elaboration of the sensor-task 
packages is delayed until some other elaboration sets up the good state 
(even if it takes a while), but if you need other tasks for that, and 
have Sequential task elaboration, this solution is not possible.

>>> With the Ravenscar profile it's not obvious how to do this (only one
>>> entry per PO, only one task allowed to queue).
>>
>> You can of course create a special protected object for each sensor
>> task that has an entry "wait until system in good state" and a
>> procedure "declare system in good state" to open that entry.
>>
>> Or you could do the same with Suspension_Objects from
>> Ada.Synchronous_Task_Control (but Gnat implements them as protected
>> objects anyway, I think).
> 
> I think those suffer from the same problem.

Yes, you need a different Suspension_Object for each task to be 
suspended (concurrently).

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-03 10:43 Ravenscar - release multiple tasks when an event occurs Simon Wright
                   ` (3 preceding siblings ...)
  2020-05-03 15:13 ` Jeffrey R. Carter
@ 2020-05-05 16:22 ` Simon Wright
  4 siblings, 0 replies; 12+ messages in thread
From: Simon Wright @ 2020-05-05 16:22 UTC (permalink / raw)


Thanks to everyone who commented. I realise that I didn't explain the
full context: this is for a tiny drone, running the aircraft controller
on an STM32F4. I want to add a "flow deck", which is an add-on board
containing sensors for height and lateral motion. There are other decks,
which would need their own tasks.

I might be able to use the AdaCore 'full' runtime, but I rather want to
use Cortex GNAT RTS (if nothing else, I can cause the application code
to load leaving space for the boot loader).

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Ravenscar - release multiple tasks when an event occurs
  2020-05-05 16:11   ` Simon Wright
@ 2020-05-05 17:02     ` Niklas Holsti
  0 siblings, 0 replies; 12+ messages in thread
From: Niklas Holsti @ 2020-05-05 17:02 UTC (permalink / raw)


On 2020-05-05 19:11, Simon Wright wrote:
> "J-P. Rosen" <rosen@adalog.fr> writes:
> 
>> Two cases:
> 
>> 2) you want to easily add new tasks as the system evolves, or perhaps
>> the number of tasks is read from a configuration file that describes the
>> interfaces. You can do the same thing, but have a linked list of locks,
>> and some kind of registration process (which you are likely to need anyway).
> 
> This is more like it: the C version of the code creates the task when it
> finds the hardware it needs to deal with, which of course isn't possible
> in Ravenscar (or Jorvik).
> 
> Fairly extravagant for an embedded system to have tasks you're never
> going to use, of course!

If an unused task is suspended, it consumes no or very little 
processing. It does reserve stack memory.

If you cannot allow stack memory for all possible tasks (for all 
possible hardware combinations), you can have a pool of tasks, with as 
many tasks as you can support, and allocate tasks dynamically to the 
hardware units that are present. Of course, each task must then have 
enough stack to handle any hardware it is assigned, so you may have to 
use stack memory more conservatively than otherwise.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-05-05 17:02 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-03 10:43 Ravenscar - release multiple tasks when an event occurs Simon Wright
2020-05-03 11:50 ` Niklas Holsti
2020-05-05 16:02   ` Simon Wright
2020-05-05 16:16     ` Niklas Holsti
2020-05-03 14:45 ` Jere
2020-05-05 16:05   ` Simon Wright
2020-05-03 15:09 ` J-P. Rosen
2020-05-05 16:11   ` Simon Wright
2020-05-05 17:02     ` Niklas Holsti
2020-05-03 15:13 ` Jeffrey R. Carter
2020-05-05 16:12   ` Simon Wright
2020-05-05 16:22 ` Simon Wright

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox