FSF GCC merge 02/23/03
[official-gcc.git] / gcc / ada / s-shasto.ads
blobc93dea0c3ccf17517188fecf79dd964cd4d99636
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 -- --
10 -- Copyright (C) 1998-2001 Free Software Foundation, Inc. --
11 -- --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
22 -- --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
29 -- --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
32 -- --
33 ------------------------------------------------------------------------------
35 -- This package manages the shared/persistent storage required for
36 -- full implementation of variables in Shared_Passive packages, more
37 -- precisely variables whose enclosing dynamic scope is a shared
38 -- passive package. This implementation is specific to GNAT and GLADE
39 -- provides a more general implementation not dedicated to file
40 -- storage.
42 -- --------------------------
43 -- -- Shared Storage Model --
44 -- --------------------------
46 -- The basic model used is that each partition that references the
47 -- Shared_Passive package has a local copy of the package data that
48 -- is initialized in accordance with the declarations of the package
49 -- in the normal manner. The routines in System.Shared_Storage are
50 -- then used to ensure that the values in these separate copies are
51 -- properly synchronized with the state of the overall system.
53 -- In the GNAT implementation, this synchronization is ensured by
54 -- maintaining a set of files, in a designated directory. The
55 -- directory is designated by setting the environment variable
56 -- SHARED_MEMORY_DIRECTORY. This variable must be set for all
57 -- partitions. If the environment variable is not defined, then the
58 -- current directory is used.
60 -- There is one storage for each variable. The name is the fully
61 -- qualified name of the variable with all letters forced to lower
62 -- case. For example, the variable Var in the shared passive package
63 -- Pkg results in the storage name pkg.var.
65 -- If the storage does not exist, it indicates that no partition has
66 -- assigned a new value, so that the initial value is the correct
67 -- one. This is the critical component of the model. It means that
68 -- there is no system-wide synchronization required for initializing
69 -- the package, since the shared storages need not (and do not)
70 -- reflect the initial state. There is therefore no issue of
71 -- synchronizing initialization and read/write access.
73 -- -----------------------
74 -- -- Read/Write Access --
75 -- -----------------------
77 -- The approach is as follows:
79 -- For each shared variable, var, an access routine varR is created whose
80 -- body has the following form (this example is for Pkg.Var):
82 -- procedure varR is
83 -- S : Ada.Streams.Stream_IO.Stream_Access;
84 -- begin
85 -- S := Shared_Var_ROpen ("pkg.var");
86 -- if S /= null then
87 -- typ'Read (S);
88 -- Shared_Var_Close (S);
89 -- end if;
90 -- end varR;
92 -- The routine Shared_Var_ROpen in package System.Shared_Storage
93 -- either returns null if the storage does not exist, or otherwise a
94 -- Stream_Access value that references the corresponding shared
95 -- storage, ready to read the current value.
97 -- Each reference to the shared variable, var, is preceded by a
98 -- call to the corresponding varR procedure, which either leaves the
99 -- initial value unchanged if the storage does not exist, or reads
100 -- the current value from the shared storage.
102 -- In addition, for each shared variable, var, an assignment routine
103 -- is created whose body has the following form (again for Pkg.Var)
105 -- procedure VarA is
106 -- S : Ada.Streams.Stream_IO.Stream_Access;
107 -- begin
108 -- S := Shared_Var_WOpen ("pkg.var");
109 -- typ'Write (S, var);
110 -- Shared_Var_Close (S);
111 -- end VarA;
113 -- The routine Shared_Var_WOpen in package System.Shared_Storage
114 -- returns a Stream_Access value that references the corresponding
115 -- shared storage, ready to write the new value.
117 -- Each assignment to the shared variable, var, is followed by a call
118 -- to the corresponding varA procedure, which writes the new value to
119 -- the shared storage.
121 -- Note that there is no general synchronization for these storage
122 -- read and write operations, since it is assumed that a correctly
123 -- operating programs will provide appropriate synchronization. In
124 -- particular, variables can be protected using protected types with
125 -- no entries.
127 -- The routine Shared_Var_Close is called to indicate the end of a
128 -- read/write operations. This can be useful even in the context of
129 -- the GNAT implementation. For instance, when a read operation and a
130 -- write operation occur at the same time on the same partition, as
131 -- the same stream is used simultaneously, both operations can
132 -- terminate abruptly by raising exception Mode_Error because the
133 -- stream has been opened in read mode and then in write mode and at
134 -- least used by the read opartion. To avoid this unexpected
135 -- behaviour, we introduce a synchronization at the partition level.
137 -- Note: a special circuit allows the use of stream attributes Read and
138 -- Write for limited types (using the corresponding attribute for the
139 -- full type), but there are limitations on the data that can be placed
140 -- in shared passive partitions. See sem_smem.ads/adb for details.
142 -- ----------------------------------------------------------------
143 -- -- Handling of Protected Objects in Shared Passive Partitions --
144 -- ----------------------------------------------------------------
146 -- In the context of GNAT, during the execution of a protected
147 -- subprogram call, access is locked out using a locking mechanism
148 -- per protected object, as provided by the GNAT.Lock_Files
149 -- capability in the specific case of GNAT. This package contains the
150 -- lock and unlock calls, and the expander generates a call to the
151 -- lock routine before the protected call and a call to the unlock
152 -- routine after the protected call.
154 -- Within the code of the protected subprogram, the access to the
155 -- protected object itself uses the local copy, without any special
156 -- synchronization. Since global access is locked out, no other task
157 -- or partition can attempt to read or write this data as long as the
158 -- lock is held.
160 -- The data in the local copy does however need synchronizing with
161 -- the global values in the shared storage. This is achieved as
162 -- follows:
164 -- The protected object generates a read and assignment routine as
165 -- described for other shared passive variables. The code for the
166 -- 'Read and 'Write attributes (not normally allowed, but allowed
167 -- in this special case) simply reads or writes the values of the
168 -- components in the protected record.
170 -- The lock call is followed by a call to the shared read routine to
171 -- synchronize the local copy to contain the proper global value.
173 -- The unlock call in the procedure case only is preceded by a call
174 -- to the shared assign routine to synchronize the global shared
175 -- storages with the (possibly modified) local copy.
177 -- These calls to the read and assign routines, as well as the lock
178 -- and unlock routines, are inserted by the expander (see exp_smem.adb).
180 with Ada.Streams.Stream_IO;
182 package System.Shared_Storage is
184 package SIO renames Ada.Streams.Stream_IO;
186 function Shared_Var_ROpen (Var : String) return SIO.Stream_Access;
187 -- As described above, this routine returns null if the
188 -- corresponding shared storage does not exist, and otherwise, if
189 -- the storage does exist, a Stream_Access value that references
190 -- the shared storage, ready to read the current value.
192 function Shared_Var_WOpen (Var : String) return SIO.Stream_Access;
193 -- As described above, this routine returns a Stream_Access value
194 -- that references the shared storage, ready to write the new
195 -- value. The storage is created by this call if it does not
196 -- already exist.
198 procedure Shared_Var_Close (Var : in SIO.Stream_Access);
199 -- This routine signals the end of a read/assign operation. It can
200 -- be useful to embrace a read/write operation between a call to
201 -- open and a call to close which protect the whole operation.
202 -- Otherwise, two simultaneous operations can result in the
203 -- raising of exception Data_Error by setting the access mode of
204 -- the variable in an incorrect mode.
206 procedure Shared_Var_Lock (Var : String);
207 -- This procedure claims the shared storage lock. It is used for
208 -- protected types in shared passive packages. A call to this
209 -- locking routine is generated as the first operation in the code
210 -- for the body of a protected subprogram, and it busy waits if
211 -- the lock is busy.
213 procedure Shared_Var_Unlock (Var : String);
214 -- This procedure releases the shared storage lock obtaind by a
215 -- prior call to the Shared_Mem_Lock procedure, and is to be
216 -- generated as the last operation in the body of a protected
217 -- subprogram.
219 end System.Shared_Storage;