1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S Y S T E M . S H A R E D _ S T O R A G E --
-- --
-- S p e c --
-- --
-- Copyright (C) 1998-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
-- This package manages the shared/persistent storage required for
-- full implementation of variables in Shared_Passive packages, more
-- precisely variables whose enclosing dynamic scope is a shared
-- passive package. This implementation is specific to GNAT and GLADE
-- provides a more general implementation not dedicated to file
-- storage.
-- This unit (and shared passive partitions) are supported on all
-- GNAT implementations except on OpenVMS (where problems arise from
-- trying to share files, and with version numbers of files)
-- --------------------------
-- -- Shared Storage Model --
-- --------------------------
-- The basic model used is that each partition that references the
-- Shared_Passive package has a local copy of the package data that
-- is initialized in accordance with the declarations of the package
-- in the normal manner. The routines in System.Shared_Storage are
-- then used to ensure that the values in these separate copies are
-- properly synchronized with the state of the overall system.
-- In the GNAT implementation, this synchronization is ensured by
-- maintaining a set of files, in a designated directory. The
-- directory is designated by setting the environment variable
-- SHARED_MEMORY_DIRECTORY. This variable must be set for all
-- partitions. If the environment variable is not defined, then the
-- current directory is used.
-- There is one storage for each variable. The name is the fully
-- qualified name of the variable with all letters forced to lower
-- case. For example, the variable Var in the shared passive package
-- Pkg results in the storage name pkg.var.
-- If the storage does not exist, it indicates that no partition has
-- assigned a new value, so that the initial value is the correct
-- one. This is the critical component of the model. It means that
-- there is no system-wide synchronization required for initializing
-- the package, since the shared storages need not (and do not)
-- reflect the initial state. There is therefore no issue of
-- synchronizing initialization and read/write access.
-- -----------------------
-- -- Read/Write Access --
-- -----------------------
-- The approach is as follows:
-- For each shared variable, var, an instantiation of the below generic
-- package is created which provides Read and Write supporting procedures.
-- The routine Read in package System.Shared_Storage.Shared_Var_Procs
-- ensures to assign variable V to the last written value among processes
-- referencing it. A call to this procedure is generated by the expander
-- before each read access to the shared variable.
-- The routine Write in package System.Shared_Storage.Shared_Var_Proc
-- set a new value to the shared variable and, according to the used
-- implementation, propagate this value among processes referencing it.
-- A call to this procedure is generated by the expander after each
-- assignment of the shared variable.
-- Note: a special circuit allows the use of stream attributes Read and
-- Write for limited types (using the corresponding attribute for the
-- full type), but there are limitations on the data that can be placed
-- in shared passive partitions. See sem_smem.ads/adb for details.
-- ----------------------------------------------------------------
-- -- Handling of Protected Objects in Shared Passive Partitions --
-- ----------------------------------------------------------------
-- In the context of GNAT, during the execution of a protected
-- subprogram call, access is locked out using a locking mechanism
-- per protected object, as provided by the GNAT.Lock_Files
-- capability in the specific case of GNAT. This package contains the
-- lock and unlock calls, and the expander generates a call to the
-- lock routine before the protected call and a call to the unlock
-- routine after the protected call.
-- Within the code of the protected subprogram, the access to the
-- protected object itself uses the local copy, without any special
-- synchronization. Since global access is locked out, no other task
-- or partition can attempt to read or write this data as long as the
-- lock is held.
-- The data in the local copy does however need synchronizing with
-- the global values in the shared storage. This is achieved as
-- follows:
-- The protected object generates a read and assignment routine as
-- described for other shared passive variables. The code for the
-- 'Read and 'Write attributes (not normally allowed, but allowed
-- in this special case) simply reads or writes the values of the
-- components in the protected record.
-- The lock call is followed by a call to the shared read routine to
-- synchronize the local copy to contain the proper global value.
-- The unlock call in the procedure case only is preceded by a call
-- to the shared assign routine to synchronize the global shared
-- storages with the (possibly modified) local copy.
-- These calls to the read and assign routines, as well as the lock
-- and unlock routines, are inserted by the expander (see exp_smem.adb).
package System.Shared_Storage is
procedure Shared_Var_Lock (Var : String);
-- This procedure claims the shared storage lock. It is used for
-- protected types in shared passive packages. A call to this
-- locking routine is generated as the first operation in the code
-- for the body of a protected subprogram, and it busy waits if
-- the lock is busy.
procedure Shared_Var_Unlock (Var : String);
-- This procedure releases the shared storage lock obtained by a
-- prior call to the Shared_Var_Lock procedure, and is to be
-- generated as the last operation in the body of a protected
-- subprogram.
-- This generic package is instantiated for each shared passive
-- variable. It provides supporting procedures called upon each
-- read or write access by the expanded code.
generic
type Typ is limited private;
-- Shared passive variable type
V : in out Typ;
-- Shared passive variable
Full_Name : String;
-- Shared passive variable storage name
package Shared_Var_Procs is
procedure Read;
-- Shared passive variable access routine. Each reference to the
-- shared variable, V, is preceded by a call to the corresponding
-- Read procedure, which either leaves the initial value unchanged
-- if the storage does not exist, or reads the current value from
-- the shared storage.
procedure Write;
-- Shared passive variable assignment routine. Each assignment to
-- the shared variable, V, is followed by a call to the corresponding
-- Write procedure, which writes the new value to the shared storage.
end Shared_Var_Procs;
end System.Shared_Storage;
|