* DYNAMIC ADA TASK CREATION? @ 2003-06-17 19:53 avram 2003-06-17 20:24 ` Simon Wright 0 siblings, 1 reply; 28+ messages in thread From: avram @ 2003-06-17 19:53 UTC (permalink / raw) How to create dynamic for example N tasks. I don't know how create N of tasks and array (not list). For example user interface gets an Integer (N) from user and then we create N number of Task in ADA. How to do this?Can anybody help me? Thanx very much. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-17 19:53 DYNAMIC ADA TASK CREATION? avram @ 2003-06-17 20:24 ` Simon Wright 2003-06-18 6:11 ` Robert I. Eachus 0 siblings, 1 reply; 28+ messages in thread From: Simon Wright @ 2003-06-17 20:24 UTC (permalink / raw) "avram" <avram79@tlen.pl> writes: > How to create dynamic for example N tasks. I don't know how create N of > tasks and array (not list). For example user interface gets an Integer (N) > from user and then we create N number of Task in ADA. How to do this?Can > anybody help me? (uncompiled) task type t is -- some entries end t; task body t is begin -- code end t; type ts is array (positive range <>) of t; n : positive; begin -- read in n declare the_ts : ts (1 .. n); begin -- do something with the tasks -- NB, can't pass this point until all the tasks have terminated end; ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-17 20:24 ` Simon Wright @ 2003-06-18 6:11 ` Robert I. Eachus 2003-06-18 9:20 ` Georg Bauhaus 2003-06-18 19:15 ` avram 0 siblings, 2 replies; 28+ messages in thread From: Robert I. Eachus @ 2003-06-18 6:11 UTC (permalink / raw) Simon Wright wrote: >> How to create dynamic for example N tasks. I don't know how create N of >>tasks and array (not list). For example user interface gets an Integer (N) >>from user and then we create N number of Task in ADA. How to do this?Can >>anybody help me? > > > (uncompiled) > > task type t is > -- some entries > end t; > > task body t is > begin > -- code > end t; > > type ts is array (positive range <>) of t; > > n : positive; > > begin > > -- read in n > > declare > the_ts : ts (1 .. n); > begin > -- do something with the tasks > -- NB, can't pass this point until all the tasks have terminated > end; Correct. But if you don't want to get stuck there, do this instead: -- task type t as above type ta is access t; type ts is array (positive range <>) of ta := new t; n : positive; begin -- read in n declare the_ts : ts (1 .. n); begin -- do something with the tasks -- NB, CAN pass this once all the tasks have been created. end; For an ordinary task object, the creator of the object is the master (in the original example, a declare block. But for a task created by an allocator, the place where the access type was declared determines who is the master. (In either case, if that is in a library package, the master is the environment task.) ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 6:11 ` Robert I. Eachus @ 2003-06-18 9:20 ` Georg Bauhaus 2003-06-18 11:13 ` John McCabe 2003-06-18 19:15 ` avram 1 sibling, 1 reply; 28+ messages in thread From: Georg Bauhaus @ 2003-06-18 9:20 UTC (permalink / raw) Robert I. Eachus <rieachus@attbi.com> wrote: : Simon Wright wrote: : :> (uncompiled) :> :> task type t is :> -- some entries :> end t; :> :> task body t is :> begin :> -- code :> end t; :> :> type ts is array (positive range <>) of t; :> :> n : positive; :> :> begin :> :> -- read in n :> :> declare :> the_ts : ts (1 .. n); :> begin :> -- do something with the tasks :> -- NB, can't pass this point until all the tasks have terminated :> end; : : Correct. But if you don't want to get stuck there, do this instead: : : -- task type t as above : type ta is access t; : : type ts is array (positive range <>) of ta := new t; ^^^^^^^^ I think I got the idea and made me program to see the tasks working outside the declare block. A good hint! But is new t on the line above some new default initialisation construct, or meant to abbreviate something? (The compiler complains.) : [...] : : declare : the_ts : ts (1 .. n); : begin : -- do something with the tasks : -- NB, CAN pass this once all the tasks have been created. : end; : : For an ordinary task object, the creator of the object is the master (in : the original example, a declare block. But for a task created by an : allocator, the place where the access type was declared determines who : is the master. (In either case, if that is in a library package, the : master is the environment task.) : -- Georg ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 9:20 ` Georg Bauhaus @ 2003-06-18 11:13 ` John McCabe 2003-06-18 12:43 ` John McCabe 2003-06-19 5:07 ` Simon Wright 0 siblings, 2 replies; 28+ messages in thread From: John McCabe @ 2003-06-18 11:13 UTC (permalink / raw) On Wed, 18 Jun 2003 09:20:01 +0000 (UTC), Georg Bauhaus <sb463ba@d2-hrz.uni-duisburg.de> wrote: >: Correct. But if you don't want to get stuck there, do this instead: >: >: -- task type t as above >: type ta is access t; >: >: type ts is array (positive range <>) of ta := new t; > ^^^^^^^^ >I think I got the idea and made me program to see the tasks working >outside the declare block. A good hint! >But is new t on the line above some new default initialisation >construct, or meant to abbreviate something? (The compiler complains.) : : declare : the_ts : ts (1 .. n); : begin : -- do something with the tasks : -- NB, CAN pass this once all the tasks have been created. : end; : I'm not surprised, you're trying to initialise a type!! Simon did say he hadn't compiled this though! You need to remove the ' := new t' at the end, then actually create the tasks something like: -- task type t as above type ta is access t; type ts is array (positive range <>) of ta; declare the_ts : ts (1 .. n); begin for Index in 1 .. n loop the_ts(n) := new t; end loop; -- do something with the tasks -- NB, CAN pass this once all the tasks have been created. end; Just a vague thought....does.. declare the_ts : ts (1 .. n) = (others => new t); begin .... compile? Best Regards John McCabe To reply by email replace 'nospam' with 'assen' ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 11:13 ` John McCabe @ 2003-06-18 12:43 ` John McCabe 2003-06-18 14:17 ` Georg Bauhaus 2003-06-19 5:07 ` Simon Wright 1 sibling, 1 reply; 28+ messages in thread From: John McCabe @ 2003-06-18 12:43 UTC (permalink / raw) On Wed, 18 Jun 2003 11:13:37 +0000 (UTC), john@nospam.demon.co.uk (John McCabe) wrote: >Just a vague thought....does.. > >declare > the_ts : ts (1 .. n) = (others => new t); Certainly won't without a : in front of the = ! Best Regards John McCabe To reply by email replace 'nospam' with 'assen' ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 12:43 ` John McCabe @ 2003-06-18 14:17 ` Georg Bauhaus 0 siblings, 0 replies; 28+ messages in thread From: Georg Bauhaus @ 2003-06-18 14:17 UTC (permalink / raw) John McCabe <john@nospam.demon.co.uk> wrote: : On Wed, 18 Jun 2003 11:13:37 +0000 (UTC), john@nospam.demon.co.uk : (John McCabe) wrote: : : :>Just a vague thought....does.. :> :>declare :> the_ts : ts (1 .. n) = (others => new t); : : Certainly won't without a : in front of the = ! Yeah, this is what I had declare the_ts : ts := (1..n => new t); and now that I see it again, there is an opportunity to change it, declare the_ts : constant ts := (1..n => new t); -- Georg ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 11:13 ` John McCabe 2003-06-18 12:43 ` John McCabe @ 2003-06-19 5:07 ` Simon Wright 2003-06-19 6:05 ` Robert I. Eachus 1 sibling, 1 reply; 28+ messages in thread From: Simon Wright @ 2003-06-19 5:07 UTC (permalink / raw) john@nospam.demon.co.uk (John McCabe) writes: w> >: Correct. But if you don't want to get stuck there, do this instead: > >: > >: -- task type t as above > >: type ta is access t; > >: > >: type ts is array (positive range <>) of ta := new t; > > ^^^^^^^^ [..] > I'm not surprised, you're trying to initialise a type!! Simon did > say he hadn't compiled this though! That version was Robert's ... ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-19 5:07 ` Simon Wright @ 2003-06-19 6:05 ` Robert I. Eachus 2003-06-19 23:30 ` Jeffrey Carter 0 siblings, 1 reply; 28+ messages in thread From: Robert I. Eachus @ 2003-06-19 6:05 UTC (permalink / raw) Simon Wright wrote: >>>: type ts is array (positive range <>) of ta := new t; >>> ^^^^^^^^ > That version was Robert's ... Let me make it official, it was a typo, should have been: type ts is array (positive range <>) of ta := (others => new t); But I really wanted to answer this: Oh, why is it worse with discriminants? There are usually in Ada implementations two types of storage associated with tasks. The first is a task descriptor, which contains addresses for the code, entry queues, and other such stuff. The other part is a stack and (and possibly local heap) for the executing object. If the task has descriminants, they are normally stored in the task descriptor. Again in the normal case, the stack (and local heap if allocated) will be deallocated when the task terminates. The task descriptor is the thing that can be deallocated by Unchecked_Deallocation. If a task without discriminants is freed before it becomes terminated, it won't affect the executing task. But it may deallocate the task descriptor which contains the discriminants. If the task, or any of it's dependent tasks references the discriminants, it is a bounded error, which will most likely cause Program_Error in the task. See RM 13.11.2(11-15) for details on other possibilities. For a task without discriminants, you may not free all the memory that you had hoped for, but the only real effect is that you may no longer be able to reference the task. (Of course, calling an instance of Unchecked_Deallocation while salting away a copy of the pointer is not something you should do either. But that case is a lot more obvious.) In most normal tasking programs there is no particular reason to free the task descriptors. And as I said, the memory allocated for the stack will go away anyway when the task is terminated. (In language lawyer speak, a task is completed when the code execution reaches the end of the code and in other cases. But termination waits until all dependent tasks have become terminated. This is so that dependent tasks can still reference the parent task's stack.) So usually when a programmer thinks he wants to go around stomping out tasks, he has left one or two tasks hanging that are keeping a lot of other tasks half-alive. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-19 6:05 ` Robert I. Eachus @ 2003-06-19 23:30 ` Jeffrey Carter 0 siblings, 0 replies; 28+ messages in thread From: Jeffrey Carter @ 2003-06-19 23:30 UTC (permalink / raw) Robert I. Eachus wrote: > Simon Wright wrote: > > type ts is array (positive range <>) of ta := (others => new t); I'd still like to know what language this is. -- Jeff Carter "You cheesy lot of second-hand electric donkey-bottom biters." Monty Python & the Holy Grail ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 6:11 ` Robert I. Eachus 2003-06-18 9:20 ` Georg Bauhaus @ 2003-06-18 19:15 ` avram 2003-06-18 21:17 ` Craig Carey 2003-06-18 23:28 ` Robert I. Eachus 1 sibling, 2 replies; 28+ messages in thread From: avram @ 2003-06-18 19:15 UTC (permalink / raw) Thanx very much. I have one more question. What about task memory deallocation. How to wait untill task ends? Is it possible to deallocate memory after the end of task from "parent task" ? avram Uzytkownik "Robert I. Eachus" <rieachus@attbi.com> napisal w wiadomosci news:3EF0026E.2050309@attbi.com... > Simon Wright wrote: > > >> How to create dynamic for example N tasks. I don't know how create N of > >>tasks and array (not list). For example user interface gets an Integer (N) > >>from user and then we create N number of Task in ADA. How to do this?Can > >>anybody help me? > > > > > > (uncompiled) > > > > task type t is > > -- some entries > > end t; > > > > task body t is > > begin > > -- code > > end t; > > > > type ts is array (positive range <>) of t; > > > > n : positive; > > > > begin > > > > -- read in n > > > > declare > > the_ts : ts (1 .. n); > > begin > > -- do something with the tasks > > -- NB, can't pass this point until all the tasks have terminated > > end; > > Correct. But if you don't want to get stuck there, do this instead: > > -- task type t as above > type ta is access t; > > type ts is array (positive range <>) of ta := new t; > > n : positive; > > begin > > -- read in n > > declare > the_ts : ts (1 .. n); > begin > -- do something with the tasks > -- NB, CAN pass this once all the tasks have been created. > end; > > For an ordinary task object, the creator of the object is the master (in > the original example, a declare block. But for a task created by an > allocator, the place where the access type was declared determines who > is the master. (In either case, if that is in a library package, the > master is the environment task.) > ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 19:15 ` avram @ 2003-06-18 21:17 ` Craig Carey 2003-06-20 18:56 ` avram 2003-06-18 23:28 ` Robert I. Eachus 1 sibling, 1 reply; 28+ messages in thread From: Craig Carey @ 2003-06-18 21:17 UTC (permalink / raw) On Wed, 18 Jun 2003 21:15:02 +0200, "avram" <avram79@tlen.pl> wrote: > Than[s] very much. I have one more question. >What about task memory deallocation. How to wait untill task ends? There was a solution posted in comp.lang.ada which is replicated: On 11 May 2003 17:35:18 +0200, in comp.lang.ada you Pascal Obry wrote: >[...] The delay could still not be enough. What I usually do >is loop until 'Terminated is true. ... > for K in 1 .. 20_000 loop > X := new A.Tt; -- [Create a new task] > N := N + 1; > X.The_End; > > loop > exit when X'Terminated; > delay 1.0E-30; > end loop; > > Free (X); > end loop; > The memory recovery can be 0% efficient, or 100% efficient depending on how the test is done (at least, for the ObjectAda and GNAT compilers). Craig Carey ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 21:17 ` Craig Carey @ 2003-06-20 18:56 ` avram 2003-06-21 13:06 ` Pascal Obry 0 siblings, 1 reply; 28+ messages in thread From: avram @ 2003-06-20 18:56 UTC (permalink / raw) Thanx, but i think that the loop is not efficient. I mean this is an active waiting, so my main process use CPU without sense. I would like to know if there is way to deallocation of a memory without active waiting. avram Uzytkownik "Craig Carey" <research@ijs.co.nz> napisal w wiadomosci news:39l1fv8ig2hr2bpsf786ao6a9it649bfnj@4ax.com... > On Wed, 18 Jun 2003 21:15:02 +0200, "avram" <avram79@tlen.pl> wrote: > > Than[s] very much. I have one more question. > >What about task memory deallocation. How to wait untill task ends? > > There was a solution posted in comp.lang.ada which is replicated: > > > On 11 May 2003 17:35:18 +0200, in comp.lang.ada you Pascal Obry wrote: > >[...] The delay could still not be enough. What I usually do > >is loop until 'Terminated is true. > ... > > for K in 1 .. 20_000 loop > > X := new A.Tt; -- [Create a new task] > > N := N + 1; > > X.The_End; > > > > loop > > exit when X'Terminated; > > delay 1.0E-30; > > end loop; > > > > Free (X); > > end loop; > > > > The memory recovery can be 0% efficient, or 100% efficient depending > on how the test is done (at least, for the ObjectAda and GNAT > compilers). > > Craig Carey > ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-20 18:56 ` avram @ 2003-06-21 13:06 ` Pascal Obry 0 siblings, 0 replies; 28+ messages in thread From: Pascal Obry @ 2003-06-21 13:06 UTC (permalink / raw) "avram" <avram79@tlen.pl> writes: > Thanx, but i think that the loop is not efficient. I mean this is an > active waiting, so my main process use CPU without sense. I would like to > know if there is way to deallocation of a memory without active waiting. No. The whole point of the loop is to waity for the task to terminate before freeing memory. How do you expect to be able to free memory of an active task ? Note that this loop will iterate once or twice in most of the case. Not a big deal. Pascal. -- --|------------------------------------------------------ --| Pascal Obry Team-Ada Member --| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE --|------------------------------------------------------ --| http://perso.wanadoo.fr/pascal.obry --| "The best way to travel is by means of imagination" --| --| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595 ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 19:15 ` avram 2003-06-18 21:17 ` Craig Carey @ 2003-06-18 23:28 ` Robert I. Eachus 2003-06-19 5:09 ` Simon Wright 1 sibling, 1 reply; 28+ messages in thread From: Robert I. Eachus @ 2003-06-18 23:28 UTC (permalink / raw) avram wrote: > Thanx very much. > I have one more question. > What about task memory deallocation. > How to wait untill task ends? > Is it possible to deallocate memory after the end of task from "parent task" If you really want to. If the task is created with an allocator, you can test for TA(...)'Terminated and call an instance of Unchecked_Deallocation for the task access value. (You can call Unchecked_Deallocation on an unterminated task, but it is not a good idea, in general. It is a bad idea if the task has discriminants.) ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-18 23:28 ` Robert I. Eachus @ 2003-06-19 5:09 ` Simon Wright 2003-06-19 6:39 ` Robert I. Eachus 0 siblings, 1 reply; 28+ messages in thread From: Simon Wright @ 2003-06-19 5:09 UTC (permalink / raw) "Robert I. Eachus" <rieachus@attbi.com> writes: > If you really want to. If the task is created with an allocator, > you can test for TA(...)'Terminated and call an instance of > Unchecked_Deallocation for the task access value. (You can call > Unchecked_Deallocation on an unterminated task, but it is not a good > idea, in general. It is a bad idea if the task has discriminants.) Oh, why is it worse with discriminants? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-19 5:09 ` Simon Wright @ 2003-06-19 6:39 ` Robert I. Eachus 2003-06-19 20:34 ` Simon Wright 2003-06-28 0:54 ` Matthew Heaney 0 siblings, 2 replies; 28+ messages in thread From: Robert I. Eachus @ 2003-06-19 6:39 UTC (permalink / raw) I said: >>If you really want to. If the task is created with an allocator, >>you can test for TA(...)'Terminated and call an instance of >>Unchecked_Deallocation for the task access value. (You can call >>Unchecked_Deallocation on an unterminated task, but it is not a good >>idea, in general. It is a bad idea if the task has discriminants.) After I answered Simon's question, I realized that the information in the Ada Reference Manual can really be divided into three parts: 1) (The smallest.) What you need to know to develop good software in Ada. 2) How to shoot yourself in the foot, if you really want to. 3) Where the bullet may go if you choose something from the second section. But what is totally missing from the RM is why shooting yourself in the foot is a bad idea. In this case, all the ordinary programmer should need to know is: A. Deallocating an unterminated task is certain not to be useful. B. Deallocating a terminated task is probably just as useless, but harmless. So why does the Ada RM spend so many words on this case? Othogonality. There are times when a programmer will create an object type that contains tasks. And he may want to use, say, a container package for objects of this type. (Yes, most container libraries refuse to work with limited data objects, but not all.) So the Reference Manual has to carefully define what happens when you deallocate a task object so that everything works together the way it should in that case. It is just like that discussion of garbage collectors for Ada. Are they allowed? Sure. Does the Reference Manual go to great lengths to allow Ada implementations for environments that have garbarge collectors? Sure, in fact there have been several Ada compilers that did target machines with garbage collection. The most popular was probably the Ada 83 Symbolics compiler. But should any user care if the target environment supports garbage collection? Of course not. Creating garbage in Ada means you are in section 2 or section 3, not section 1. There are debuggers, tools and special compiler options to allow you to find where garbage is being created in an Ada program. But they are useful precisely because ANY garbage in an Ada program is evidence of a bug. This used to not be true. In fact Dave Emery and I got criticized for distributing a package for reading and using command line parameters that left garbage behind. Of course, it was a copy of the command line parameters, and no matter how many times you used the facilities in the package, there was still at most one copy of the command line that could be considered garbage. How did we fix it? Got Ada.Command_Line, and Ada.Strings.Unbounded added in Ada95. How's that for a belt and suspenders fix. ;-) ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-19 6:39 ` Robert I. Eachus @ 2003-06-19 20:34 ` Simon Wright 2003-06-28 0:54 ` Matthew Heaney 1 sibling, 0 replies; 28+ messages in thread From: Simon Wright @ 2003-06-19 20:34 UTC (permalink / raw) "Robert I. Eachus" <rieachus@attbi.com> writes: (enlightening replies on deleting allocated tasks, snipped) Thanks! ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-19 6:39 ` Robert I. Eachus 2003-06-19 20:34 ` Simon Wright @ 2003-06-28 0:54 ` Matthew Heaney 2003-06-28 7:25 ` Robert I. Eachus 1 sibling, 1 reply; 28+ messages in thread From: Matthew Heaney @ 2003-06-28 0:54 UTC (permalink / raw) "Robert I. Eachus" <rieachus@attbi.com> wrote in message news:<3EF15A7C.4030901@attbi.com>... > There are times when a programmer will create an object type that > contains tasks. And he may want to use, say, a container package for > objects of this type. (Yes, most container libraries refuse to work with > limited data objects, but not all.) The new release of the Charles library does indeed work with element types that are limited. The basic idea is that when you insert an element into the container, the element is allocated with its default value -- whatever that means for the element type. For example, for an element type that is controlled, controlled initialization will occur. The list works like this: procedure Op (List : in out List_Subtype) is begin Push_Back (List); declare I : constant Iterator_Type := Last (List); E : Limited_Element_Type renames To_Access (I).all; begin --now manipulate E as desired end; end Op; A map works like this: procedure Op (Map : in out Map_Subtype) is I : Iterator_Type; begin Insert (Map, Key, I); declare E : Limited_Element_Type renames To_Access (I).all; begin --now manipulate E as desired end; end Op; For example, this schema allows you to create a map of File_Type, indexed by its file name (of type String). For example: procedure Insert (Map : in out Map_Subtype; Name : in String) is I : Iterator_Type; begin Insert (Map, Key => Name, Iterator => I); declare File : File_Type renames To_Access (I).all; begin Open (File, Mode => Out_File, Name => Name); --... end; end Insert; Not all of the containers for limited elements are there yet -- I still have to do the multisets and multimaps. I'll post them next week (30 June 2003). http://home.earthlink.net/~matthewjheaney/charles/index.html http://home.earthlink.net/~matthewjheaney/charles/charles-20030627.zip I also posted the slides from my paper presentation about Charles at the Ada-Europe 2003 conference which took place last week in Toulouse, France. http://home.earthlink.net/~matthewjheaney/charles/charles.ppt http://home.earthlink.net/~matthewjheaney/charles/charlesppt.pdf http://home.earthlink.net/~matthewjheaney/charles/charlesppt.htm ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-28 0:54 ` Matthew Heaney @ 2003-06-28 7:25 ` Robert I. Eachus 2003-06-30 7:35 ` Dmitry A. Kazakov 0 siblings, 1 reply; 28+ messages in thread From: Robert I. Eachus @ 2003-06-28 7:25 UTC (permalink / raw) I wrote: >> There are times when a programmer will create an object type that >>contains tasks. And he may want to use, say, a container package for >>objects of this type. (Yes, most container libraries refuse to work with >>limited data objects, but not all.) Matthew Heaney wrote: > The new release of the Charles library does indeed work with element > types that are limited. The basic idea is that when you insert an > element into the container, the element is allocated with its default > value -- whatever that means for the element type. For example, for > an element type that is controlled, controlled initialization will > occur. Not quite what I had in mind, but great. I was thinking of container packages that manage references/access values, assuming that the original objects cannot be moved or changed. When I need a package like this, I usually encapsulate a "normal" container library around a limited type and an explicit access type: generic type Element is limited private; type Pointer is access Element; package Limited_Stack is procedure Push(E: in Element); procedure Push(P: in Pointer); function Peek return Pointer; function Pop return Pointer; function Pop return Element; -- constant view... end Limited_Stack; The explicit access type is because of the rules on return by reference providing a constant view. I may propose as an Ada 0Y revision allowing return by reference functions where a view conversion would be allowed. In other words, you could have a return by reference function as an in out parameter in another call. It seems that should be part of AI-318, but AI-318 goes a lot further without addressing this at all. An alternative would be allowing a function to return an anonymous access type. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-28 7:25 ` Robert I. Eachus @ 2003-06-30 7:35 ` Dmitry A. Kazakov 2003-06-30 15:01 ` Matthew Heaney 2003-07-03 9:53 ` Robert I. Eachus 0 siblings, 2 replies; 28+ messages in thread From: Dmitry A. Kazakov @ 2003-06-30 7:35 UTC (permalink / raw) On Sat, 28 Jun 2003 07:25:02 GMT, "Robert I. Eachus" <rieachus@attbi.com> wrote: >I wrote: >>> There are times when a programmer will create an object type that >>>contains tasks. And he may want to use, say, a container package for >>>objects of this type. (Yes, most container libraries refuse to work with >>>limited data objects, but not all.) > >Matthew Heaney wrote: >> The new release of the Charles library does indeed work with element >> types that are limited. The basic idea is that when you insert an >> element into the container, the element is allocated with its default >> value -- whatever that means for the element type. For example, for >> an element type that is controlled, controlled initialization will >> occur. > >Not quite what I had in mind, but great. I was thinking of container >packages that manage references/access values, assuming that the >original objects cannot be moved or changed. When I need a package like >this, I usually encapsulate a "normal" container library around a >limited type and an explicit access type: > > generic > type Element is limited private; A short question. Why not: type Element (<>) is limited private; [I am using this in my containers because it is weaker than just limited private.] > type Pointer is access Element; > package Limited_Stack is > procedure Push(E: in Element); > procedure Push(P: in Pointer); > function Peek return Pointer; > function Pop return Pointer; > function Pop return Element; -- constant view... > end Limited_Stack; > >The explicit access type is because of the rules on return by reference >providing a constant view. I may propose as an Ada 0Y revision allowing >return by reference functions where a view conversion would be allowed. > In other words, you could have a return by reference function as an in >out parameter in another call. It seems that should be part of AI-318, >but AI-318 goes a lot further without addressing this at all. An >alternative would be allowing a function to return an anonymous access type. Or both! Returned anonymous access type could be very useful for tagged types, because it would make operations returning a pointer primitive and covariant, which is presently impossible. --- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-30 7:35 ` Dmitry A. Kazakov @ 2003-06-30 15:01 ` Matthew Heaney 2003-07-01 7:19 ` Dmitry A. Kazakov 2003-07-02 12:05 ` Mário Amado Alves 2003-07-03 9:53 ` Robert I. Eachus 1 sibling, 2 replies; 28+ messages in thread From: Matthew Heaney @ 2003-06-30 15:01 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote in message news:<0gpvfv49qaa0b62ab5m0kg39kka66sis8t@4ax.com>... > On Sat, 28 Jun 2003 07:25:02 GMT, "Robert I. Eachus" > <rieachus@attbi.com> wrote: > > > generic > > type Element is limited private; > > A short question. Why not: > > type Element (<>) is limited private; > > [I am using this in my containers because it is weaker than just > limited private.] Because the type must be definite, of course! Otherwise, how would you know how much space to allocate for the object? Consider the following type (as you've declared it above): package P is type T (<>) is limited private; private type T is limited null record; end P; Here's a little puzzle: how do you declare an instance of type T? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-30 15:01 ` Matthew Heaney @ 2003-07-01 7:19 ` Dmitry A. Kazakov 2003-07-01 14:21 ` Matthew Heaney 2003-07-02 12:05 ` Mário Amado Alves 1 sibling, 1 reply; 28+ messages in thread From: Dmitry A. Kazakov @ 2003-07-01 7:19 UTC (permalink / raw) On 30 Jun 2003 08:01:29 -0700, mheaney@on2.com (Matthew Heaney) wrote: >Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote in message news:<0gpvfv49qaa0b62ab5m0kg39kka66sis8t@4ax.com>... >> On Sat, 28 Jun 2003 07:25:02 GMT, "Robert I. Eachus" >> <rieachus@attbi.com> wrote: >> >> > generic >> > type Element is limited private; >> >> A short question. Why not: >> >> type Element (<>) is limited private; >> >> [I am using this in my containers because it is weaker than just >> limited private.] > >Because the type must be definite, of course! Otherwise, how would >you know how much space to allocate for the object? > >Consider the following type (as you've declared it above): > >package P is > type T (<>) is limited private; >private > type T is limited null record; >end P; > >Here's a little puzzle: how do you declare an instance of type T? I thought the container has only pointers to instances which are created by caller, but maybe I missed something. [ An advantage in having (<>) for Element is that it could then have T'Class as actual. For example: type Operand is new Ada.Finalization.Limited_Controlled with private; type Operand_Ptr is access all Operand'Class; ... package Argument_Stack is new Limited_Stack (Element => Operand'Class, Pointer => Operand_Ptr); ] --- Regards, Dmitry Kazakov www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-07-01 7:19 ` Dmitry A. Kazakov @ 2003-07-01 14:21 ` Matthew Heaney 0 siblings, 0 replies; 28+ messages in thread From: Matthew Heaney @ 2003-07-01 14:21 UTC (permalink / raw) Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote in message news:<tnc2gvkr3fu9rpkd0tu56095ttbuflkgi9@4ax.com>... > > I thought the container has only pointers to instances which are > created by caller, but maybe I missed something. > > [ An advantage in having (<>) for Element is that it could then have > T'Class as actual. For example: > > type Operand is new Ada.Finalization.Limited_Controlled with private; > type Operand_Ptr is access all Operand'Class; > ... > package Argument_Stack is new Limited_Stack > (Element => Operand'Class, Pointer => Operand_Ptr); > ] Then we are comparing apples and oranges. The containers I was talking about are declared like this: generic type Element_Type is limited private; package Generic_Container is ...; Strictly speaking your container doesn't have elements -- it has pointers to elements. The model in Charles is that an element is a component of an internal node of storage, which is designated by an iterator. If you want an access object that designates the element, then you can use Generic_Element to convert ("dereference") the iterator to the access type. Your container seems to have two levels of indirection: a pointer to an internal node contains a pointer to the element. In Charles there is only a single level of indirection. http://home.earthlink.net/~matthewjheaney/charles/index.html Of course, there is still the problem of a container of elements of indefinite type T'Class, which your container more or less solves. There are at least a couple of ways to do that in Charles. One way is to use a nonlimited container of pointers: package T_Class_Lists is new Charles.Lists.Double.Unbounded (T_Class_Access); Insert (List, New_Item => new T'Class'(...), Before => I); This implies that you have to manually deallocate the items prior to destruction of the container object, which you can do easily enough by passing an instantiation of Unchecked_Deallocation as the generic actual to Generic_Modify_Element. If you want to automate the finalization of container elements then you can use an Access_Control object as the element of a limited list: package T_Class_Lists is new Charles.Lists.Double.Limited_Unbounded (Pointer_Type); where Pointer_Type is an instantiation of Charles.Access_Control. (That package is analogous to the auto_ptr in C++.) You'd do something like: Insert (List, Before => I, Iterator => J); declare P : Pointer_Type renames To_Access (J).all; begin Initialize (P, new T'Class'(...)); end; So now when you delete the item: Delete (List, Iterator => J); then Free will be invoked automatically as a side-effect of finalization of the Pointer_Type object. One of the things that is lacking in the C++ STL is that you can't use an auto_ptr as a container element. The limited containers in Charles were partly motivated by a desire to provide that ability. The syntax is admittedly heavy, but you can ease the pain as desired by creating a thin layer (either over just the insertion operations as in the example above, or over the entire container). If there is interest then perhaps we can generalize your original idea by creating another container form: generic type Element_Type (<>) is limited private; type Handle_Type is private; with procedure Finalize (Handle : in out Handle_Type) is <>; package Generic_Indefinite_Containers is type Container_Type is limited private; procedure Insert (Container : in out Container_Type; New_Item : in Handle_Type); ... end Generic_Indefinite_Containers; Of course we could be more specific, by using an access type directly as the handle: generic type Element_Type (<>) is limited private; type Element_Access is access all Element_Type; with procedure Free (X : in out Element_Access) is <>; package Generic_Indefinite_Containers is ...; It would be trivial to implement either of these as a thin layer over the existing components in Charles, which is largely why I haven't bothered creating a separate component for indefinite types. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-30 15:01 ` Matthew Heaney 2003-07-01 7:19 ` Dmitry A. Kazakov @ 2003-07-02 12:05 ` Mário Amado Alves 2003-07-02 19:41 ` Simon Wright 1 sibling, 1 reply; 28+ messages in thread From: Mário Amado Alves @ 2003-07-02 12:05 UTC (permalink / raw) "Why not: type Element (<>) is limited private;" (Dmitri) "Because the type must be definite, of course! Otherwise, how would you know how much space to allocate for the object?" (Matthew) With the amazing 'Size attribute, of course! What I have *not* figured out yet is how to use the really amazing 'Definite attribute to choose the most efficient implementation automatically (at compile or at run time). Matthew should remember the small talk we had about this in Toulouse. His impression was this is not possible and after a little research that is my impression too. But never loose hope! Namely there is always Ada 2015: -- Don't try this at home! generic type Element_Type (<>) is private; package Unbounded_Arrays is when Element'Definite => new package Unbounded_Arrays_For_Definite_Elements (Element_Type); when not => new package Unbounded_Arrays_For_Nondefinite_Elements (Element_Type); end; Cheers, --Marius ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-07-02 12:05 ` Mário Amado Alves @ 2003-07-02 19:41 ` Simon Wright 2003-07-03 21:31 ` Mário Amado Alves 0 siblings, 1 reply; 28+ messages in thread From: Simon Wright @ 2003-07-02 19:41 UTC (permalink / raw) maa@liacc.up.pt (M�rio Amado Alves) writes: > "Why not: > type Element (<>) is limited private;" (Dmitri) > > "Because the type must be definite, of course! Otherwise, how would > you know how much space to allocate for the object?" (Matthew) > > With the amazing 'Size attribute, of course! Am I missing something? I thought the point of indefinite types was that different objects of the type might have different sizes? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-07-02 19:41 ` Simon Wright @ 2003-07-03 21:31 ` Mário Amado Alves 0 siblings, 0 replies; 28+ messages in thread From: Mário Amado Alves @ 2003-07-03 21:31 UTC (permalink / raw) > > "Why not: > > type Element (<>) is limited private;" (Dmitri) > > > > "Because the type must be definite, of course! Otherwise, how would > > you know how much space to allocate for the object?" (Matthew) > > > > With the amazing 'Size attribute, of course! (Marius) > > Am I missing something? I thought the point of indefinite types was > that different objects of the type might have different sizes? (Simon) It is. I was refering to Object'Size, not Type'Size, of course. Type'Size for indefinite types is of course nonsense (ARM says implementation defined). Object'Size tells you exactly "how much space to allocate for the object". (Unless Matt's "object" is the container, not the element. But is there any interesting container with an priori known size, even for definite elements?) ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: DYNAMIC ADA TASK CREATION? 2003-06-30 7:35 ` Dmitry A. Kazakov 2003-06-30 15:01 ` Matthew Heaney @ 2003-07-03 9:53 ` Robert I. Eachus 1 sibling, 0 replies; 28+ messages in thread From: Robert I. Eachus @ 2003-07-03 9:53 UTC (permalink / raw) Dmitry A. Kazakov wrote: > A short question. Why not: > > type Element (<>) is limited private; > > [I am using this in my containers because it is weaker than just > limited private.] A short answer, Matt has provided additional discussion. There are many cases in Ada where you can wrap a limited object with discriminants in a record without discriminats. It seems crazy, but the package which is now Ada.Strings.Bounded started out as a "trick" I kept distributing to show how to do it. -- Robert I. Eachus �In an ally, considerations of house, clan, planet, race are insignificant beside two prime questions, which are: 1. Can he shoot? 2. Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and Steve Miller. ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2003-07-03 21:31 UTC | newest] Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2003-06-17 19:53 DYNAMIC ADA TASK CREATION? avram 2003-06-17 20:24 ` Simon Wright 2003-06-18 6:11 ` Robert I. Eachus 2003-06-18 9:20 ` Georg Bauhaus 2003-06-18 11:13 ` John McCabe 2003-06-18 12:43 ` John McCabe 2003-06-18 14:17 ` Georg Bauhaus 2003-06-19 5:07 ` Simon Wright 2003-06-19 6:05 ` Robert I. Eachus 2003-06-19 23:30 ` Jeffrey Carter 2003-06-18 19:15 ` avram 2003-06-18 21:17 ` Craig Carey 2003-06-20 18:56 ` avram 2003-06-21 13:06 ` Pascal Obry 2003-06-18 23:28 ` Robert I. Eachus 2003-06-19 5:09 ` Simon Wright 2003-06-19 6:39 ` Robert I. Eachus 2003-06-19 20:34 ` Simon Wright 2003-06-28 0:54 ` Matthew Heaney 2003-06-28 7:25 ` Robert I. Eachus 2003-06-30 7:35 ` Dmitry A. Kazakov 2003-06-30 15:01 ` Matthew Heaney 2003-07-01 7:19 ` Dmitry A. Kazakov 2003-07-01 14:21 ` Matthew Heaney 2003-07-02 12:05 ` Mário Amado Alves 2003-07-02 19:41 ` Simon Wright 2003-07-03 21:31 ` Mário Amado Alves 2003-07-03 9:53 ` Robert I. Eachus
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox