Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

ACE_Pagefile_Memory_Pool Class Reference

Make a memory pool that is based on "anonymous" memory regions allocated from the Win32 page file. More...

#include <Memory_Pool.h>

List of all members.

Public Types

typedef ACE_Pagefile_Memory_Pool_Options OPTIONS

Public Methods

 ACE_Pagefile_Memory_Pool (const ACE_TCHAR *backing_store_name=0, const OPTIONS *options=0)
 Initialize the pool. More...

void * init_acquire (size_t nbytes, size_t &rounded_bytes, int &first_time)
 Ask system for initial chunk of shared memory. More...

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. More...

int release (int destroy=1)
 Instruct the memory pool to release all of its resources. More...

virtual int seh_selector (void *)
int remap (void *addr)
size_t round_to_page_size (size_t nbytes)
 Round up to system page size. More...

size_t round_to_chunk_size (size_t nbytes)
 Round up to the chunk size required by the operation system. More...

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)
virtual void * base_addr (void) const
 Return the base address of this memory pool, 0 if base_addr never changes. More...

void dump (void) const

Protected Methods

int map (int &firstTime, size_t appendBytes=0)
int unmap (void)
 Release the mapping. More...


Private Attributes

Control_Block local_cb_
 Description of what our process mapped. More...

Control_Blockshared_cb_
 Shared memory pool statistics. More...

ACE_HANDLE object_handle_
 File mapping handle. More...

size_t page_size_
 System page size. More...

ACE_TCHAR backing_store_name_ [MAXPATHLEN]
 Name of the backing store where the shared memory pool is kept. More...


Detailed Description

Make a memory pool that is based on "anonymous" memory regions allocated from the Win32 page file.

Definition at line 676 of file Memory_Pool.h.


Member Typedef Documentation

typedef ACE_Pagefile_Memory_Pool_Options ACE_Pagefile_Memory_Pool::OPTIONS
 

Definition at line 679 of file Memory_Pool.h.


Constructor & Destructor Documentation

ACE_Pagefile_Memory_Pool::ACE_Pagefile_Memory_Pool const ACE_TCHAR   backing_store_name = 0,
const OPTIONS   options = 0
 

Initialize the pool.

Definition at line 1031 of file Memory_Pool.cpp.

References ACE_DEFAULT_PAGEFILE_POOL_NAME, ACE_TCHAR, local_cb_, ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, ACE_Pagefile_Memory_Pool::Control_Block::req_base_, ACE_Pagefile_Memory_Pool::Control_Block::sh_, and ACE_OS_String::strsncpy.

