MMAP_Memory_Pool.h

Go to the documentation of this file.
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 */

Generated on Tue Feb 2 17:18:40 2010 for ACE by  doxygen 1.4.7