comp.lang.ada
 help / color / mirror / Atom feed
* Multiple task bodies for one task type?
@ 2001-09-15  0:26 Darren New
  2001-09-17  9:37 ` John McCabe
  2001-09-17 14:15 ` Stephen Leake
  0 siblings, 2 replies; 7+ messages in thread
From: Darren New @ 2001-09-15  0:26 UTC (permalink / raw)


What's the normal Ada idiom for having multiple types of task in an
array?

Basically, I want a bunch of tasks where I can do something like

tat : array (1..10) of mumble;
ta : tat;
begin
  -- "perform" is an entry or a protected procedure
  ta(1).perform(30);
  ta(2).perform(30);
end

and have the two calls execute different code.

Generally, I want to write a framework where these tasks act something
like callbacks, except I expect I'm going to want them to actually be
tasks and protected objects (probably one of each).

But it looks like each task type gets exactly one task body.

Of course, the primary problem is that things like "accept" and "abort"
and such have to actually be in the task body itself, not in subprograms
called from the task body, or I'd just make (say) a generic with a
procedure for each entry, or something.

Any hints how one would go about this? Thanks in advance!

-- 
Darren New 
San Diego, CA, USA (PST). Cryptokeys on demand.
    Those who work hard with few results always 
           value hard work over getting results.



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

* Re: Multiple task bodies for one task type?
  2001-09-15  0:26 Multiple task bodies for one task type? Darren New
@ 2001-09-17  9:37 ` John McCabe
  2001-09-17 14:01   ` Tucker Taft
  2001-09-18 19:01   ` Richard Riehle
  2001-09-17 14:15 ` Stephen Leake
  1 sibling, 2 replies; 7+ messages in thread
From: John McCabe @ 2001-09-17  9:37 UTC (permalink / raw)


On Sat, 15 Sep 2001 00:26:01 GMT, Darren New <dnew@san.rr.com> wrote:

If I understand yuo correctly, what you want is a heterogeneous array
of tasks. If that is the case, I don't believe it is supported by Ada
as the task type is not extendable.

>But it looks like each task type gets exactly one task body.

That is correct.

>Of course, the primary problem is that things like "accept" and "abort"
>and such have to actually be in the task body itself, not in subprograms
>called from the task body, or I'd just make (say) a generic with a
>procedure for each entry, or something.

>Any hints how one would go about this? Thanks in advance!

You may be able to implement someting like this using a discriminant
on the task type. You would have to include all possible variations on
the code within a case statement in the task. There may be other ways
of course!

Hope this helps.



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

* Re: Multiple task bodies for one task type?
  2001-09-17  9:37 ` John McCabe
@ 2001-09-17 14:01   ` Tucker Taft
  2001-09-18 19:01   ` Richard Riehle
  1 sibling, 0 replies; 7+ messages in thread
From: Tucker Taft @ 2001-09-17 14:01 UTC (permalink / raw)


John McCabe wrote:
> 
> On Sat, 15 Sep 2001 00:26:01 GMT, Darren New <dnew@san.rr.com> wrote:
> 
> If I understand yuo correctly, what you want is a heterogeneous array
> of tasks. If that is the case, I don't believe it is supported by Ada
> as the task type is not extendable.

You could define a limited tagged type, and include a task body
in each extension.  You would need some primitive operations to
interface with the entries of the task.  An access-to-LT'Class type
could be used for passing these around conveniently, where LT is
the limited tagged type.

> ...
> You may be able to implement someting like this using a discriminant
> on the task type. You would have to include all possible variations on
> the code within a case statement in the task. There may be other ways
> of course!

The tagged type mechanism is more easily extensible, though the
interface to the task must be through primitive operations,
rather than directly with entries.

> 
> Hope this helps.

-- 
-Tucker Taft   stt@avercom.net   http://www.avercom.net
Chief Technology Officer, AverCom Corporation (A Titan Company) 
Bedford, MA  USA (AverCom was formerly the Commercial Division of AverStar:
http://www.averstar.com/~stt)



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

* Re: Multiple task bodies for one task type?
  2001-09-15  0:26 Multiple task bodies for one task type? Darren New
  2001-09-17  9:37 ` John McCabe
