|
| 1 | +=============== |
| 2 | +GNAT Semaphores |
| 3 | +=============== |
| 4 | + |
| 5 | +---------- |
| 6 | +Semaphores |
| 7 | +---------- |
| 8 | + |
| 9 | +* Shared counters |
| 10 | +* Multitask-safe |
| 11 | + |
| 12 | + - Support priorities from "Real-time Systems" LRM Annex D |
| 13 | + |
| 14 | +* :ada:`Counting_Semaphore` and :ada:`Binary_Semaphore` |
| 15 | + |
| 16 | + - :ada:`protected` types |
| 17 | + - Counting holds an Integer |
| 18 | + - Binary holds a Boolean |
| 19 | + |
| 20 | +* Priority ceiling (LRM D.3) |
| 21 | + |
| 22 | + - For :ada:`pragma Locking_Policy (Ceiling_Locking)` |
| 23 | + - Protects against priority inversions |
| 24 | + |
| 25 | + |
| 26 | +--------- |
| 27 | +Interface |
| 28 | +--------- |
| 29 | + |
| 30 | +.. code:: Ada |
| 31 | +
|
| 32 | + protected type Counting_Semaphore |
| 33 | + (Initial_Value : Natural; |
| 34 | + [...] |
| 35 | +
|
| 36 | + entry Seize; |
| 37 | + -- Blocks caller until/unless the semaphore's internal counter is |
| 38 | + -- greater than zero. Decrements the semaphore's internal counter when |
| 39 | + -- executed. |
| 40 | +
|
| 41 | + procedure Release; |
| 42 | + -- Increments the semaphore's internal counter |
| 43 | +
|
| 44 | +.. code:: Ada |
| 45 | +
|
| 46 | + protected type Binary_Semaphore |
| 47 | + (Initially_Available : Boolean; |
| 48 | +
|
| 49 | +.. code:: Ada |
| 50 | +
|
| 51 | + subtype Mutual_Exclusion is Binary_Semaphore |
| 52 | + (Initially_Available => True, |
| 53 | + Ceiling => Default_Ceiling); |
| 54 | +
|
| 55 | +------------------ |
| 56 | +Idiom: Scope Locks |
| 57 | +------------------ |
| 58 | + |
| 59 | +* Automatic release |
| 60 | + |
| 61 | +.. code:: Ada |
| 62 | +
|
| 63 | + type Scope_Lock (Lock : access Mutual_Exclusion) is |
| 64 | + new Ada.Finalization.Limited_Controlled with null record; |
| 65 | +
|
| 66 | + procedure Initialize (This : in out Scope_Lock) is |
| 67 | + begin |
| 68 | + This.Lock.Seize; |
| 69 | + end Initialize; |
| 70 | +
|
| 71 | + procedure Finalize (This : in out Scope_Lock) is |
| 72 | + begin |
| 73 | + This.Lock.Release; |
| 74 | + end Finalize; |
| 75 | + |
| 76 | + Mutex : aliased Mutual_Exclusion; |
| 77 | +
|
| 78 | + State : Integer := 0; |
| 79 | +
|
| 80 | + procedure Operation_1 is |
| 81 | + S : Scope_Lock (Mutex’Access); |
| 82 | + begin |
| 83 | + State := State + 1; -- for example... |
| 84 | + Put_Line ("State is now" & State'Img); |
| 85 | + end Operation_1; |
0 commit comments