01033   : shared_cb_ (0),
01034     object_handle_ (0),
01035     page_size_ (ACE_Pagefile_Memory_Pool::round_to_page_size (1))
01036 {
01037   // Initialize local copy of pool statistics.
01038   if (options != 0)
01039     {
01040       this->local_cb_.req_base_ = options->base_addr_;
01041       this->local_cb_.mapped_base_ = 0;
01042       this->local_cb_.sh_.max_size_ =
01043         options->max_size_;
01044       this->local_cb_.sh_.mapped_size_ = 0;
01045       this->local_cb_.sh_.free_offset_ =
01046         this->local_cb_.sh_.mapped_size_;
01047       this->local_cb_.sh_.free_size_ = 0;
01048     }
01049 
01050   if (backing_store_name == 0)
01051     // Only create a new unique filename for the backing store file if
01052     // the user didn't supply one...
01053     backing_store_name = ACE_DEFAULT_PAGEFILE_POOL_NAME;
01054 
01055   ACE_OS::strsncpy (this->backing_store_name_,
01056                     backing_store_name,
01057                     (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
01058 }


Member Function Documentation

void * ACE_Pagefile_Memory_Pool::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.

Definition at line 1061 of file Memory_Pool.cpp.

References local_cb_, map, ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, round_to_page_size, ACE_Pagefile_Memory_Pool::Control_Block::sh_, and shared_cb_.

Referenced by init_acquire.

01063 {
01064   rounded_bytes = round_to_page_size (nbytes);
01065   void *result = 0;
01066   int first_time = 0;
01067 
01068   // Check local_cb_ for consistency.  Remap, if extra space is too
01069   // small and/or we didn't map the whole shared memory section
01070   if (this->shared_cb_->sh_.mapped_size_
01071       > this->local_cb_.sh_.mapped_size_
01072       || this->shared_cb_->sh_.free_size_ < rounded_bytes)
01073     {
01074       size_t append = 0;
01075       if (rounded_bytes > this->shared_cb_->sh_.free_size_)
01076         append = rounded_bytes - this->shared_cb_->sh_.free_size_;
01077 
01078       if (this->map (first_time, append) < 0)
01079         return result;
01080     }
01081 
01082   // Get the block from extra space and update shared and local
01083   // control block
01084   if (this->shared_cb_->sh_.free_size_ < rounded_bytes)
01085     return result;
01086 
01087   result = (void *)((char *) this->local_cb_.mapped_base_
01088                     + this->shared_cb_->sh_.free_offset_);
01089   this->shared_cb_->sh_.free_offset_ += rounded_bytes;
01090   this->shared_cb_->sh_.free_size_ -= rounded_bytes;
01091   this->local_cb_.sh_ = this->shared_cb_->sh_;
01092 
01093   return result;
01094 }

virtual void* ACE_Pagefile_Memory_Pool::base_addr void    const [virtual]
 

Return the base address of this memory pool, 0 if base_addr never changes.

void ACE_Pagefile_Memory_Pool::dump void    const [inline]
 

Definition at line 733 of file Memory_Pool.h.

00733 {}

void * ACE_Pagefile_Memory_Pool::init_acquire size_t    nbytes,
size_t &    rounded_bytes,
int &    first_time
 

Ask system for initial chunk of shared memory.

Definition at line 1097 of file Memory_Pool.cpp.

References acquire, local_cb_, map, ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, and round_to_page_size.

01100 {
01101   // Map the shared memory and get information, if we created the
01102   // shared memory.
01103   if (this->map (first_time) < 0)
01104     return 0;
01105 
01106   if (first_time != 0)
01107     // We created the shared memory. So we have to allocate the
01108     // requested memory.
01109     return this->acquire (nbytes, rounded_bytes);
01110   else
01111     // We just mapped the memory and return the base address
01112     return (void *)((char *) this->local_cb_.mapped_base_
01113                     + ACE_Pagefile_Memory_Pool::round_to_page_size
01114                     ((int) sizeof (Control_Block)));
01115 }

int ACE_Pagefile_Memory_Pool::map int &    firstTime,
size_t    appendBytes = 0
[protected]
 

Map portions or the entire pool into the local virtual address space. To do this, we compute the new <file_offset> of the backing store and commit the memory.

Definition at line 1186 of file Memory_Pool.cpp.

References ACE_MAP_FILE, ACE_Singleton::instance, local_cb_, ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, object_handle_, ACE_Pagefile_Memory_Pool::Control_Block::req_base_, round_to_chunk_size, round_to_page_size, ACE_Pagefile_Memory_Pool::Control_Block::sh_, and shared_cb_.

Referenced by acquire, init_acquire, and remap.

01188 {
01189   size_t map_size;
01190   void *map_addr;
01191 
01192   // Create file mapping, if not yet done
01193   if (object_handle_ == 0)
01194     {
01195 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
01196       // Allow access by all users.
01197       SECURITY_ATTRIBUTES sa;
01198       SECURITY_DESCRIPTOR sd;
01199       ::InitializeSecurityDescriptor (&sd,
01200                                       SECURITY_DESCRIPTOR_REVISION);
01201       ::SetSecurityDescriptorDacl (&sd,
01202                                    TRUE,
01203                                    0,
01204                                    FALSE);
01205       sa.nLength = sizeof (SECURITY_ATTRIBUTES);
01206       sa.lpSecurityDescriptor = &sd;
01207       sa.bInheritHandle = FALSE;
01208 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */
01209 
01210       // Get an object handle to the named reserved memory object.
01211       DWORD size_high;
01212       DWORD size_low;
01213 #if defined (ACE_WIN64)
01214       size_high = ACE_static_cast (DWORD,
01215                                    this->local_cb_.sh_.max_size_ >> 32);
01216       size_low  = ACE_static_cast (DWORD,
01217                                    this->local_cb_.sh_.max_size_ & 0xFFFFFFFF);
01218 #else
01219       size_high = 0;
01220       size_low = this->local_cb_.sh_.max_size_;
01221 #endif
01222 
01223       object_handle_ =
01224         ACE_TEXT_CreateFileMapping (INVALID_HANDLE_VALUE,
01225 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0))
01226                                     &sa,
01227 #else
01228                                     0,
01229 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */
01230                                     PAGE_READWRITE | SEC_RESERVE,
01231                                     size_high,
01232                                     size_low,
01233                                     this->backing_store_name_);
01234       if (object_handle_ == 0)
01235         return -1;
01236       first_time =
01237         ::GetLastError () == ERROR_ALREADY_EXISTS
01238         ? 0
01239         : 1;
01240     }
01241 
01242   // Do the initial mapping.
01243   if (this->shared_cb_ == 0)
01244     {
01245       // Map a view to the shared memory.  Note: <MapViewOfFile[Ex]>
01246       // does *not* commit the pages!
01247       this->shared_cb_ = (ACE_Pagefile_Memory_Pool::Control_Block *)
01248         ACE_MAP_FILE (this->object_handle_,
01249                       FILE_MAP_WRITE,
01250                       0,
01251                       0,
01252                       this->local_cb_.sh_.max_size_,
01253                       this->local_cb_.req_base_);
01254       if (this->shared_cb_ == 0)
01255         return -1;
01256 
01257       // There was no previous mapping, so we map the first chunk and
01258       // initialize the shared pool statistics.
01259       if (first_time)
01260         {
01261           // 1st block is used to keep shared memory statistics.
01262           map_size =
01263             ACE_Pagefile_Memory_Pool::round_to_chunk_size
01264             (ACE_Pagefile_Memory_Pool::round_to_page_size
01265              ((int) sizeof(Control_Block))
01266              + append_bytes);
01267 
01268           if (::VirtualAlloc ((void *) this->shared_cb_,
01269                               map_size,
01270                               MEM_COMMIT,
01271                               PAGE_READWRITE) == 0)
01272             return -1;
01273 
01274           this->shared_cb_->req_base_ = 0;
01275           this->shared_cb_->mapped_base_ = 0;
01276           this->local_cb_.mapped_base_ = this->shared_cb_;
01277           this->local_cb_.sh_.mapped_size_ = map_size;
01278           this->local_cb_.sh_.free_offset_ =
01279             round_to_page_size ((int) sizeof (Control_Block));
01280           this->local_cb_.sh_.free_size_ =
01281             this->local_cb_.sh_.mapped_size_ -
01282             this->local_cb_.sh_.free_offset_;
01283           this->shared_cb_->sh_ = this->local_cb_.sh_;
01284         }
01285 
01286       // The shared memory exists, so we map the first chunk to the
01287       // base address of the pool to get the shared pool statistics.
01288       else
01289         {
01290           // 1st block is used to keep shared memory statistics.
01291           map_size =
01292             ACE_Pagefile_Memory_Pool::round_to_chunk_size
01293             ((int) sizeof (Control_Block));
01294 
01295           if (::VirtualAlloc ((void *) this->shared_cb_,
01296                               map_size,
01297                               MEM_COMMIT,
01298                               PAGE_READWRITE) == 0)
01299             return -1;
01300           this->local_cb_.mapped_base_ = this->shared_cb_;
01301           this->local_cb_.sh_.mapped_size_ = map_size;
01302         }
01303     }
01304 
01305   // If the shared memory is larger than the part we've already
01306   // committed, we have to remap it.
01307   if (this->shared_cb_->sh_.mapped_size_ >
01308       this->local_cb_.sh_.mapped_size_
01309       || append_bytes > 0)
01310     {
01311       map_size =
01312         (this->shared_cb_->sh_.mapped_size_ -
01313          this->local_cb_.sh_.mapped_size_)
01314         + ACE_Pagefile_Memory_Pool::round_to_chunk_size
01315         (append_bytes);
01316 
01317       map_addr = (void *)((char *) this->shared_cb_ +
01318                           this->local_cb_.sh_.mapped_size_);
01319 
01320       if (::VirtualAlloc (map_addr,
01321                           map_size,
01322                           MEM_COMMIT,
01323                           PAGE_READWRITE) == 0)
01324         return -1;
01325       else if (append_bytes > 0)
01326         {
01327           this->shared_cb_->sh_.mapped_size_ +=
01328             round_to_chunk_size (append_bytes);
01329           this->shared_cb_->sh_.free_size_ =
01330             this->shared_cb_->sh_.mapped_size_ -
01331             this->shared_cb_->sh_.free_offset_;
01332         }
01333     }
01334 
01335   // Update local copy of the shared memory statistics.
01336   this->local_cb_.sh_ =
01337     this->shared_cb_->sh_;
01338 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
01339   ACE_BASED_POINTER_REPOSITORY::instance ()->bind
01340     (this->local_cb_.mapped_base_,
01341      this->local_cb_.sh_.mapped_size_);
01342 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
01343 
01344   return 0;
01345 }

