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-2008, 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 2, 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. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 ------------------------------------------------------------------------------
34 -- This package manages the shared/persistent storage required for
35 -- full implementation of variables in Shared_Passive packages, more
36 -- precisely variables whose enclosing dynamic scope is a shared
37 -- passive package. This implementation is specific to GNAT and GLADE
38 -- provides a more general implementation not dedicated to file
41 -- This unit (and shared passive partitions) are supported on all
42 -- GNAT implementations except on OpenVMS (where problems arise from
43 -- trying to share files, and with version numbers of files)
45 -- --------------------------
46 -- -- Shared Storage Model --
47 -- --------------------------
49 -- The basic model used is that each partition that references the
50 -- Shared_Passive package has a local copy of the package data that
51 -- is initialized in accordance with the declarations of the package
52 -- in the normal manner. The routines in System.Shared_Storage are
53 -- then used to ensure that the values in these separate copies are
54 -- properly synchronized with the state of the overall system.
56 -- In the GNAT implementation, this synchronization is ensured by
57 -- maintaining a set of files, in a designated directory. The
58 -- directory is designated by setting the environment variable
59 -- SHARED_MEMORY_DIRECTORY. This variable must be set for all
60 -- partitions. If the environment variable is not defined, then the
61 -- current directory is used.
63 -- There is one storage for each variable. The name is the fully
64 -- qualified name of the variable with all letters forced to lower
65 -- case. For example, the variable Var in the shared passive package
66 -- Pkg results in the storage name pkg.var.
68 -- If the storage does not exist, it indicates that no partition has
69 -- assigned a new value, so that the initial value is the correct
70 -- one. This is the critical component of the model. It means that
71 -- there is no system-wide synchronization required for initializing
72 -- the package, since the shared storages need not (and do not)
73 -- reflect the initial state. There is therefore no issue of
74 -- synchronizing initialization and read/write access.
76 -- -----------------------
77 -- -- Read/Write Access --
78 -- -----------------------
80 -- The approach is as follows:
82 -- For each shared variable, var, an instantiation of the below generic
83 -- package is created which provides Read and Write supporting procedures.
85 -- The routine Read in package System.Shared_Storage.Shared_Var_Procs
86 -- ensures to assign variable V to the last written value among processes
87 -- referencing it. A call to this procedure is generated by the expander
88 -- before each read access to the shared variable.
90 -- The routine Write in package System.Shared_Storage.Shared_Var_Proc
91 -- set a new value to the shared variable and, according to the used
92 -- implementation, propagate this value among processes referencing it.
93 -- A call to this procedure is generated by the expander after each
94 -- assignment of the shared variable.
96 -- Note: a special circuit allows the use of stream attributes Read and
97 -- Write for limited types (using the corresponding attribute for the
98 -- full type), but there are limitations on the data that can be placed
99 -- in shared passive partitions. See sem_smem.ads/adb for details.
101 -- ----------------------------------------------------------------
102 -- -- Handling of Protected Objects in Shared Passive Partitions --
103 -- ----------------------------------------------------------------
105 -- In the context of GNAT, during the execution of a protected
106 -- subprogram call, access is locked out using a locking mechanism
107 -- per protected object, as provided by the GNAT.Lock_Files
108 -- capability in the specific case of GNAT. This package contains the
109 -- lock and unlock calls, and the expander generates a call to the
110 -- lock routine before the protected call and a call to the unlock
111 -- routine after the protected call.
113 -- Within the code of the protected subprogram, the access to the
114 -- protected object itself uses the local copy, without any special
115 -- synchronization. Since global access is locked out, no other task
116 -- or partition can attempt to read or write this data as long as the
119 -- The data in the local copy does however need synchronizing with
120 -- the global values in the shared storage. This is achieved as
123 -- The protected object generates a read and assignment routine as
124 -- described for other shared passive variables. The code for the
125 -- 'Read and 'Write attributes (not normally allowed, but allowed
126 -- in this special case) simply reads or writes the values of the
127 -- components in the protected record.
129 -- The lock call is followed by a call to the shared read routine to
130 -- synchronize the local copy to contain the proper global value.
132 -- The unlock call in the procedure case only is preceded by a call
133 -- to the shared assign routine to synchronize the global shared
134 -- storages with the (possibly modified) local copy.
136 -- These calls to the read and assign routines, as well as the lock
137 -- and unlock routines, are inserted by the expander (see exp_smem.adb).
139 package System.Shared_Storage is
141 procedure Shared_Var_Lock (Var : String);
142 -- This procedure claims the shared storage lock. It is used for
143 -- protected types in shared passive packages. A call to this
144 -- locking routine is generated as the first operation in the code
145 -- for the body of a protected subprogram, and it busy waits if
148 procedure Shared_Var_Unlock (Var : String);
149 -- This procedure releases the shared storage lock obtained by a
150 -- prior call to the Shared_Var_Lock procedure, and is to be
151 -- generated as the last operation in the body of a protected
154 -- This generic package is instantiated for each shared passive
155 -- variable. It provides supporting procedures called upon each
156 -- read or write access by the expanded code.
160 type Typ is limited private;
161 -- Shared passive variable type
164 -- Shared passive variable
167 -- Shared passive variable storage name
169 package Shared_Var_Procs is
172 -- Shared passive variable access routine. Each reference to the
173 -- shared variable, V, is preceded by a call to the corresponding
174 -- Read procedure, which either leaves the initial value unchanged
175 -- if the storage does not exist, or reads the current value from
176 -- the shared storage.
179 -- Shared passive variable assignment routine. Each assignment to
180 -- the shared variable, V, is followed by a call to the corresponding
181 -- Write procedure, which writes the new value to the shared storage.
183 end Shared_Var_Procs;
185 end System.Shared_Storage;