Merge from mainline
[official-gcc.git] / gcc / ada / s-shasto.ads
blob77cfa7b64210f7a37e292445eff765cb7bb226bc
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S Y S T E M . S H A R E D _ S T O R A G E --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 1998-2006, Free Software Foundation, Inc. --
10 -- --
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. --
21 -- --
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. --
28 -- --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 -- This package manages the shared/persistant 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
39 -- storage.
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 access routine varR is created whose
83 -- body has the following form (this example is for Pkg.Var):
85 -- procedure varR is
86 -- S : Ada.Streams.Stream_IO.Stream_Access;
87 -- begin
88 -- S := Shared_Var_ROpen ("pkg.var");
89 -- if S /= null then
90 -- typ'Read (S);
91 -- Shared_Var_Close (S);
92 -- end if;
93 -- end varR;
95 -- The routine Shared_Var_ROpen in package System.Shared_Storage
96 -- either returns null if the storage does not exist, or otherwise a
97 -- Stream_Access value that references the corresponding shared
98 -- storage, ready to read the current value.
100 -- Each reference to the shared variable, var, is preceded by a
101 -- call to the corresponding varR procedure, which either leaves the
102 -- initial value unchanged if the storage does not exist, or reads
103 -- the current value from the shared storage.
105 -- In addition, for each shared variable, var, an assignment routine
106 -- is created whose body has the following form (again for Pkg.Var)
108 -- procedure VarA is
109 -- S : Ada.Streams.Stream_IO.Stream_Access;
110 -- begin
111 -- S := Shared_Var_WOpen ("pkg.var");
112 -- typ'Write (S, var);
113 -- Shared_Var_Close (S);
114 -- end VarA;
116 -- The routine Shared_Var_WOpen in package System.Shared_Storage
117 -- returns a Stream_Access value that references the corresponding
118 -- shared storage, ready to write the new value.
120 -- Each assignment to the shared variable, var, is followed by a call
121 -- to the corresponding varA procedure, which writes the new value to
122 -- the shared storage.
124 -- Note that there is no general synchronization for these storage
125 -- read and write operations, since it is assumed that a correctly
126 -- operating programs will provide appropriate synchronization. In
127 -- particular, variables can be protected using protected types with
128 -- no entries.
130 -- The routine Shared_Var_Close is called to indicate the end of a
131 -- read/write operations. This can be useful even in the context of
132 -- the GNAT implementation. For instance, when a read operation and a
133 -- write operation occur at the same time on the same partition, as
134 -- the same stream is used simultaneously, both operations can
135 -- terminate abruptly by raising exception Mode_Error because the
136 -- stream has been opened in read mode and then in write mode and at
137 -- least used by the read opartion. To avoid this unexpected
138 -- behaviour, we introduce a synchronization at the partition level.
140 -- Note: a special circuit allows the use of stream attributes Read and
141 -- Write for limited types (using the corresponding attribute for the
142 -- full type), but there are limitations on the data that can be placed
143 -- in shared passive partitions. See sem_smem.ads/adb for details.
145 -- ----------------------------------------------------------------
146 -- -- Handling of Protected Objects in Shared Passive Partitions --
147 -- ----------------------------------------------------------------
149 -- In the context of GNAT, during the execution of a protected
150 -- subprogram call, access is locked out using a locking mechanism
151 -- per protected object, as provided by the GNAT.Lock_Files
152 -- capability in the specific case of GNAT. This package contains the
153 -- lock and unlock calls, and the expander generates a call to the
154 -- lock routine before the protected call and a call to the unlock
155 -- routine after the protected call.
157 -- Within the code of the protected subprogram, the access to the
158 -- protected object itself uses the local copy, without any special
159 -- synchronization. Since global access is locked out, no other task
160 -- or partition can attempt to read or write this data as long as the
161 -- lock is held.
163 -- The data in the local copy does however need synchronizing with
164 -- the global values in the shared storage. This is achieved as
165 -- follows:
167 -- The protected object generates a read and assignment routine as
168 -- described for other shared passive variables. The code for the
169 -- 'Read and 'Write attributes (not normally allowed, but allowed
170 -- in this special case) simply reads or writes the values of the
171 -- components in the protected record.
173 -- The lock call is followed by a call to the shared read routine to
174 -- synchronize the local copy to contain the proper global value.
176 -- The unlock call in the procedure case only is preceded by a call
177 -- to the shared assign routine to synchronize the global shared
178 -- storages with the (possibly modified) local copy.
180 -- These calls to the read and assign routines, as well as the lock
181 -- and unlock routines, are inserted by the expander (see exp_smem.adb).
183 with Ada.Streams.Stream_IO;
185 package System.Shared_Storage is
187 package SIO renames Ada.Streams.Stream_IO;
189 function Shared_Var_ROpen (Var : String) return SIO.Stream_Access;
190 -- As described above, this routine returns null if the
191 -- corresponding shared storage does not exist, and otherwise, if
192 -- the storage does exist, a Stream_Access value that references
193 -- the shared storage, ready to read the current value.
195 function Shared_Var_WOpen (Var : String) return SIO.Stream_Access;
196 -- As described above, this routine returns a Stream_Access value
197 -- that references the shared storage, ready to write the new
198 -- value. The storage is created by this call if it does not
199 -- already exist.
201 procedure Shared_Var_Close (Var : SIO.Stream_Access);
202 -- This routine signals the end of a read/assign operation. It can
203 -- be useful to embrace a read/write operation between a call to
204 -- open and a call to close which protect the whole operation.
205 -- Otherwise, two simultaneous operations can result in the
206 -- raising of exception Data_Error by setting the access mode of
207 -- the variable in an incorrect mode.
209 procedure Shared_Var_Lock (Var : String);
210 -- This procedure claims the shared storage lock. It is used for
211 -- protected types in shared passive packages. A call to this
212 -- locking routine is generated as the first operation in the code
213 -- for the body of a protected subprogram, and it busy waits if
214 -- the lock is busy.
216 procedure Shared_Var_Unlock (Var : String);
217 -- This procedure releases the shared storage lock obtaind by a
218 -- prior call to the Shared_Mem_Lock procedure, and is to be
219 -- generated as the last operation in the body of a protected
220 -- subprogram.
222 end System.Shared_Storage;