int ACE_Pagefile_Memory_Pool::protect void *   ,
size_t   ,
int    = PROT_RDWR
 

int ACE_Pagefile_Memory_Pool::protect ssize_t    = -1,
int    = PROT_RDWR
 

int ACE_Pagefile_Memory_Pool::release int    destroy = 1
 

Instruct the memory pool to release all of its resources.

Definition at line 1026 of file Memory_Pool.cpp.

References unmap.

01027 {
01028   return this->unmap ();
01029 }

int ACE_Pagefile_Memory_Pool::remap void *    addr
 

Try to extend the virtual address space so that <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 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).

Definition at line 1135 of file Memory_Pool.cpp.

References local_cb_, map, ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, ACE_Pagefile_Memory_Pool::Control_Block::sh_, and shared_cb_.

Referenced by seh_selector.

01136 {
01137   // If the shared memory is not mapped or the address, that caused
01138   // the memory fault is outside of the commited range of chunks, we
01139   // return.
01140   if (this->shared_cb_ == 0
01141       || addr < this->local_cb_.mapped_base_
01142       || addr >= (void *)((char *) this->local_cb_.mapped_base_
01143                           + this->shared_cb_->sh_.mapped_size_))
01144     return -1;
01145 
01146   // We can solve the problem by committing additional chunks.
01147   int first_time = 0;
01148   return this->map (first_time);
01149 }

