/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace // // = FILENAME // ACE_Memory_Pool.h // // = AUTHOR // Doug Schmidt and Prashant Jain // // ============================================================================ #ifndef ACE_MEMORY_POOL_H #define ACE_MEMORY_POOL_H #include "ace/pre.h" #include "ace/ACE.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "ace/Event_Handler.h" #include "ace/Signal.h" #include "ace/Mem_Map.h" #if !defined (ACE_WIN32) #include "ace/SV_Semaphore_Complex.h" #endif /* !ACE_WIN32 */ #if !defined (ACE_LACKS_SBRK) class ACE_Export ACE_Sbrk_Memory_Pool_Options { // = TITLE // Helper class for Sbrk Memory Pool constructor options. // // = DESCRIPTION // This should be a nested class, but that breaks too many // compilers. }; class ACE_Export ACE_Sbrk_Memory_Pool { // = TITLE // Make a memory pool that is based on . public: typedef ACE_Sbrk_Memory_Pool_Options OPTIONS; ACE_Sbrk_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. virtual ~ACE_Sbrk_Memory_Pool (void); // = Implementor operations. virtual void *init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time); // Ask system for initial chunk of local memory. virtual void *acquire (size_t nbytes, size_t &rounded_bytes); // Acquire at least NBYTES from the memory pool. ROUNDED_BYTES is // the actual number of bytes allocated. virtual int release (void); // Instruct the memory pool to release all of its resources. virtual int sync (ssize_t len = -1, int flags = MS_SYNC); // Sync bytes of the memory region to the backing store // starting at base_addr_>. If == -1 then sync the // whole region. virtual int sync (void *addr, size_t len, int flags = MS_SYNC); // Sync bytes of the memory region to the backing store // starting at . virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at base_addr_> up to bytes. If == -1 // then change protection of all pages in the mapped region. virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at up to bytes. virtual void dump (void) const; // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. protected: virtual size_t round_up (size_t nbytes); // Implement the algorithm for rounding up the request to an // appropriate chunksize. }; #endif /* !ACE_LACKS_SBRK */ #if !defined (ACE_LACKS_SYSV_SHMEM) class ACE_Export ACE_Shared_Memory_Pool_Options { // = TITLE // Helper class for Shared Memory Pool constructor options. // // = DESCRIPTION // This should be a nested class, but that breaks too many // compilers. public: // = Initialization method. ACE_Shared_Memory_Pool_Options (const char *base_addr = ACE_DEFAULT_BASE_ADDR, size_t max_segments = ACE_DEFAULT_MAX_SEGMENTS, size_t file_perms = ACE_DEFAULT_FILE_PERMS, off_t minimum_bytes = 0, size_t segment_size = ACE_DEFAULT_SEGMENT_SIZE); const char *base_addr_; // Base address of the memory-mapped backing store. size_t max_segments_; // Number of shared memory segments to allocate. off_t minimum_bytes_; // What the minimum bytes of the initial segment should be. size_t file_perms_; // File permissions to use when creating/opening a segment. size_t segment_size_; // Shared memory segment size. }; class ACE_Export ACE_Shared_Memory_Pool : public ACE_Event_Handler { // = TITLE // Make a memory pool that is based on System V shared memory // (shmget(2) etc.). This implementation allows memory to be // shared between processes. public: typedef ACE_Shared_Memory_Pool_Options OPTIONS; ACE_Shared_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. virtual ~ACE_Shared_Memory_Pool (void); virtual void *init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time); // Ask system for initial chunk of local memory. virtual void *acquire (size_t nbytes, size_t &rounded_bytes); // Acquire at least NBYTES from the memory pool. ROUNDED_BYTES is // the actual number of bytes allocated. Also acquires an internal // semaphore that ensures proper serialization of Memory_Pool // initialization across processes. virtual int release (void); // Instruct the memory pool to release all of its resources. virtual int sync (ssize_t len = -1, int flags = MS_SYNC); // Sync the memory region to the backing store starting at // base_addr_>. virtual int sync (void *addr, size_t len, int flags = MS_SYNC); // Sync the memory region to the backing store starting at . virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at base_addr_> up to bytes. If == -1 // then change protection of all pages in the mapped region. virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at up to bytes. virtual void dump (void) const; // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. protected: virtual size_t round_up (size_t nbytes); // Implement the algorithm for rounding up the request to an // appropriate chunksize. virtual int commit_backing_store_name (size_t rounded_bytes, off_t &offset); // Commits a new shared memory segment if necessary after an // or a signal. is set to the new offset into // the backing store. // = Keeps track of all the segments being used. struct SHM_TABLE { key_t key_; // Shared memory segment key. int shmid_; // Shared memory segment internal id. int used_; // Is the segment currently used.; }; void *base_addr_; // Base address of the shared memory segment. If this has the value // of 0 then the OS is free to select any address, otherwise this // value is what the OS must try to use to map the shared memory // segment. size_t file_perms_; // File permissions to use when creating/opening a segment. size_t max_segments_; // Number of shared memory segments in the table. off_t minimum_bytes_; // What the minimim bytes of the initial segment should be. size_t segment_size_; // Shared memory segment size. key_t base_shm_key_; // Base shared memory key for the segment. virtual int find_seg (const void *const searchPtr, off_t &offset, size_t &counter); // find the segment that contains the searchPtr virtual int in_use (off_t &offset, size_t &counter); // Determine how much memory is currently in use. ACE_Sig_Handler signal_handler_; // Handles SIGSEGV. virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); // Handle SIGSEGV and SIGBUS signals to remap shared memory // properly. }; #endif /* !ACE_LACKS_SYSV_SHMEM */ class ACE_Export ACE_Local_Memory_Pool_Options { // = TITLE // Helper class for Local Memory Pool constructor options. // // = DESCRIPTION // This should be a nested class, but that breaks too many // compilers. }; class ACE_Export ACE_Local_Memory_Pool { // = TITLE // Make a memory pool that is based on C++ new/delete. This is // useful for integrating existing components that use new/delete // into the ACE Malloc scheme... public: typedef ACE_Local_Memory_Pool_Options OPTIONS; ACE_Local_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. virtual ~ACE_Local_Memory_Pool (void); virtual void *init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time); // Ask system for initial chunk of local memory. virtual void *acquire (size_t nbytes, size_t &rounded_bytes); // Acquire at least NBYTES from the memory pool. ROUNDED_BYTES is // the actual number of bytes allocated. virtual int release (void); // Instruct the memory pool to release all of its resources. virtual int sync (ssize_t len = -1, int flags = MS_SYNC); // Sync bytes of the memory region to the backing store // starting at base_addr_>. If == -1 then sync the // whole region. virtual int sync (void *addr, size_t len, int flags = MS_SYNC); // Sync bytes of the memory region to the backing store // starting at . virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at base_addr_> up to bytes. If == -1 // then change protection of all pages in the mapped region. virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at up to bytes. #if defined (ACE_WIN32) virtual int seh_selector (void *); // Win32 Structural exception selector. The return value decides // how to handle memory pool related structural exceptions. Returns // 1, 0, or , -1. #endif /* ACE_WIN32 */ virtual int remap (void *addr); // Try to extend the virtual address space so that is now // covered by the address mapping. Always returns 0 since we can't // remap a local memory pool. virtual void dump (void) const; // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. protected: ACE_Unbounded_Set allocated_chunks_; // List of memory that we have allocated. virtual size_t round_up (size_t nbytes); // Implement the algorithm for rounding up the request to an // appropriate chunksize. }; class ACE_Export ACE_MMAP_Memory_Pool_Options { // = TITLE // Helper class for MMAP Memory Pool constructor options. // // = DESCRIPTION // This should be a nested class, but that breaks too many // compilers. public: // = Initialization method. ACE_MMAP_Memory_Pool_Options (const void *base_addr = ACE_DEFAULT_BASE_ADDR, int use_fixed_addr = 1, int write_each_page = 1, off_t minimum_bytes = 0, u_int flags = 0, int guess_on_fault = 1, LPSECURITY_ATTRIBUTES sa = 0); const void *base_addr_; // Base address of the memory-mapped backing store. int use_fixed_addr_; // Must we use the or can we let mmap(2) select it? int write_each_page_; // Should each page be written eagerly to avoid surprises later // on? off_t minimum_bytes_; // What the minimim bytes of the initial segment should be. u_int flags_; // Any special flags that need to be used for . int guess_on_fault_; // 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). LPSECURITY_ATTRIBUTES sa_; // Pointer to a security attributes object. Only used on NT. }; class ACE_Export ACE_MMAP_Memory_Pool : public ACE_Event_Handler { // = TITLE // Make a memory pool that is based on . This // implementation allows memory to be shared between processes. public: typedef ACE_MMAP_Memory_Pool_Options OPTIONS; // = Initialization and termination methods. ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. virtual ~ACE_MMAP_Memory_Pool (void); virtual void *init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time); // Ask system for initial chunk of shared memory. virtual void *acquire (size_t nbytes, size_t &rounded_bytes); // Acquire at least from the memory pool. // is the actual number of bytes allocated. Also acquires an // internal semaphore that ensures proper serialization of // initialization across processes. virtual int release (void); // Instruct the memory pool to release all of its resources. virtual int sync (ssize_t len = -1, int flags = MS_SYNC); // Sync the memory region to the backing store starting at // base_addr_>. virtual int sync (void *addr, size_t len, int flags = MS_SYNC); // Sync the memory region to the backing store starting at . virtual int protect (ssize_t len = -1, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at base_addr_> up to bytes. If == -1 // then change protection of all pages in the mapped region. virtual int protect (void *addr, size_t len, int prot = PROT_RDWR); // Change the protection of the pages of the mapped region to // starting at up to bytes. #if defined (ACE_WIN32) virtual int seh_selector (void *); // Win32 Structural exception selector. The return value decides // how to handle memory pool related structural exceptions. Returns // 1, 0, or , -1. #endif /* ACE_WIN32 */ virtual int remap (void *addr); // Try to extend the virtual address space so that 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 void *base_addr (void) const; // Return the base address of this memory pool. virtual void dump (void) const; // Dump the state of an object. ACE_ALLOC_HOOK_DECLARE; // Declare the dynamic allocation hooks. protected: // = Implement the algorithm for rounding up the request to an // appropriate chunksize. virtual size_t round_up (size_t nbytes); virtual int commit_backing_store_name (size_t rounded_bytes, off_t &map_size); // Compute the new of the backing store and commit the // memory. virtual int map_file (off_t map_size); // Memory map the file up to bytes. virtual int handle_signal (int signum, siginfo_t *, ucontext_t *); // Handle SIGSEGV and SIGBUS signals to remap shared memory // properly. ACE_Sig_Handler signal_handler_; // Handles SIGSEGV. ACE_Mem_Map mmap_; // Memory-mapping object. void *base_addr_; // 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. int flags_; // Flags passed into . int write_each_page_; // Should we write a byte to each page to forceably allocate memory // for this backing store? off_t minimum_bytes_; // What the minimum bytes of the initial segment should be. ACE_TCHAR backing_store_name_[MAXPATHLEN + 1]; // Name of the backing store where the shared memory pool is kept. int guess_on_fault_; // 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). LPSECURITY_ATTRIBUTES sa_; // Security attributes object, only used on NT. }; class ACE_Export ACE_Lite_MMAP_Memory_Pool : public ACE_MMAP_Memory_Pool { // = TITLE // Make a ``lighter-weight'' memory pool based . // // = DESCRIPTION // This implementation allows memory to be shared between // processes. However, unlike the // the 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. public: // = Initialization and termination methods. ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. virtual ~ACE_Lite_MMAP_Memory_Pool (void); 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); // Overwrite the default sync behavior with no-op }; #if defined (ACE_WIN32) class ACE_Export ACE_Pagefile_Memory_Pool_Options { // = TITLE // Helper class for Pagefile Memory Pool constructor options. // // = DESCRIPTION // This should be a nested class, but that breaks too many // compilers. public: // Initialization method. ACE_Pagefile_Memory_Pool_Options (void *base_addr = ACE_DEFAULT_PAGEFILE_POOL_BASE, size_t max_size = ACE_DEFAULT_PAGEFILE_POOL_SIZE); void *base_addr_; // Base address of the memory-mapped backing store. size_t max_size_; // Maximum size the pool may grow. }; class ACE_Export ACE_Pagefile_Memory_Pool { // = TITLE // Make a memory pool that is based on "anonymous" memory // regions allocated from the Win32 page file. public: typedef ACE_Pagefile_Memory_Pool_Options OPTIONS; ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name = 0, const OPTIONS *options = 0); // Initialize the pool. void *init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time); // Ask system for initial chunk of shared memory. void *acquire (size_t nbytes, size_t &rounded_bytes); // Acquire at least from the memory pool. // is the actual number of bytes allocated. int release (void); // Instruct the memory pool to release all of its resources. virtual int seh_selector (void *); // Win32 Structural exception selector. The return value decides // how to handle memory pool related structural exceptions. Returns // 1, 0, or , -1. int remap (void *addr); // Try to extend the virtual address space so that 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 an // exception handler for 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). size_t round_to_page_size (size_t nbytes); // Round up to system page size. size_t round_to_chunk_size (size_t nbytes); // Round up to the chunk size required by the operation system // = Don't need this methods here ... int sync (ssize_t = -1, int = MS_SYNC); int sync (void *, size_t, int = MS_SYNC); int protect (ssize_t = -1, int = PROT_RDWR); int protect (void *, size_t, int = PROT_RDWR); void dump (void) const {} protected: int map (int &firstTime, int appendBytes = 0); // Map portions or the entire pool into the local virtual address // space. To do this, we compute the new of the // backing store and commit the memory. int unmap (void); // Release the mapping. private: class Control_Block { // = TITLE // Attributes that are meaningful in local storage only. public: void *req_base_; // required base address void *mapped_base_; // Base address returned from system call class Shared_Control_Block { // = TITLE // Pool statistics public: size_t max_size_; // Maximum size the pool may grow int mapped_size_; // Size of mapped shared memory segment int free_offset_; // Offset to mapped but not yet acquired address space int free_size_; // Size of mapped but not yet acquired address space }; Shared_Control_Block sh_; }; // 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. Control_Block local_cb_; // Description of what our process mapped. Control_Block *shared_cb_; // Shared memory pool statistics. ACE_HANDLE object_handle_; // File mapping handle. size_t page_size_; // System page size. ACE_TCHAR backing_store_name_[MAXPATHLEN]; // Name of the backing store where the shared memory pool is kept. }; #endif /* ACE_WIN32 */ #if defined (__ACE_INLINE__) #include "ace/Memory_Pool.i" #endif /* __ACE_INLINE__ */ #include "ace/post.h" #endif /* ACE_MEMORY_POOL_H */