OSDN Git Service

* 1aexcept.adb, 1aexcept.ads, 1ic.ads, 1ssecsta.adb,
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-shasto.ads
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-2001 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,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, 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 ------------------------------------------------------------------------------
33
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
39 --  storage.
40
41 --  --------------------------
42 --  -- Shared Storage Model --
43 --  --------------------------
44
45 --  The basic model used is that each partition that references the
46 --  Shared_Passive package has a local copy of the package data that
47 --  is initialized in accordance with the declarations of the package
48 --  in the normal manner. The routines in System.Shared_Storage are
49 --  then used to ensure that the values in these separate copies are
50 --  properly synchronized with the state of the overall system.
51
52 --  In the GNAT implementation, this synchronization is ensured by
53 --  maintaining a set of files, in a designated directory. The
54 --  directory is designated by setting the environment variable
55 --  SHARED_MEMORY_DIRECTORY. This variable must be set for all
56 --  partitions. If the environment variable is not defined, then the
57 --  current directory is used.
58
59 --  There is one storage for each variable. The name is the fully
60 --  qualified name of the variable with all letters forced to lower
61 --  case. For example, the variable Var in the shared passive package
62 --  Pkg results in the storage name pkg.var.
63
64 --  If the storage does not exist, it indicates that no partition has
65 --  assigned a new value, so that the initial value is the correct
66 --  one. This is the critical component of the model. It means that
67 --  there is no system-wide synchronization required for initializing
68 --  the package, since the shared storages need not (and do not)
69 --  reflect the initial state. There is therefore no issue of
70 --  synchronizing initialization and read/write access.
71
72 --  -----------------------
73 --  -- Read/Write Access --
74 --  -----------------------
75
76 --  The approach is as follows:
77
78 --    For each shared variable, var, an access routine varR is created whose
79 --    body has the following form (this example is for Pkg.Var):
80
81 --      procedure varR is
82 --         S : Ada.Streams.Stream_IO.Stream_Access;
83 --      begin
84 --         S := Shared_Var_ROpen ("pkg.var");
85 --         if S /= null then
86 --            typ'Read (S);
87 --            Shared_Var_Close (S);
88 --         end if;
89 --      end varR;
90
91 --    The routine Shared_Var_ROpen in package System.Shared_Storage
92 --    either returns null if the storage does not exist, or otherwise a
93 --    Stream_Access value that references the corresponding shared
94 --    storage, ready to read the current value.
95
96 --    Each reference to the shared variable, var, is preceded by a
97 --    call to the corresponding varR procedure, which either leaves the
98 --    initial value unchanged if the storage does not exist, or reads
99 --    the current value from the shared storage.
100
101 --    In addition, for each shared variable, var, an assignment routine
102 --    is created whose body has the following form (again for Pkg.Var)
103
104 --      procedure VarA is
105 --         S : Ada.Streams.Stream_IO.Stream_Access;
106 --      begin
107 --         S := Shared_Var_WOpen ("pkg.var");
108 --         typ'Write (S, var);
109 --         Shared_Var_Close (S);
110 --      end VarA;
111
112 --    The routine Shared_Var_WOpen in package System.Shared_Storage
113 --    returns a Stream_Access value that references the corresponding
114 --    shared storage, ready to write the new value.
115
116 --    Each assignment to the shared variable, var, is followed by a call
117 --    to the corresponding varA procedure, which writes the new value to
118 --    the shared storage.
119
120 --    Note that there is no general synchronization for these storage
121 --    read and write operations, since it is assumed that a correctly
122 --    operating programs will provide appropriate synchronization. In
123 --    particular, variables can be protected using protected types with
124 --    no entries.
125
126 --    The routine Shared_Var_Close is called to indicate the end of a
127 --    read/write operations. This can be useful even in the context of
128 --    the GNAT implementation. For instance, when a read operation and a
129 --    write operation occur at the same time on the same partition, as
130 --    the same stream is used simultaneously, both operations can
131 --    terminate abruptly by raising exception Mode_Error because the
132 --    stream has been opened in read mode and then in write mode and at
133 --    least used by the read opartion. To avoid this unexpected
134 --    behaviour, we introduce a synchronization at the partition level.
135
136 --  Note: a special circuit allows the use of stream attributes Read and
137 --  Write for limited types (using the corresponding attribute for the
138 --  full type), but there are limitations on the data that can be placed
139 --  in shared passive partitions. See sem_smem.ads/adb for details.
140
141 --  ----------------------------------------------------------------
142 --  -- Handling of Protected Objects in Shared Passive Partitions --
143 --  ----------------------------------------------------------------
144
145 --  In the context of GNAT, during the execution of a protected
146 --  subprogram call, access is locked out using a locking mechanism
147 --  per protected object, as provided by the GNAT.Lock_Files
148 --  capability in the specific case of GNAT. This package contains the
149 --  lock and unlock calls, and the expander generates a call to the
150 --  lock routine before the protected call and a call to the unlock
151 --  routine after the protected call.
152
153 --  Within the code of the protected subprogram, the access to the
154 --  protected object itself uses the local copy, without any special
155 --  synchronization.  Since global access is locked out, no other task
156 --  or partition can attempt to read or write this data as long as the
157 --  lock is held.
158
159 --  The data in the local copy does however need synchronizing with
160 --  the global values in the shared storage. This is achieved as
161 --  follows:
162
163 --    The protected object generates a read and assignment routine as
164 --    described for other shared passive variables. The code for the
165 --    'Read and 'Write attributes (not normally allowed, but allowed
166 --    in this special case) simply reads or writes the values of the
167 --    components in the protected record.
168
169 --    The lock call is followed by a call to the shared read routine to
170 --    synchronize the local copy to contain the proper global value.
171
172 --    The unlock call in the procedure case only is preceded by a call
173 --    to the shared assign routine to synchronize the global shared
174 --    storages with the (possibly modified) local copy.
175
176 --    These calls to the read and assign routines, as well as the lock
177 --    and unlock routines, are inserted by the expander (see exp_smem.adb).
178
179 with Ada.Streams.Stream_IO;
180
181 package System.Shared_Storage is
182
183    package SIO renames Ada.Streams.Stream_IO;
184
185    function Shared_Var_ROpen (Var : String) return SIO.Stream_Access;
186    --  As described above, this routine returns null if the
187    --  corresponding shared storage does not exist, and otherwise, if
188    --  the storage does exist, a Stream_Access value that references
189    --  the shared storage, ready to read the current value.
190
191    function Shared_Var_WOpen (Var : String) return SIO.Stream_Access;
192    --  As described above, this routine returns a Stream_Access value
193    --  that references the shared storage, ready to write the new
194    --  value. The storage is created by this call if it does not
195    --  already exist.
196
197    procedure Shared_Var_Close (Var : in SIO.Stream_Access);
198    --  This routine signals the end of a read/assign operation. It can
199    --  be useful to embrace a read/write operation between a call to
200    --  open and a call to close which protect the whole operation.
201    --  Otherwise, two simultaneous operations can result in the
202    --  raising of exception Data_Error by setting the access mode of
203    --  the variable in an incorrect mode.
204
205    procedure Shared_Var_Lock (Var : String);
206    --  This procedure claims the shared storage lock. It is used for
207    --  protected types in shared passive packages. A call to this
208    --  locking routine is generated as the first operation in the code
209    --  for the body of a protected subprogram, and it busy waits if
210    --  the lock is busy.
211
212    procedure Shared_Var_Unlock (Var : String);
213    --  This procedure releases the shared storage lock obtaind by a
214    --  prior call to the Shared_Mem_Lock procedure, and is to be
215    --  generated as the last operation in the body of a protected
216    --  subprogram.
217
218 end System.Shared_Storage;