00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file MMAP_Memory_Pool.h 00006 * 00007 * $Id: MMAP_Memory_Pool.h 81589 2008-05-02 13:07:33Z johnnyw $ 00008 * 00009 * @author Dougls C. Schmidt <schmidt@cs.wustl.edu> 00010 * @author Prashant Jain <pjain@cs.wustl.edu> 00011 */ 00012 //============================================================================= 00013 00014 #ifndef ACE_MMAP_MEMORY_POOL_H 00015 #define ACE_MMAP_MEMORY_POOL_H 00016 00017 #include /**/ "ace/pre.h" 00018 00019 #include /**/ "ace/ACE_export.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/ACE.h" 00026 #include "ace/Event_Handler.h" 00027 #include "ace/Sig_Handler.h" 00028 #include "ace/Mem_Map.h" 00029 00030 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00031 00032 /** 00033 * @class ACE_MMAP_Memory_Pool_Options 00034 * 00035 * @brief Helper class for MMAP Memory Pool constructor options. 00036 * 00037 * This should be a nested class, but that breaks too many 00038 * compilers. 00039 */ 00040 class ACE_Export ACE_MMAP_Memory_Pool_Options 00041 { 00042 public: 00043 enum 00044 { 00045 /** 00046 * The base address from the first call to mmap will be used for subsequent 00047 * calls to mmap. 00048 */ 00049 FIRSTCALL_FIXED = 0, 00050 00051 /** 00052 * The base address specified in base_addr will be used in all calls to 00053 * mmap. 00054 */ 00055 ALWAYS_FIXED = 1, 00056 00057 /** 00058 * The base address will be selected by the OS for each call to mmap. 00059 * Caution should be used with this mode since a call that requires the 00060 * backing store to grow may change pointers that are cached by the 00061 * application. 00062 */ 00063 NEVER_FIXED = 2 00064 }; 00065 00066 /// Constructor 00067 ACE_MMAP_Memory_Pool_Options (const void *base_addr = ACE_DEFAULT_BASE_ADDR, 00068 int use_fixed_addr = ALWAYS_FIXED, 00069 bool write_each_page = true, 00070 size_t minimum_bytes = 0, 00071 u_int flags = 0, 00072 bool guess_on_fault = true, 00073 LPSECURITY_ATTRIBUTES sa = 0, 00074 mode_t file_mode = ACE_DEFAULT_FILE_PERMS, 00075 bool unique_ = false, 00076 bool install_signal_handler = true); 00077 00078 /// Base address of the memory-mapped backing store. 00079 const void *base_addr_; 00080 00081 /** 00082 * Determines whether we set @c base_addr_ or if mmap(2) selects it 00083 * FIRSTCALL_FIXED The base address from the first call to mmap 00084 * will be used for subsequent calls to mmap 00085 * ALWAYS_FIXED The base address specified in base_addr will be 00086 * used in all calls to mmap. 00087 * NEVER_FIXED The base address will be selected by the OS for 00088 * each call to mmap. Caution should be used with 00089 * this mode since a call that requires the backing 00090 * store to grow may change pointers that are 00091 * cached by the application. 00092 */ 00093 int use_fixed_addr_; 00094 00095 /// Should each page be written eagerly to avoid surprises later 00096 /// on? 00097 bool write_each_page_; 00098 00099 /// What the minimim bytes of the initial segment should be. 00100 size_t minimum_bytes_; 00101 00102 /// Any special flags that need to be used for @c mmap. 00103 u_int flags_; 00104 00105 /** 00106 * Try to remap without knowing the faulting address. This 00107 * parameter is ignored on platforms that know the faulting address 00108 * (UNIX with SI_ADDR and Win32). 00109 */ 00110 bool guess_on_fault_; 00111 00112 /// Pointer to a security attributes object. Only used on NT. 00113 LPSECURITY_ATTRIBUTES sa_; 00114 00115 /// File mode for mmaped file, if it is created. 00116 mode_t file_mode_; 00117 00118 /// Do we want an unique backing store name? 00119 bool unique_; 00120 00121 /// Should we install a signal handler 00122 bool install_signal_handler_; 00123 00124 private: 00125 // Prevent copying 00126 ACE_MMAP_Memory_Pool_Options (const ACE_MMAP_Memory_Pool_Options &); 00127 ACE_MMAP_Memory_Pool_Options &operator= (const ACE_MMAP_Memory_Pool_Options &); 00128 }; 00129 00130 /** 00131 * @class ACE_MMAP_Memory_Pool 00132 * 00133 * @brief Make a memory pool that is based on @c mmap(2). This 00134 * implementation allows memory to be shared between processes. 00135 */ 00136 class ACE_Export ACE_MMAP_Memory_Pool : public ACE_Event_Handler 00137 { 00138 public: 00139 typedef ACE_MMAP_Memory_Pool_Options OPTIONS; 00140 00141 // = Initialization and termination methods. 00142 00143 /// Initialize the pool. 00144 ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, 00145 const OPTIONS *options = 0); 00146 00147 /// Destructor. 00148 virtual ~ACE_MMAP_Memory_Pool (void); 00149 00150 /// Ask system for initial chunk of shared memory. 00151 virtual void *init_acquire (size_t nbytes, 00152 size_t &rounded_bytes, 00153 int &first_time); 00154 00155 /** 00156 * Acquire at least @a nbytes from the memory pool. @a rounded_bytes 00157 * is the actual number of bytes allocated. Also acquires an 00158 * internal semaphore that ensures proper serialization of 00159 * ACE_MMAP_Memory_Pool initialization across processes. 00160 */ 00161 virtual void *acquire (size_t nbytes, 00162 size_t &rounded_bytes); 00163 00164 /// Instruct the memory pool to release all of its resources. 00165 virtual int release (int destroy = 1); 00166 00167 /// Sync the memory region to the backing store starting at 00168 /// @c this->base_addr_. 00169 virtual int sync (size_t len, int flags = MS_SYNC); 00170 00171 /// Sync the memory region to the backing store starting at 00172 /// @c this->base_addr_. Will sync as much as the backing file 00173 /// allows. 00174 virtual int sync (int flags = MS_SYNC); 00175 00176 /// Sync the memory region to the backing store starting at @a addr. 00177 virtual int sync (void *addr, size_t len, int flags = MS_SYNC); 00178 00179 /** 00180 * Change the protection of the pages of the mapped region to @a prot 00181 * starting at @c this->base_addr_ up to @a len bytes. If @a len == -1 00182 * then change protection of all pages in the mapped region. 00183 */ 00184 virtual int protect (size_t len, int prot = PROT_RDWR); 00185 00186 /** 00187 * Change the protection of all the pages of the mapped region to @a prot 00188 * starting at @c this->base_addr_. 00189 */ 00190 virtual int protect (int prot = PROT_RDWR); 00191 00192 /// Change the protection of the pages of the mapped region to @a prot 00193 /// starting at @a addr up to @a len bytes. 00194 virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); 00195 00196 #if defined (ACE_WIN32) 00197 /** 00198 * Win32 Structural exception selector. The return value decides 00199 * how to handle memory pool related structural exceptions. Returns 00200 * 1, 0, or , -1. 00201 */ 00202 virtual int seh_selector (void *); 00203 #endif /* ACE_WIN32 */ 00204 00205 /** 00206 * Try to extend the virtual address space so that @a addr is now 00207 * covered by the address mapping. The method succeeds and returns 00208 * 0 if the backing store has adequate memory to cover this address. 00209 * Otherwise, it returns -1. This method is typically called by a 00210 * UNIX signal handler for SIGSEGV or a Win32 structured exception 00211 * when another process has grown the backing store (and its 00212 * mapping) and our process now incurs a fault because our mapping 00213 * isn't in range (yet). 00214 */ 00215 virtual int remap (void *addr); 00216 00217 /// Return the base address of this memory pool. 00218 virtual void *base_addr (void) const; 00219 00220 /// Dump the state of an object. 00221 virtual void dump (void) const; 00222 00223 /// Get reference to underlying ACE_Mem_Map object. 00224 ACE_Mem_Map const & mmap (void) const; 00225 00226 /// Get reference to underlying ACE_Mem_Map object. 00227 ACE_Mem_Map & mmap (void); 00228 00229 /// Declare the dynamic allocation hooks. 00230 ACE_ALLOC_HOOK_DECLARE; 00231 00232 protected: 00233 /// Implement the algorithm for rounding up the request to an 00234 /// appropriate chunksize. 00235 virtual size_t round_up (size_t nbytes); 00236 00237 /// Compute the new @a map_size of the backing store and commit the 00238 /// memory. 00239 virtual int commit_backing_store_name (size_t rounded_bytes, 00240 size_t & map_size); 00241 00242 /// Memory map the file up to @a map_size bytes. 00243 virtual int map_file (size_t map_size); 00244 00245 #if !defined (ACE_WIN32) 00246 /** 00247 * Handle SIGSEGV and SIGBUS signals to remap memory properly. When a 00248 * process reads or writes to non-mapped memory a signal (SIGBUS or 00249 * SIGSEGV) will be triggered. At that point, the ACE_Sig_Handler 00250 * (which is part of the ACE_Reactor) will catch the signal and 00251 * dispatch the handle_signal() method defined here. If the SIGSEGV 00252 * signal occurred due to the fact that the mapping wasn't uptodate 00253 * with respect to the backing store, the handler method below will 00254 * update the mapping accordingly. When the signal handler returns, 00255 * the instruction should be restarted and the operation should work. 00256 */ 00257 virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); 00258 #endif 00259 00260 #if !defined (ACE_WIN32) 00261 /// Handles SIGSEGV. 00262 ACE_Sig_Handler signal_handler_; 00263 #endif 00264 00265 /// Memory-mapping object. 00266 ACE_Mem_Map mmap_; 00267 00268 /** 00269 * Base of mapped region. If this has the value of 0 then the OS is 00270 * free to select any address to map the file, otherwise this value 00271 * is what the OS must try to use to mmap the file. 00272 */ 00273 void *base_addr_; 00274 00275 /// Must we use the @c base_addr_ or can we let mmap(2) select it? 00276 int use_fixed_addr_; 00277 00278 /// Flags passed into ACE_OS::mmap(). 00279 int flags_; 00280 00281 /// Should we write a byte to each page to forceably allocate memory 00282 /// for this backing store? 00283 bool write_each_page_; 00284 00285 /// What the minimum bytes of the initial segment should be. 00286 size_t minimum_bytes_; 00287 00288 /// Name of the backing store where the shared memory pool is kept. 00289 ACE_TCHAR backing_store_name_[MAXPATHLEN + 1]; 00290 00291 /** 00292 * Try to remap without knowing the faulting address. This 00293 * parameter is ignored on platforms that know the faulting address 00294 * (UNIX with SI_ADDR and Win32). 00295 */ 00296 bool guess_on_fault_; 00297 00298 /// Security attributes object, only used on NT. 00299 LPSECURITY_ATTRIBUTES sa_; 00300 00301 /// Protection mode for mmaped file. 00302 mode_t file_mode_; 00303 00304 /// Should we install a signal handler 00305 bool install_signal_handler_; 00306 }; 00307 00308 /** 00309 * @class ACE_Lite_MMAP_Memory_Pool 00310 * 00311 * @brief Make a ``lighter-weight'' memory pool based ACE_Mem_Map. 00312 * 00313 * This implementation allows memory to be shared between 00314 * processes. However, unlike the ACE_MMAP_Memory_Pool 00315 * the @c sync methods are no-ops, which means that we don't pay 00316 * for the price of flushing the memory to the backing store on 00317 * every update. Naturally, this trades off increased 00318 * performance for less reliability if the machine crashes. 00319 */ 00320 class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool 00321 { 00322 public: 00323 /// Initialize the pool. 00324 ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, 00325 const OPTIONS *options = 0); 00326 00327 /// Destructor. 00328 virtual ~ACE_Lite_MMAP_Memory_Pool (void); 00329 00330 /// Overwrite the default sync behavior with no-op 00331 virtual int sync (size_t len, int flags = MS_SYNC); 00332 00333 /// Overwrite the default sync behavior with no-op 00334 virtual int sync (int flags = MS_SYNC); 00335 00336 /// Overwrite the default sync behavior with no-op 00337 virtual int sync (void *addr, size_t len, int flags = MS_SYNC); 00338 }; 00339 00340 ACE_END_VERSIONED_NAMESPACE_DECL 00341 00342 #if defined (__ACE_INLINE__) 00343 #include "ace/MMAP_Memory_Pool.inl" 00344 #endif /* __ACE_INLINE__ */ 00345 00346 #include /**/ "ace/post.h" 00347 #endif /* ACE_MMAP_MEMORY_POOL_H */