with Text_Io, Ada.Integer_Text_Io; use Text_Io, Ada.Integer_Text_Io; with Ada.Float_Text_Io; use Ada.Float_Text_Io; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; -- mutex, protected type version -- In 1995 the Ada language was updated to become more object oriented. -- A new construct called a protected type was added to the language that -- automates some of the basic capabilities provided by the -- select-when-accept combination of the previous program. This program -- does the same thing as testandset.adb, but this time with a protected -- type "object". -- A "method" of a protected type object can either be a function, -- a procedure, or an "entry", which are not exactly the same as the entries -- we saw earlier. These entries are not used along with "accept". -- All data variables must be declared in the "private" section of the -- protected type. Procedures are executed mutually exclusively. That -- is, if one task is executing a procedure of a protected type, all -- tasks that calls procedures on that object will be suspended in a queue. -- When a procedure exits, another task can be let in. This protection -- mechanism is similar to "synchronized" methods in Java. Functions, -- unlike procedure, are only allowed READ access to the private data. They -- thus cannot change the state of a procedure (don't ask me what happens -- when there are pointers though - I don't know!). It's thus OK to have -- multiple task call functions concurrently. Entries are the same as -- procedures except that they have a "when" condition. procedure Testandset2 is protected type Mutexvar is entry Lock; procedure Unlock; function Currentstate return Boolean; private -- all data must be declared in private section Free : Boolean := True; end Mutexvar; protected body Mutexvar is entry Lock when Free is begin Free := False; end Lock; procedure Unlock is begin Free := True; end Unlock; -- functions do not implement mutual exclusion. function Currentstate return Boolean is begin return Free; end Currentstate; end Mutexvar; --------------- test - the rest is the same as the first version. X : Integer := 0; -- shared integer Mutex0 : Mutexvar; -- shared instance of mutexvar task type CR(Id : Integer); -- critical region task task body CR is begin loop Put(Id,Width=>2); Put("entering critical section"); New_Line; Mutex0.Lock; Put(Id,Width=>2); Put("entered critical section"); New_Line; X := X+1; Put(Id,Width=>2); Put("leaving critical section"); New_Line; Mutex0.Unlock; end loop; end CR; TaskA : CR(1); TaskB : CR(2); begin -- main procedure Put("nothing for main procedure to do in this program."); New_Line; end testandset2;