@ 2001-09-17 14:15 ` Stephen Leake
  1 sibling, 0 replies; 7+ messages in thread
From: Stephen Leake @ 2001-09-17 14:15 UTC (permalink / raw)


Darren New <dnew@san.rr.com> writes:

> What's the normal Ada idiom for having multiple types of task in an
> array?

There is no direct support for arrays of heterogeneous objects in Ada.
You can have arrays of tagged types, and the concrete types can have
different task objects:

type base_type is abstract tagged null record;
type base_access_type is access all base_type'class;

type task_1_tagged_type is new base_type with record
    task_1 : task_1_type;
end record;

type task_2_tagged_type is new base_type with record
    task_2 : task_2_type;
end record;

type task_array_type is array (1 .. 10) of base_access_type;
 
> Basically, I want a bunch of tasks where I can do something like
> 
> tat : array (1..10) of mumble;
> ta : tat;
> begin
>   -- "perform" is an entry or a protected procedure
>   ta(1).perform(30);
>   ta(2).perform(30);
> end
> 
> and have the two calls execute different code.

You can use task discriminants to execute different code (I forget the
syntax, so I won't give an example).

> Generally, I want to write a framework where these tasks act
> something like callbacks, except I expect I'm going to want them to
> actually be tasks and protected objects (probably one of each).

You can use real callbacks; pass a subprogram pointer to each task in
an Initialize rendezvous.

> But it looks like each task type gets exactly one task body.

Yes, but it can be parameterized by task attributes, or the entries
can be parameterized by family parameters (again, I forget the syntax).

> Of course, the primary problem is that things like "accept" and
> "abort" and such have to actually be in the task body itself, not in
> subprograms called from the task body, or I'd just make (say) a
> generic with a procedure for each entry, or something.
> 
> Any hints how one would go about this? Thanks in advance!

Try writing a detailed example in illegal Ada that shows what you
want, then we can help make it legal.

-- 
-- Stephe



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

* Re: Multiple task bodies for one task type?
  2001-09-17  9:37 ` John McCabe
  2001-09-17 14:01   ` Tucker Taft
@ 2001-09-18 19:01   ` Richard Riehle
  2001-09-18 21:03     ` Darren New
  2001-09-18 21:26     ` tmoran
  1 sibling, 2 replies; 7+ messages in thread
From: Richard Riehle @ 2001-09-18 19:01 UTC (permalink / raw)


John McCabe wrote:

> On Sat, 15 Sep 2001 00:26:01 GMT, Darren New <dnew@san.rr.com> wrote:
>

> You may be able to implement someting like this using a discriminant
> on the task type. You would have to include all possible variations on
> the code within a case statement in the task. There may be other ways
> of course!

It is not possible to have an array of tasks with discriminants unless it is
an array of access values to the task type.   This is much like the array of
varying length strings, or array of tagged types someone called a "ragged
array."    Even in this case, it will be necessary for each task to include
control logic to behave differently in different circumstances.  This is not
the same as having a different body.

One possible solution to this is to use the discriminant to trigger a
delegation
effect.  Ada is unique in its direct support for true delegation through the
requeue mechanism.   In this case, an entry can be requeued to a different
task.    Although you cannot pass new parameters in the requeue, each
task (delegatee) can have a different body.  The model can be as simple
as a router that has no other role than to delegate work based on some
set of characteristics of the entry at the beginning of rendezvous.  To
further
empower this design, one could requeue (delegate) to/through a protected
object for improved security of the entire design.

Delegation is a powerful capability in Ada and few languages support it
as directly, or in as pure a form, as Ada through its requeue feature.

Richard Riehle
richard@adaworks.com





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

* Re: Multiple task bodies for one task type?
  2001-09-18 19:01   ` Richard Riehle
@ 2001-09-18 21:03     ` Darren New
  2001-09-18 21:26     ` tmoran
  1 sibling, 0 replies; 7+ messages in thread
From: Darren New @ 2001-09-18 21:03 UTC (permalink / raw)


Richard Riehle wrote:
> Delegation is a powerful capability in Ada and few languages support it
> as directly, or in as pure a form, as Ada through its requeue feature.

Ah ha! Requeuing! This is something I hadn't thought of, that might be
very appropriate! I have to study my Ada books some more, do some actual
design, see if this might not work out. 

Thanks for the suggestions, *everybody*!

-- 
Darren New 
San Diego, CA, USA (PST). Cryptokeys on demand.
                   Who is this Dr. Ibid anyway, 
                  and how does he know so much?



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

* Re: Multiple task bodies for one task type?
  2001-09-18 19:01   ` Richard Riehle
  2001-09-18 21:03     ` Darren New
@ 2001-09-18 21:26     ` tmoran
  1 sibling, 0 replies; 7+ messages in thread
From: tmoran @ 2001-09-18 21:26 UTC (permalink / raw)


  Another approach is that "multiple bodies for the same
