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