size_t ACE_Pagefile_Memory_Pool::round_to_chunk_size size_t    nbytes
 

Round up to the chunk size required by the operation system.

Referenced by map.

size_t ACE_Pagefile_Memory_Pool::round_to_page_size size_t    nbytes
 

Round up to system page size.

Referenced by acquire, init_acquire, and map.

int ACE_Pagefile_Memory_Pool::seh_selector void *    [virtual]
 

Win32 Structural exception selector. The return value decides how to handle memory pool related structural exceptions. Returns 1, 0, or , -1.

Definition at line 1118 of file Memory_Pool.cpp.

References remap.

01119 {
01120   DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
01121 
01122   if (ecode == EXCEPTION_ACCESS_VIOLATION)
01123     {
01124       void * fault_addr = (void *)
01125         ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
01126 
01127       if (this->remap (fault_addr) == 0)
01128         return 1;
01129     }
01130 
01131   return 0;
01132 }

int ACE_Pagefile_Memory_Pool::sync void *   ,
size_t   ,
int    = MS_SYNC
 

int ACE_Pagefile_Memory_Pool::sync ssize_t    = -1,
int    = MS_SYNC
 

int ACE_Pagefile_Memory_Pool::unmap void    [protected]
 

Release the mapping.

Definition at line 1152 of file Memory_Pool.cpp.

References ACE_DEFAULT_PAGEFILE_POOL_BASE, ACE_DEFAULT_PAGEFILE_POOL_SIZE, ACE_Singleton::instance, local_cb_, ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, object_handle_, ACE_Pagefile_Memory_Pool::Control_Block::req_base_, ACE_Pagefile_Memory_Pool::Control_Block::sh_, and shared_cb_.

Referenced by release.

01153 {
01154 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
01155   ACE_BASED_POINTER_REPOSITORY::instance ()->unbind
01156     (this->local_cb_.mapped_base_);
01157 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */
01158 
01159   // Cleanup cached pool pointer.
01160   this->shared_cb_ = 0;
01161 
01162   if (this->local_cb_.sh_.mapped_size_ > 0)
01163     ::UnmapViewOfFile (this->local_cb_.mapped_base_);
01164 
01165   // Reset local pool statistics.
01166   this->local_cb_.req_base_ =
01167     ACE_DEFAULT_PAGEFILE_POOL_BASE;
01168   this->local_cb_.mapped_base_ = 0;
01169   this->local_cb_.sh_.max_size_ =
01170     ACE_DEFAULT_PAGEFILE_POOL_SIZE;
01171   this->local_cb_.sh_.mapped_size_ = 0;
01172   this->local_cb_.sh_.free_offset_ =
01173     this->local_cb_.sh_.mapped_size_;
01174   this->local_cb_.sh_.free_size_ = 0;
01175 
01176   // Release the pool
01177   if (this->object_handle_ != 0)
01178     {
01179       ::CloseHandle (this->object_handle_);
01180       this->object_handle_ = 0;
01181     }
01182   return 0;
01183 }


Member Data Documentation

ACE_TCHAR ACE_Pagefile_Memory_Pool::backing_store_name_[MAXPATHLEN] [private]
 

Name of the backing store where the shared memory pool is kept.

Definition at line 804 of file Memory_Pool.h.

Control_Block ACE_Pagefile_Memory_Pool::local_cb_ [private]
 

Description of what our process mapped.

Definition at line 792 of file Memory_Pool.h.

Referenced by ACE_Pagefile_Memory_Pool, acquire, init_acquire, map, remap, and unmap.

ACE_HANDLE ACE_Pagefile_Memory_Pool::object_handle_ [private]
 

File mapping handle.

Definition at line 798 of file Memory_Pool.h.

Referenced by map, and unmap.

size_t ACE_Pagefile_Memory_Pool::page_size_ [private]
 

System page size.

Definition at line 801 of file Memory_Pool.h.

Control_Block* ACE_Pagefile_Memory_Pool::shared_cb_ [private]
 

Shared memory pool statistics.

Definition at line 795 of file Memory_Pool.h.

Referenced by acquire, map, remap, and unmap.


The documentation for this class was generated from the following files:
Generated on Mon Jun 16 12:51:57 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002