diff options
Diffstat (limited to 'gcc/ada/s-shasto.ads')
-rw-r--r-- | gcc/ada/s-shasto.ads | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/gcc/ada/s-shasto.ads b/gcc/ada/s-shasto.ads new file mode 100644 index 00000000000..d1b5e819edc --- /dev/null +++ b/gcc/ada/s-shasto.ads @@ -0,0 +1,220 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT COMPILER COMPONENTS -- +-- -- +-- S Y S T E M . S H A R E D _ S T O R A G E -- +-- -- +-- S p e c -- +-- -- +-- $Revision: 1.5 $ -- +-- -- +-- Copyright (C) 1998-2001 Free Software Foundation, Inc. -- +-- -- +-- GNAT is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 2, or (at your option) any later ver- -- +-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- +-- for more details. You should have received a copy of the GNU General -- +-- Public License distributed with GNAT; see file COPYING. If not, write -- +-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, -- +-- MA 02111-1307, USA. -- +-- -- +-- As a special exception, if other files instantiate generics from this -- +-- unit, or you link this unit with other files to produce an executable, -- +-- this unit does not by itself cause the resulting executable to be -- +-- covered by the GNU General Public License. This exception does not -- +-- however invalidate any other reasons why the executable file might be -- +-- covered by the GNU Public License. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). -- +-- -- +------------------------------------------------------------------------------ + +-- This package manages the shared/persistant storage required for +-- full implementation of variables in Shared_Passive packages, more +-- precisely variables whose enclosing dynamic scope is a shared +-- passive package. This implementation is specific to GNAT and GLADE +-- provides a more general implementation not dedicated to file +-- storage. + +-- -------------------------- +-- -- Shared Storage Model -- +-- -------------------------- + +-- The basic model used is that each partition that references the +-- Shared_Passive package has a local copy of the package data that +-- is initialized in accordance with the declarations of the package +-- in the normal manner. The routines in System.Shared_Storage are +-- then used to ensure that the values in these separate copies are +-- properly synchronized with the state of the overall system. + +-- In the GNAT implementation, this synchronization is ensured by +-- maintaining a set of files, in a designated directory. The +-- directory is designated by setting the environment variable +-- SHARED_MEMORY_DIRECTORY. This variable must be set for all +-- partitions. If the environment variable is not defined, then the +-- current directory is used. + +-- There is one storage for each variable. The name is the fully +-- qualified name of the variable with all letters forced to lower +-- case. For example, the variable Var in the shared passive package +-- Pkg results in the storage name pkg.var. + +-- If the storage does not exist, it indicates that no partition has +-- assigned a new value, so that the initial value is the correct +-- one. This is the critical component of the model. It means that +-- there is no system-wide synchronization required for initializing +-- the package, since the shared storages need not (and do not) +-- reflect the initial state. There is therefore no issue of +-- synchronizing initialization and read/write access. + +-- ----------------------- +-- -- Read/Write Access -- +-- ----------------------- + +-- The approach is as follows: + +-- For each shared variable, var, an access routine varR is created whose +-- body has the following form (this example is for Pkg.Var): + +-- procedure varR is +-- S : Ada.Streams.Stream_IO.Stream_Access; +-- begin +-- S := Shared_Var_ROpen ("pkg.var"); +-- if S /= null then +-- typ'Read (S); +-- Shared_Var_Close (S); +-- end if; +-- end varR; + +-- The routine Shared_Var_ROpen in package System.Shared_Storage +-- either returns null if the storage does not exist, or otherwise a +-- Stream_Access value that references the corresponding shared +-- storage, ready to read the current value. + +-- Each reference to the shared variable, var, is preceded by a +-- call to the corresponding varR procedure, which either leaves the +-- initial value unchanged if the storage does not exist, or reads +-- the current value from the shared storage. + +-- In addition, for each shared variable, var, an assignment routine +-- is created whose body has the following form (again for Pkg.Var) + +-- procedure VarA is +-- S : Ada.Streams.Stream_IO.Stream_Access; +-- begin +-- S := Shared_Var_WOpen ("pkg.var"); +-- typ'Write (S, var); +-- Shared_Var_Close (S); +-- end VarA; + +-- The routine Shared_Var_WOpen in package System.Shared_Storage +-- returns a Stream_Access value that references the corresponding +-- shared storage, ready to write the new value. + +-- Each assignment to the shared variable, var, is followed by a call +-- to the corresponding varA procedure, which writes the new value to +-- the shared storage. + +-- Note that there is no general synchronization for these storage +-- read and write operations, since it is assumed that a correctly +-- operating programs will provide appropriate synchronization. In +-- particular, variables can be protected using protected types with +-- no entries. + +-- The routine Shared_Var_Close is called to indicate the end of a +-- read/write operations. This can be useful even in the context of +-- the GNAT implementation. For instance, when a read operation and a +-- write operation occur at the same time on the same partition, as +-- the same stream is used simultaneously, both operations can +-- terminate abruptly by raising exception Mode_Error because the +-- stream has been opened in read mode and then in write mode and at +-- least used by the read opartion. To avoid this unexpected +-- behaviour, we introduce a synchronization at the partition level. + +-- Note: a special circuit allows the use of stream attributes Read and +-- Write for limited types (using the corresponding attribute for the +-- full type), but there are limitations on the data that can be placed +-- in shared passive partitions. See sem_smem.ads/adb for details. + +-- ---------------------------------------------------------------- +-- -- Handling of Protected Objects in Shared Passive Partitions -- +-- ---------------------------------------------------------------- + +-- In the context of GNAT, during the execution of a protected +-- subprogram call, access is locked out using a locking mechanism +-- per protected object, as provided by the GNAT.Lock_Files +-- capability in the specific case of GNAT. This package contains the +-- lock and unlock calls, and the expander generates a call to the +-- lock routine before the protected call and a call to the unlock +-- routine after the protected call. + +-- Within the code of the protected subprogram, the access to the +-- protected object itself uses the local copy, without any special +-- synchronization. Since global access is locked out, no other task +-- or partition can attempt to read or write this data as long as the +-- lock is held. + +-- The data in the local copy does however need synchronizing with +-- the global values in the shared storage. This is achieved as +-- follows: + +-- The protected object generates a read and assignment routine as +-- described for other shared passive variables. The code for the +-- 'Read and 'Write attributes (not normally allowed, but allowed +-- in this special case) simply reads or writes the values of the +-- components in the protected record. + +-- The lock call is followed by a call to the shared read routine to +-- synchronize the local copy to contain the proper global value. + +-- The unlock call in the procedure case only is preceded by a call +-- to the shared assign routine to synchronize the global shared +-- storages with the (possibly modified) local copy. + +-- These calls to the read and assign routines, as well as the lock +-- and unlock routines, are inserted by the expander (see exp_smem.adb). + +with Ada.Streams.Stream_IO; + +package System.Shared_Storage is + + package SIO renames Ada.Streams.Stream_IO; + + function Shared_Var_ROpen (Var : String) return SIO.Stream_Access; + -- As described above, this routine returns null if the + -- corresponding shared storage does not exist, and otherwise, if + -- the storage does exist, a Stream_Access value that references + -- the shared storage, ready to read the current value. + + function Shared_Var_WOpen (Var : String) return SIO.Stream_Access; + -- As described above, this routine returns a Stream_Access value + -- that references the shared storage, ready to write the new + -- value. The storage is created by this call if it does not + -- already exist. + + procedure Shared_Var_Close (Var : in SIO.Stream_Access); + -- This routine signals the end of a read/assign operation. It can + -- be useful to embrace a read/write operation between a call to + -- open and a call to close which protect the whole operation. + -- Otherwise, two simultaneous operations can result in the + -- raising of exception Data_Error by setting the access mode of + -- the variable in an incorrect mode. + + procedure Shared_Var_Lock (Var : String); + -- This procedure claims the shared storage lock. It is used for + -- protected types in shared passive packages. A call to this + -- locking routine is generated as the first operation in the code + -- for the body of a protected subprogram, and it busy waits if + -- the lock is busy. + + procedure Shared_Var_Unlock (Var : String); + -- This procedure releases the shared storage lock obtaind by a + -- prior call to the Shared_Mem_Lock procedure, and is to be + -- generated as the last operation in the body of a protected + -- subprogram. + +end System.Shared_Storage; |