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