Download presentation
Presentation is loading. Please wait.
Published byAbner Newman Modified over 9 years ago
1
1 16-035 Ada Constructs Revisited 21 Oct. 2002
2
2 16-035 Constructs to be Expanded Generics Tasking Elaboration
3
3 16-035 Generics Generic units are used to make Ada’s strong types less painful —Possible to create general unit once, but use it for many different declared types —Has types, variables, subprograms, and packages as parameters —When each instance is made of a generic unit, it might be a separate copy, or it might share code
4
4 16-035 Non-Generic Version package Complex_Numbers is type Complex is private;... function Construct (Real : Float; Imaginary : Float) return Complex; function “+” (X, Y: Complex) return Complex;... private type Complex is record Real_Part : Float; Imaginary_Part : Float; end record; end;
5
5 16-035 Non-Generic Body package body Complex_Numbers is... function Construct (Real : Float; Imaginary : Float) return Complex is begin return Complex’(Real, Imaginary); end Construct; function “+” (X, Y: Complex) return Complex is begin return Complex’( (X.Real_Part + Y.Real_Part), (X.Imaginary_Part + Y.Imaginary_Part) ); end “+”;... end Complex_Numbers;
6
6 16-035 Generic Example generic type My_Float is digits <>; package Generic_Complex_Numbers is type Complex is private;... function Construct (Real : My_Float; Imaginary : My_Float) return Complex; function “+” (X, Y: Complex) return Complex;... private type Complex is record Real_Part : My_Float; Imaginary_Part : My_Float; end record; end;
7
7 16-035 Generic Body – Almost Identical to Non-Generic package body Generic_Complex_Numbers is... function Construct (Real : My_Float; Imaginary : My_Float) return Complex is begin return Complex’(Real, Imaginary); end Construct; function “+” (X, Y: Complex) return Complex is begin return Complex’( (X.Real_Part + Y.Real_Part), (X.Imaginary_Part + Y.Imaginary_Part) ); end “+”;... end Generic_Complex_Numbers;
8
8 16-035 Instantiating a Generic with Generic_Complex_Numbers; procedure Test is type Small_Float_type is digits 6; type Large_Float_type is digits 14; package Small_Complex is new Generic_Complex_Numbers (Small_Float_type); use Small_Complex; package Large_Complex is new Generic_Complex_Numbers (Large_Float_type); use Large_Complex; Small_Real_Part : Small_Float_type := 1.234_567; Small_Imaginary_Part : Small_Float_type := 2.345_678; Large_Real_Part : Large_Float_type := 3.456_789_101_112; Large_Imaginary_Part : Large_Float_type := 4.567_891_011_121_3; Small_Complex_Number : Small_Complex.Complex := Construct (Small_Real_Part, Small_Imaginary_Part); Large_complex_Number : Large_Complex.Complex := Construct (Large_Real_part, Large_Imaginary_Part); begin Small_Complex_Number := Small_Complex_Number + Small_Complex_Number; Large_Complex_Number := Large_Complex_Number + Large_Complex_Number; end Test;
9
9 16-035 Tasking Multitasking (what UNIX people call Threads) is built in to the Ada language —Model is parallel activities —Easily implemented to use multiple processors —Implementation can use any scheduling mechanism »Time slicing, where each task (of the same priority) gets a bit of time, then the next task runs »One task runs until it hits a blocking point, then the next task (of the same priority or lower) runs —Priority can be used (if supported) to force the system to run tasks in a certain order (if running on a single processor system)
10
10 16-035 The rendezvous “two people meet, perform a transaction and then go on independently” Between two tasks: one task calls an entry declared in another. Task Specification task T is entry E( … ); end; Some other Task T.E( … ); Task Body accept E( … ) do --sequence of statements end E;
11
11 16-035 Simple mechanism to create critical sections: section of code that must be executed by only one task at a time task type Semaphore is entry P; -- Dijkstra’s terminology entry V; -- Passeren (lock) end Semaphore; -- Vrimajken (unlock) task body Semaphore is begin loop accept P; accept V; -- will not accept another P until a caller asks for V end loop; end Semaphore; Example: semaphore
12
12 16-035 Using a semaphore A task that needs exclusive access to the critical section executes: Semaphore.P; … -- critical section code Semaphore.V; If in the meantime another task calls Semaphore.P, it blocks, because the semaphore does not accept a call to P until after the next call to V : the other task is blocked until the current one releases by making an entry call to V. Programming hazards: –someone else may call V : race condition –no one calls V: other callers are deadlocked –Starvation is possible if the queue is not a FIFO queue
13
13 16-035 Timing and scheduling Time slicing Priorities Real-Time Systems annex (Annex D) Task can be held up of different reasons —Waiting for: »a partner in a rendezvous »dependent task to terminate —delay 3.0; Seconds: constant duration := 1.0; Minutes: constant Duration := 60.0; Hours: constant Duration := 3600.0; delay 2*Hours+40*Minutes;
14
14 16-035 Example loop delay 5*Minutes; Action; end loop; Want cyclic execution. Any problems with this solution?
15
15 16-035 Same, but different … declare use Calendar; Interval: constant Duration := 5*Minutes; Next_Time: Time := First_Time; begin loop delay until Next_Time; Action; Next_Time := Next_Time + Interval; end loop; end;
16
16 16-035 “Protected Variable” Protect a variable V from uncontrolled access. package Protected_Variable is procedure Read(X: out Item); procedure Write(X: in Item); end; package body Protected_Variable is V: Item := initial value; procedure Read(X: out Item) is begin X := V; end; procedure Write(X: in Item) is begin V := X; end; end Protected_Variable; type Item is record X_Coord: Float; Y_Coord: Float; end record; Any problems?
17
17 16-035 Protected Object Example package Variable is type My_Type is...; protected P_Variable is function Read return My_Type; -- Many callers procedure Write ( -- One caller X : in My_Type ); private V : My_Type := 0; end P_Variable; end Variable; Any number of tasks may call protected functions at the same time Protected functions can not write to protected objects Not possible for a task to call Write while another calls Read (the second will block)
18
18 16-035 Bounded buffer IJ N: constant := 8; type Index is mod N; type Item_Array is array (Index) of Item; protected type Buffering is entry Put(X: in Item); entry Get(X: out Item); private A: Item_Array; I,J: Index := 0; Count: Integer range 0..N := 0; end Buffering; protected body Buffering is entry Put(X: in Item) when Count < N is begin A(I) := X; I := I+1; Count := Count + 1; end Put; entry Get(X: out Item) when Count >0 is begin X := A(J); J := J + 1; Count := Count – 1; end Get; end Buffering; My_Buffer : Buffering; … My_Buffer.Put(X);
19
19 16-035 Elaboration Ada programs perform work before the first executable statement after the “begin” of the main procedure is run —“Elaboration” code is executed first »Gives data initial values (which might call functions) »Creates objects (if dynamic) »Runs package initialization code To be completely precise, the whole program is one big elaboration —Package specifications are elaborated before their bodies —Package bodies are elaborated before any of their subprograms can be called —Package bodies can have task bodies, which start running after the package body has been elaborated —When all packages have been elaborated, the main procedure runs
20
20 16-035 Elaboration Example with Ada.Text_IO; procedure Elab_Test is package Random_Pack is -- Elaboration of this is first type My_Type is digits 6 range 0.0.. 1.0; function Random return My_Type; end Random_Pack; package body Random_Pack is -- Elaboration of this is second Seed : My_Type; function Random return My_Type is task My_Task; task body My_Task is X : My_Type := Random; begin Ada.Text_IO.Put ("Made it"); end My_Task; begin return Seed; -- For now, return a constant end Random; begin Seed := 0.5; -- Need this before Random can be called end Random_Pack; -- After last statement after "begin", My_Task can run use Random_Pack; Z : My_Type := Random; -- Executes the Random function begin null; end Elab_Test;
21
21 16-035 Watch Out for Circular Dependencies package My_Pack is type My_type is range 1_000.. 1_000_000; procedure Do_Something (Parameter : in out My_type); end My_Pack; package Other_Pack is type Other_type is range 0.. 1_000; function Do_Something_Else return Other_type; end Other_Pack; with Other_Pack; pragma Elaborate (Other_Pack); package body My_Pack is X : Other_Pack.Other_type := Do_Something_Else; -- Needs Other_Pack body elab... end My_Pack; with My_Pack; package body Other_Pack is X : My_Pack.My_type;... end Other_Pack;
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.