LARMSTRONG%rca.com@RELAY.CS.NET ("LEN ARMSTRONG ", SYSTEMS LAB) (10/13/86)
OK, I need some help -- anyone wanna' volunteer? I have a construct similar to the following: package P is task type T is entry E1; -- Entries are really unimportant for this example. entry E2; end T; type TR (PARAM_FIELD : <SOME_TYPE>) is record TASK_FIELD : T; end record; XX : TR(<SOME_CONSTANT_VALUE_OF_<SOME_TYPE>>) end P; However, my problem comes in when I am in the body of the task type T. I need to access inside XX.TASK_FIELD the value held by XX.PARAM_FIELD. Does anyone know of anyway I can do this? For some reason, I feel my chances of being allowed to do it are very slim. I would really like to be able to keep the lexical structure I am currently using (as defined above) but other solutions are welcome also. Thanks, Len LArmstrong%Henry@RCA.Com
gary@telesoft.UUCP@ndmce.uucp (Gary Dismukes @lizard) (10/18/86)
In response to Len Armstrong's question regarding tasks and discriminants: Since the access that a task has to data outside of its body is essentially limited to visible objects declared prior to the task body and to data passed in as entry parameters, there is no way for a task to directly access a discriminant of a record type containing the task as a component. At one point during the language design process there was some discussion of allowing discriminants to be declared for task types. However, this was not long before the standardization of Ada and it was felt that not enough time was available to give the necessary attention to integrating such a feature so it was not added. There is, however, a way to achieve the basic functionality that you are looking for. One approach to solving the problem would be to require an explicit call to an initialization entry after the declaration of the record object. Using the given example we would have: declare X: TR( SOME_VALUE_OF_SOME_TYPE ); begin X.TASK_FIELD.INITIALIZE( X.PARAM_FIELD ); ... end; This is clearly undesirable because of the separation of the declaration and initialization of the object. We would prefer that the user of the type TR need not be concerned with the initialization of the task. An alternative approach is to introduce an access type and initialization function as shown below: package PKG is task type T is entry INITIALIZE ( INIT_PARAM: SOME_TYPE ); entry E1; entry E2; end T; type T_ACCESS is access T; function T_INIT ( INIT_PARAM: SOME_TYPE ) return T_ACCESS; type TR ( PARAM_FIELD: SOME_TYPE ) is record TASK_FIELD : T_ACCESS := T_INIT( PARAM_FIELD ); end record; end PKG; package body PKG is task body T is PARAMETER: SOME_TYPE; begin accept INITIALIZE ( INIT_PARAM: SOME_TYPE ) do PARAMETER:= INIT_PARAM; end INITIALIZE; ... end T; function T_INIT ( INIT_PARAM: SOME_TYPE ) return T_ACCESS is NEW_T: T_ACCESS := new T; begin NEW_T.INITIALIZE( INIT_PARAM ); return NEW_T; end T_INIT; end PKG; It then suffices to declare an object of type PKG.TR with the appropriate discriminant constraint: XX : PKG.TR( SOME_VALUE_OF_SOME_TYPE ); This solution encapsulates the creation and initialization of the task object within a function and relies on the ability to use a discriminant in the default value expression for a record component. The replacement of the task component with an access component is largely transparent to the user because of the implicit dereferencing for entry calls (e.g., XX.TASK_FIELD.E1). The main disadvantage is that, if deallocation of the task object is an important concern, an explicit unchecked deallocation will be necessary unless the implementation supports garbage collection. There is also a fundamental limitation in using discriminants to parameterize tasks because the type of a discriminant is restricted by the language to being a discrete type, but this may not matter for the application considered. Gary Dismukes TeleSoft
Bryan@SIERRA.STANFORD.EDU@ndmce.uucp (Doug Bryan) (10/18/86)
Here is an idea for you... let me know if you get anything better. doug ........................ generic package Pack is task type T is entry My_Discriminant (D : Integer); entry Echo_Discriminant; end T; type Acc is access T; function F (D : Integer) return Acc; type Rec (D : Integer) is record Acc_T : Acc := F (D); end record; end Pack; ------------------------------- with Text_Io; package body Pack is function F (D : Integer) return Acc is A : Acc := new T; begin A.My_Discriminant (D); return A; end F; task body T is Local_Discriminant : Integer; begin accept My_Discriminant (D : Integer) do Local_Discriminant := D; end My_Discriminant; accept Echo_Discriminant; Text_Io.Put_Line (Integer'Image (Local_Discriminant)); end T; end Pack; ------------------------------- with Pack; procedure Disc_Task is package P is new Pack; -- Pack is generic in order to force elaboration of body before -- the following objects are elaborated. Rec_1 : P.Rec (1); Rec_2 : P.Rec (2); Rec_3 : P.Rec (3); begin Rec_1.Acc_T.Echo_Discriminant; Rec_2.Acc_T.Echo_Discriminant; Rec_3.Acc_T.Echo_Discriminant; end Disc_Task; -------