procedure spec" suggests tagged types.  Create a task with the
desired set of "entry"s, "select"s, loops, etc.  Give it an
access discriminant that points to a tagged type class.  Make
the changeable parts of the code do calls on primitive functions
of that tagged type.  That will make the task body's execution
dependent on its discriminant parameter.  Any time you want a
new task, of the same spec as the old one but executing new code
in its body, just create a new child of the tagged type with
new primitive procedures to be called by the task.
  If you want an array of these tasks, each with a different
discriminant, you'll of course need to make an array of pointers
to the task type.
  Here's a trivial, but working, example:
package root is  -- blanks to be filled in by actual code

  type task_bodies is abstract tagged null record;
  procedure entrya(t : task_bodies) is abstract;
  procedure continuea(t : task_bodies) is abstract;
  procedure entryb(t : task_bodies; i : in out integer) is abstract;
  procedure continueb(t : task_bodies) is abstract;
  procedure entryc(t : task_bodies; c : in character) is abstract;
  procedure continuec(t : task_bodies) is abstract;

  type task_body_access is access task_bodies'class;

end root;

with root;
package task_interface is    -- define the single task spec

  task type schizo(p : root.task_body_access) is
    entry a;
    entry b(i : in out integer);
    entry c(c : in character);
  end schizo;

end task_interface;

package body task_interface is  -- the common code of the task

  task body schizo is
  begin
    select
      accept a do
        root.entrya(p.all);
      end a;
      root.continuea(p.all);
    or
      accept b(i : in out integer) do
        root.entryb(p.all,i);
      end b;
      root.continueb(p.all);
    or
      accept c(c : in character) do
        root.entryc(p.all,c);
      end c;
      root.continuec(p.all);
    end select;
  end schizo;

end task_interface;

with root;
package test12 is   -- two different sets of body code

  type kind1 is new root.task_bodies with null record;
  procedure entrya(t : kind1);
  procedure continuea(t : kind1);
  procedure entryb(t : kind1; i : in out integer);
  procedure continueb(t : kind1);
  procedure entryc(t : kind1; c : in character);
  procedure continuec(t : kind1);

  type kind2 is new root.task_bodies with null record;
  procedure entrya(t : kind2);
  procedure continuea(t : kind2);
  procedure entryb(t : kind2; i : in out integer);
  procedure continueb(t : kind2);
  procedure entryc(t : kind2; c : in character);
  procedure continuec(t : kind2);
end test12;

with ada.text_io;
package body test12 is

  procedure entrya(t : kind1) is
  begin
    ada.text_io.put('1');
  end entrya;
  procedure continuea(t : kind1) is
  begin
    null;
  end continuea;
  procedure entryb(t : kind1; i : in out integer) is
  begin
    null;
  end entryb;
  procedure continueb(t : kind1) is
  begin
    null;
  end continueb;
  procedure entryc(t : kind1; c : in character) is
  begin
    null;
  end entryc;
  procedure continuec(t : kind1) is
  begin
    null;
  end continuec;

  procedure entrya(t : kind2) is
  begin
    ada.text_io.put('2');
  end entrya;
  procedure continuea(t : kind2) is
  begin
    null;
  end continuea;
  procedure entryb(t : kind2; i : in out integer) is
  begin
    null;
  end entryb;
  procedure continueb(t : kind2) is
  begin
    null;
  end continueb;
  procedure entryc(t : kind2; c : in character) is
  begin
    null;
  end entryc;
  procedure continuec(t : kind2) is
  begin
    null;
  end continuec;

end test12;

with root,
     task_interface,
     test12;
procedure test is

  type task_access is access all task_interface.schizo;
  worker : array(1 .. 4) of task_access;

  first_kind : root.task_body_access := new test12.kind1;
  second_kind : root.task_body_access := new test12.kind2;

begin
  -- start up array of tasks of different kinds
  worker(1) := new task_interface.schizo(first_kind);   -- kind 1
  worker(2) := new task_interface.schizo(second_kind);  --      2
  worker(3) := new task_interface.schizo(first_kind);   --      1
  worker(4) := new task_interface.schizo(first_kind);   --      1

  for i in worker'range loop   -- exercise the tasks
    worker(i).a;
  end loop;

end test;



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

end of thread, other threads:[~2001-09-18 21:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-15  0:26 Multiple task bodies for one task type? Darren New
2001-09-17  9:37 ` John McCabe
2001-09-17 14:01   ` Tucker Taft
2001-09-18 19:01   ` Richard Riehle
2001-09-18 21:03     ` Darren New
2001-09-18 21:26     ` tmoran
2001-09-17 14:15 ` Stephen Leake

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