#include <Pagefile_Memory_Pool.h>
Collaboration diagram for ACE_Pagefile_Memory_Pool:
Public Types | |
typedef ACE_Pagefile_Memory_Pool_Options | OPTIONS |
Public Member Functions | |
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) |
int | release (int destroy=1) |
Instruct the memory pool to release all of its resources. | |
virtual int | seh_selector (void *) |
int | remap (void *addr) |
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. | |
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 |
void | dump (void) const |
Protected Member Functions | |
int | map (int &firstTime, size_t appendBytes=0) |
int | unmap (void) |
Release the mapping. | |
Private Attributes | |
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. |
Definition at line 61 of file Pagefile_Memory_Pool.h.
|
Definition at line 64 of file Pagefile_Memory_Pool.h. |
|
Initialize the pool.
Definition at line 50 of file Pagefile_Memory_Pool.cpp. References ACE_DEFAULT_PAGEFILE_POOL_NAME, ACE_LIB_TEXT, ACE_TCHAR, local_cb_, ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, page_size_, ACE_Pagefile_Memory_Pool::Control_Block::req_base_, round_to_chunk_size(), ACE_Pagefile_Memory_Pool::Control_Block::sh_, ACE_OS::strcat(), ACE_OS::strlen(), and ACE_OS::strsncpy().
00052 : shared_cb_ (0), 00053 object_handle_ (0), 00054 page_size_ (ACE_Pagefile_Memory_Pool::round_to_page_size (1)) 00055 { 00056 // Initialize local copy of pool statistics. 00057 if (options != 0) 00058 { 00059 this->local_cb_.req_base_ = options->base_addr_; 00060 this->local_cb_.mapped_base_ = 0; 00061 this->local_cb_.sh_.max_size_ = 00062 options->max_size_; 00063 this->local_cb_.sh_.mapped_size_ = 0; 00064 this->local_cb_.sh_.free_offset_ = 00065 this->local_cb_.sh_.mapped_size_; 00066 this->local_cb_.sh_.free_size_ = 0; 00067 } 00068 else 00069 { 00070 this->local_cb_.req_base_ = 0; 00071 this->local_cb_.mapped_base_ = 0; 00072 this->local_cb_.sh_.max_size_ = 00073 this->round_to_chunk_size (page_size_) ; 00074 this->local_cb_.sh_.mapped_size_ = 0; 00075 this->local_cb_.sh_.free_offset_ = 00076 this->local_cb_.sh_.mapped_size_; 00077 this->local_cb_.sh_.free_size_ = 0; 00078 } 00079 00080 int update_backing_store_name = backing_store_name == 0 ? 0 : 1; 00081 00082 if (backing_store_name == 0) 00083 // Only create a new unique filename for the backing store file if 00084 // the user didn't supply one... 00085 backing_store_name = ACE_DEFAULT_PAGEFILE_POOL_NAME; 00086 00087 ACE_OS::strsncpy (this->backing_store_name_, 00088 backing_store_name, 00089 (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR))); 00090 00091 if (update_backing_store_name 00092 && ACE_OS::strlen (this->backing_store_name_) < sizeof this->backing_store_name_) 00093 ACE_OS::strcat (this->backing_store_name_, 00094 ACE_LIB_TEXT ("_")); 00095 } |
|
Acquire at least from the memory pool. is the actual number of bytes allocated. Definition at line 98 of file Pagefile_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().
00100 { 00101 rounded_bytes = round_to_page_size (nbytes); 00102 void *result = 0; 00103 int first_time = 0; 00104 00105 // Check local_cb_ for consistency. Remap, if extra space is too 00106 // small and/or we didn't map the whole shared memory section 00107 if (this->shared_cb_->sh_.mapped_size_ 00108 > this->local_cb_.sh_.mapped_size_ 00109 || this->shared_cb_->sh_.free_size_ < rounded_bytes) 00110 { 00111 size_t append = 0; 00112 if (rounded_bytes > this->shared_cb_->sh_.free_size_) 00113 append = rounded_bytes - this->shared_cb_->sh_.free_size_; 00114 00115 if (this->map (first_time, append) < 0) 00116 return result; 00117 } 00118 00119 // Get the block from extra space and update shared and local 00120 // control block 00121 if (this->shared_cb_->sh_.free_size_ < rounded_bytes) 00122 return result; 00123 00124 result = (void *)((char *) this->local_cb_.mapped_base_ 00125 + this->shared_cb_->sh_.free_offset_); 00126 this->shared_cb_->sh_.free_offset_ += rounded_bytes; 00127 this->shared_cb_->sh_.free_size_ -= rounded_bytes; 00128 this->local_cb_.sh_ = this->shared_cb_->sh_; 00129 00130 return result; 00131 } |
|
Return the base address of this memory pool, 0 if base_addr never changes. |
|
Definition at line 118 of file Pagefile_Memory_Pool.h.
00118 {} |
|
Ask system for initial chunk of shared memory.
Definition at line 134 of file Pagefile_Memory_Pool.cpp. References acquire(), local_cb_, map(), ACE_Pagefile_Memory_Pool::Control_Block::mapped_base_, and round_to_page_size().
00137 { 00138 // Map the shared memory and get information, if we created the 00139 // shared memory. 00140 if (this->map (first_time) < 0) 00141 return 0; 00142 00143 if (first_time != 0) 00144 // We created the shared memory. So we have to allocate the 00145 // requested memory. 00146 return this->acquire (nbytes, rounded_bytes); 00147 else 00148 // We just mapped the memory and return the base address 00149 return (void *)((char *) this->local_cb_.mapped_base_ 00150 + ACE_Pagefile_Memory_Pool::round_to_page_size 00151 ((int) sizeof (Control_Block))); 00152 } |
|
Map portions or the entire pool into the local virtual address space. To do this, we compute the new Definition at line 223 of file Pagefile_Memory_Pool.cpp. References ACE_MAP_FILE, 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().
00225 { 00226 size_t map_size; 00227 void *map_addr; 00228 00229 // Create file mapping, if not yet done 00230 if (object_handle_ == 0) 00231 { 00232 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) 00233 // Allow access by all users. 00234 SECURITY_ATTRIBUTES sa; 00235 SECURITY_DESCRIPTOR sd; 00236 ::InitializeSecurityDescriptor (&sd, 00237 SECURITY_DESCRIPTOR_REVISION); 00238 ::SetSecurityDescriptorDacl (&sd, 00239 TRUE, 00240 0, 00241 FALSE); 00242 sa.nLength = sizeof (SECURITY_ATTRIBUTES); 00243 sa.lpSecurityDescriptor = &sd; 00244 sa.bInheritHandle = FALSE; 00245 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */ 00246 00247 // Get an object handle to the named reserved memory object. 00248 DWORD size_high; 00249 DWORD size_low; 00250 #if defined (ACE_WIN64) 00251 size_high = static_cast<DWORD> (this->local_cb_.sh_.max_size_ >> 32); 00252 size_low = static_cast<DWORD> (this->local_cb_.sh_.max_size_ & 0xFFFFFFFF); 00253 #else 00254 size_high = 0; 00255 size_low = this->local_cb_.sh_.max_size_; 00256 #endif 00257 00258 object_handle_ = 00259 ACE_TEXT_CreateFileMapping (INVALID_HANDLE_VALUE, 00260 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) 00261 &sa, 00262 #else 00263 0, 00264 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) */ 00265 PAGE_READWRITE | SEC_RESERVE, 00266 size_high, 00267 size_low, 00268 this->backing_store_name_); 00269 if (object_handle_ == 0) 00270 return -1; 00271 first_time = 00272 ::GetLastError () == ERROR_ALREADY_EXISTS 00273 ? 0 00274 : 1; 00275 } 00276 00277 // Do the initial mapping. 00278 if (this->shared_cb_ == 0) 00279 { 00280 // Map a view to the shared memory. Note: <MapViewOfFile[Ex]> 00281 // does *not* commit the pages! 00282 this->shared_cb_ = (ACE_Pagefile_Memory_Pool::Control_Block *) 00283 ACE_MAP_FILE (this->object_handle_, 00284 FILE_MAP_WRITE, 00285 0, 00286 0, 00287 this->local_cb_.sh_.max_size_, 00288 this->local_cb_.req_base_); 00289 if (this->shared_cb_ == 0) 00290 return -1; 00291 00292 // There was no previous mapping, so we map the first chunk and 00293 // initialize the shared pool statistics. 00294 if (first_time) 00295 { 00296 // 1st block is used to keep shared memory statistics. 00297 map_size = 00298 ACE_Pagefile_Memory_Pool::round_to_chunk_size 00299 (ACE_Pagefile_Memory_Pool::round_to_page_size 00300 ((int) sizeof(Control_Block)) 00301 + append_bytes); 00302 00303 if (::VirtualAlloc ((void *) this->shared_cb_, 00304 map_size, 00305 MEM_COMMIT, 00306 PAGE_READWRITE) == 0) 00307 return -1; 00308 00309 this->shared_cb_->req_base_ = 0; 00310 this->shared_cb_->mapped_base_ = 0; 00311 this->local_cb_.mapped_base_ = this->shared_cb_; 00312 this->local_cb_.sh_.mapped_size_ = map_size; 00313 this->local_cb_.sh_.free_offset_ = 00314 round_to_page_size ((int) sizeof (Control_Block)); 00315 this->local_cb_.sh_.free_size_ = 00316 this->local_cb_.sh_.mapped_size_ - 00317 this->local_cb_.sh_.free_offset_; 00318 this->shared_cb_->sh_ = this->local_cb_.sh_; 00319 } 00320 00321 // The shared memory exists, so we map the first chunk to the 00322 // base address of the pool to get the shared pool statistics. 00323 else 00324 { 00325 // 1st block is used to keep shared memory statistics. 00326 map_size = 00327 ACE_Pagefile_Memory_Pool::round_to_chunk_size 00328 ((int) sizeof (Control_Block)); 00329 00330 if (::VirtualAlloc ((void *) this->shared_cb_, 00331 map_size, 00332 MEM_COMMIT, 00333 PAGE_READWRITE) == 0) 00334 return -1; 00335 this->local_cb_.mapped_base_ = this->shared_cb_; 00336 this->local_cb_.sh_.mapped_size_ = map_size; 00337 } 00338 } 00339 00340 // If the shared memory is larger than the part we've already 00341 // committed, we have to remap it. 00342 if (this->shared_cb_->sh_.mapped_size_ > 00343 this->local_cb_.sh_.mapped_size_ 00344 || append_bytes > 0) 00345 { 00346 map_size = 00347 (this->shared_cb_->sh_.mapped_size_ - 00348 this->local_cb_.sh_.mapped_size_) 00349 + ACE_Pagefile_Memory_Pool::round_to_chunk_size 00350 (append_bytes); 00351 00352 map_addr = (void *)((char *) this->shared_cb_ + 00353 this->local_cb_.sh_.mapped_size_); 00354 00355 if (::VirtualAlloc (map_addr, 00356 map_size, 00357 MEM_COMMIT, 00358 PAGE_READWRITE) == 0) 00359 return -1; 00360 else if (append_bytes > 0) 00361 { 00362 this->shared_cb_->sh_.mapped_size_ += 00363 round_to_chunk_size (append_bytes); 00364 this->shared_cb_->sh_.free_size_ = 00365 this->shared_cb_->sh_.mapped_size_ - 00366 this->shared_cb_->sh_.free_offset_; 00367 } 00368 } 00369 00370 // Update local copy of the shared memory statistics. 00371 this->local_cb_.sh_ = 00372 this->shared_cb_->sh_; 00373 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1) 00374 ACE_BASED_POINTER_REPOSITORY::instance ()->bind 00375 (this->local_cb_.mapped_base_, 00376 this->local_cb_.sh_.mapped_size_); 00377 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */ 00378 00379 return 0; 00380 } |
|
|
|
|
|
Instruct the memory pool to release all of its resources.
Definition at line 45 of file Pagefile_Memory_Pool.cpp. References unmap().
00046 { 00047 return this->unmap (); 00048 } |
|
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). Definition at line 172 of file Pagefile_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().
00173 { 00174 // If the shared memory is not mapped or the address, that caused 00175 // the memory fault is outside of the commited range of chunks, we 00176 // return. 00177 if (this->shared_cb_ == 0 00178 || addr < this->local_cb_.mapped_base_ 00179 || addr >= (void *)((char *) this->local_cb_.mapped_base_ 00180 + this->shared_cb_->sh_.mapped_size_)) 00181 return -1; 00182 00183 // We can solve the problem by committing additional chunks. 00184 int first_time = 0; 00185 return this->map (first_time); 00186 } |
|
Round up to the chunk size required by the operation system.
Referenced by ACE_Pagefile_Memory_Pool(), and map(). |
|
Round up to system page size.
Referenced by acquire(), init_acquire(), and map(). |
|
Win32 Structural exception selector. The return value decides how to handle memory pool related structural exceptions. Returns 1, 0, or , -1. Definition at line 155 of file Pagefile_Memory_Pool.cpp. References remap().
00156 { 00157 DWORD ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode; 00158 00159 if (ecode == EXCEPTION_ACCESS_VIOLATION) 00160 { 00161 void * fault_addr = (void *) 00162 ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1]; 00163 00164 if (this->remap (fault_addr) == 0) 00165 return 1; 00166 } 00167 00168 return 0; 00169 } |
|
|
|
|
|
Release the mapping.
Definition at line 189 of file Pagefile_Memory_Pool.cpp. References ACE_DEFAULT_PAGEFILE_POOL_BASE, ACE_DEFAULT_PAGEFILE_POOL_SIZE, 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().
00190 { 00191 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1) 00192 ACE_BASED_POINTER_REPOSITORY::instance ()->unbind 00193 (this->local_cb_.mapped_base_); 00194 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */ 00195 00196 // Cleanup cached pool pointer. 00197 this->shared_cb_ = 0; 00198 00199 if (this->local_cb_.sh_.mapped_size_ > 0) 00200 ::UnmapViewOfFile (this->local_cb_.mapped_base_); 00201 00202 // Reset local pool statistics. 00203 this->local_cb_.req_base_ = 00204 ACE_DEFAULT_PAGEFILE_POOL_BASE; 00205 this->local_cb_.mapped_base_ = 0; 00206 this->local_cb_.sh_.max_size_ = 00207 ACE_DEFAULT_PAGEFILE_POOL_SIZE; 00208 this->local_cb_.sh_.mapped_size_ = 0; 00209 this->local_cb_.sh_.free_offset_ = 00210 this->local_cb_.sh_.mapped_size_; 00211 this->local_cb_.sh_.free_size_ = 0; 00212 00213 // Release the pool 00214 if (this->object_handle_ != 0) 00215 { 00216 ::CloseHandle (this->object_handle_); 00217 this->object_handle_ = 0; 00218 } 00219 return 0; 00220 } |
|
Name of the backing store where the shared memory pool is kept.
Definition at line 189 of file Pagefile_Memory_Pool.h. |
|
Description of what our process mapped.
Definition at line 177 of file Pagefile_Memory_Pool.h. Referenced by ACE_Pagefile_Memory_Pool(), acquire(), init_acquire(), map(), remap(), and unmap(). |
|
File mapping handle.
Definition at line 183 of file Pagefile_Memory_Pool.h. |
|
System page size.
Definition at line 186 of file Pagefile_Memory_Pool.h. Referenced by ACE_Pagefile_Memory_Pool(). |
|
Shared memory pool statistics.
Definition at line 180 of file Pagefile_Memory_Pool.h. |