diff options
Diffstat (limited to 'ACE/ace/MMAP_Memory_Pool.h')
-rw-r--r-- | ACE/ace/MMAP_Memory_Pool.h | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/ACE/ace/MMAP_Memory_Pool.h b/ACE/ace/MMAP_Memory_Pool.h new file mode 100644 index 00000000000..2670ef9c190 --- /dev/null +++ b/ACE/ace/MMAP_Memory_Pool.h @@ -0,0 +1,313 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file MMAP_Memory_Pool.h + * + * $Id$ + * + * @author Dougls C. Schmidt <schmidt@cs.wustl.edu> + * @author Prashant Jain <pjain@cs.wustl.edu> + */ +//============================================================================= + +#ifndef ACE_MMAP_MEMORY_POOL_H +#define ACE_MMAP_MEMORY_POOL_H + +#include /**/ "ace/pre.h" + +#include "ace/ACE_export.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/ACE.h" +#include "ace/Event_Handler.h" +#include "ace/Sig_Handler.h" +#include "ace/Mem_Map.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL + +/** + * @class ACE_MMAP_Memory_Pool_Options + * + * @brief Helper class for MMAP Memory Pool constructor options. + * + * This should be a nested class, but that breaks too many + * compilers. + */ +class ACE_Export ACE_MMAP_Memory_Pool_Options +{ +public: + enum + { + /** + * The base address from the first call to mmap will be used for subsequent + * calls to mmap. + */ + FIRSTCALL_FIXED = 0, + + /** + * The base address specified in base_addr will be used in all calls to + * mmap. + */ + ALWAYS_FIXED = 1, + + /** + * The base address will be selected by the OS for each call to mmap. + * Caution should be used with this mode since a call that requires the + * backing store to grow may change pointers that are cached by the + * application. + */ + NEVER_FIXED = 2 + }; + + // = Initialization method. + ACE_MMAP_Memory_Pool_Options (const void *base_addr = ACE_DEFAULT_BASE_ADDR, + int use_fixed_addr = ALWAYS_FIXED, + int write_each_page = 1, + ACE_LOFF_T minimum_bytes = 0, + u_int flags = 0, + int guess_on_fault = 1, + LPSECURITY_ATTRIBUTES sa = 0, + mode_t file_mode = ACE_DEFAULT_FILE_PERMS, + bool unique_ = false); + + /// Base address of the memory-mapped backing store. + const void *base_addr_; + + /** + * Determines whether we set @c base_addr_ or if mmap(2) selects it + * FIRSTCALL_FIXED The base address from the first call to mmap + * will be used for subsequent calls to mmap + * ALWAYS_FIXED The base address specified in base_addr will be + * used in all calls to mmap. + * NEVER_FIXED The base address will be selected by the OS for + * each call to mmap. Caution should be used with + * this mode since a call that requires the backing + * store to grow may change pointers that are + * cached by the application. + */ + int use_fixed_addr_; + + /// Should each page be written eagerly to avoid surprises later + /// on? + int write_each_page_; + + /// What the minimim bytes of the initial segment should be. + ACE_LOFF_T minimum_bytes_; + + /// Any special flags that need to be used for @c mmap. + u_int flags_; + + /** + * Try to remap without knowing the faulting address. This + * parameter is ignored on platforms that know the faulting address + * (UNIX with SI_ADDR and Win32). + */ + bool guess_on_fault_; + + /// Pointer to a security attributes object. Only used on NT. + LPSECURITY_ATTRIBUTES sa_; + + /// File mode for mmaped file, if it is created. + mode_t file_mode_; + + /// Do we want an unique backing store name? + bool unique_; + +private: + // Prevent copying + ACE_MMAP_Memory_Pool_Options (const ACE_MMAP_Memory_Pool_Options &); + ACE_MMAP_Memory_Pool_Options &operator= (const ACE_MMAP_Memory_Pool_Options &); +}; + +/** + * @class ACE_MMAP_Memory_Pool + * + * @brief Make a memory pool that is based on @c mmap(2). This + * implementation allows memory to be shared between processes. + */ +class ACE_Export ACE_MMAP_Memory_Pool : public ACE_Event_Handler +{ +public: + typedef ACE_MMAP_Memory_Pool_Options OPTIONS; + + // = Initialization and termination methods. + + /// Initialize the pool. + ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, + const OPTIONS *options = 0); + + /// Destructor. + virtual ~ACE_MMAP_Memory_Pool (void); + + /// Ask system for initial chunk of shared memory. + virtual void *init_acquire (size_t nbytes, + size_t &rounded_bytes, + int &first_time); + + /** + * Acquire at least @a nbytes from the memory pool. @a rounded_bytes + * is the actual number of bytes allocated. Also acquires an + * internal semaphore that ensures proper serialization of + * ACE_MMAP_Memory_Pool initialization across processes. + */ + virtual void *acquire (size_t nbytes, + size_t &rounded_bytes); + + /// Instruct the memory pool to release all of its resources. + virtual int release (int destroy = 1); + + /// Sync the memory region to the backing store starting at + /// @c this->base_addr_. + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + + /// Sync the memory region to the backing store starting at @a addr. + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); + + /** + * Change the protection of the pages of the mapped region to <prot> + * starting at <this->base_addr_> up to <len> bytes. If <len> == -1 + * then change protection of all pages in the mapped region. + */ + virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); + + /// Change the protection of the pages of the mapped region to @a prot + /// starting at @a addr up to @a len bytes. + virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); + +#if defined (ACE_WIN32) + /** + * Win32 Structural exception selector. The return value decides + * how to handle memory pool related structural exceptions. Returns + * 1, 0, or , -1. + */ + virtual int seh_selector (void *); +#endif /* ACE_WIN32 */ + + /** + * Try to extend the virtual address space so that @a addr is now + * covered by the address mapping. The method succeeds and returns + * 0 if the backing store has adequate memory to cover this address. + * Otherwise, it returns -1. This method is typically called by a + * UNIX signal handler for SIGSEGV or a Win32 structured exception + * when another process has grown the backing store (and its + * mapping) and our process now incurs a fault because our mapping + * isn't in range (yet). + */ + virtual int remap (void *addr); + + /// Return the base address of this memory pool. + virtual void *base_addr (void) const; + + /// Dump the state of an object. + virtual void dump (void) const; + + /// Get reference to underlying ACE_Mem_Map object. + ACE_Mem_Map const & mmap (void) const; + + /// Get reference to underlying ACE_Mem_Map object. + ACE_Mem_Map & mmap (void); + + /// Declare the dynamic allocation hooks. + ACE_ALLOC_HOOK_DECLARE; + +protected: + /// Implement the algorithm for rounding up the request to an + /// appropriate chunksize. + virtual size_t round_up (size_t nbytes); + + /// Compute the new @a map_size of the backing store and commit the + /// memory. + virtual int commit_backing_store_name (size_t rounded_bytes, + ACE_LOFF_T &map_size); + + /// Memory map the file up to @a map_size bytes. + virtual int map_file (ACE_LOFF_T map_size); + + /// Handle SIGSEGV and SIGBUS signals to remap shared memory + /// properly. + virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); + + /// Handles SIGSEGV. + ACE_Sig_Handler signal_handler_; + + /// Memory-mapping object. + ACE_Mem_Map mmap_; + + /** + * Base of mapped region. If this has the value of 0 then the OS is + * free to select any address to map the file, otherwise this value + * is what the OS must try to use to mmap the file. + */ + void *base_addr_; + + /// Must we use the @c base_addr_ or can we let mmap(2) select it? + int use_fixed_addr_; + + /// Flags passed into <ACE_OS::mmap>. + int flags_; + + /// Should we write a byte to each page to forceably allocate memory + /// for this backing store? + int write_each_page_; + + /// What the minimum bytes of the initial segment should be. + ACE_LOFF_T minimum_bytes_; + + /// Name of the backing store where the shared memory pool is kept. + ACE_TCHAR backing_store_name_[MAXPATHLEN + 1]; + + /** + * Try to remap without knowing the faulting address. This + * parameter is ignored on platforms that know the faulting address + * (UNIX with SI_ADDR and Win32). + */ + bool guess_on_fault_; + + /// Security attributes object, only used on NT. + LPSECURITY_ATTRIBUTES sa_; + + /// Protection mode for mmaped file. + mode_t file_mode_; +}; + +/** + * @class ACE_Lite_MMAP_Memory_Pool + * + * @brief Make a ``lighter-weight'' memory pool based ACE_Mem_Map. + * + * This implementation allows memory to be shared between + * processes. However, unlike the ACE_MMAP_Memory_Pool + * the <sync> methods are no-ops, which means that we don't pay + * for the price of flushing the memory to the backing store on + * every update. Naturally, this trades off increased + * performance for less reliability if the machine crashes. + */ +class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool +{ +public: + /// Initialize the pool. + ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, + const OPTIONS *options = 0); + + /// Destructor. + virtual ~ACE_Lite_MMAP_Memory_Pool (void); + + /// Overwrite the default sync behavior with no-op + virtual int sync (ssize_t len = -1, int flags = MS_SYNC); + + /// Overwrite the default sync behavior with no-op + virtual int sync (void *addr, size_t len, int flags = MS_SYNC); +}; + +ACE_END_VERSIONED_NAMESPACE_DECL + +#if defined (__ACE_INLINE__) +#include "ace/MMAP_Memory_Pool.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* ACE_MMAP_MEMORY_POOL_H */ |