00001
00002
00003
00004 #include "ace/MMAP_Memory_Pool.h"
00005 #include "ace/OS_NS_sys_mman.h"
00006 #include "ace/OS_NS_unistd.h"
00007 #include "ace/OS_NS_string.h"
00008 #include "ace/OS_NS_sys_stat.h"
00009 #include "ace/Log_Msg.h"
00010
00011 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00012 #include "ace/Based_Pointer_T.h"
00013 #include "ace/Based_Pointer_Repository.h"
00014 #endif
00015
00016 #if !defined (__ACE_INLINE__)
00017 #include "ace/MMAP_Memory_Pool.inl"
00018 #endif
00019
00020 ACE_RCSID(ace,
00021 MMAP_Memory_Pool,
00022 "MMAP_Memory_Pool.cpp,v 4.13 2006/06/09 14:03:06 jwillemsen Exp")
00023
00024 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00025
00026 ACE_ALLOC_HOOK_DEFINE(ACE_MMAP_Memory_Pool)
00027
00028 void
00029 ACE_MMAP_Memory_Pool::dump (void) const
00030 {
00031 #if defined (ACE_HAS_DUMP)
00032 ACE_TRACE ("ACE_MMAP_Memory_Pool::dump");
00033 #endif
00034 }
00035
00036 int
00037 ACE_MMAP_Memory_Pool::release (int destroy)
00038 {
00039 ACE_TRACE ("ACE_MMAP_Memory_Pool::release");
00040
00041 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00042 ACE_BASED_POINTER_REPOSITORY::instance ()->unbind (this->mmap_.addr ());
00043 #endif
00044
00045 if (destroy)
00046 this->mmap_.remove ();
00047 else
00048 this->mmap_.close ();
00049 return 0;
00050 }
00051
00052 int
00053 ACE_MMAP_Memory_Pool::sync (ssize_t len, int flags)
00054 {
00055 ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
00056
00057 if (len < 0)
00058 len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
00059
00060 return this->mmap_.sync (len, flags);
00061 }
00062
00063
00064
00065
00066 int
00067 ACE_MMAP_Memory_Pool::sync (void *addr, size_t len, int flags)
00068 {
00069 ACE_TRACE ("ACE_MMAP_Memory_Pool::sync");
00070 return ACE_OS::msync (addr, len, flags);
00071 }
00072
00073
00074
00075
00076
00077 int
00078 ACE_MMAP_Memory_Pool::protect (ssize_t len, int prot)
00079 {
00080 ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
00081
00082 if (len < 0)
00083 len = ACE_OS::lseek (this->mmap_.handle (), 0, SEEK_END);
00084
00085 return this->mmap_.protect (len, prot);
00086 }
00087
00088
00089
00090
00091 int
00092 ACE_MMAP_Memory_Pool::protect (void *addr, size_t len, int prot)
00093 {
00094 ACE_TRACE ("ACE_MMAP_Memory_Pool::protect");
00095 return ACE_OS::mprotect (addr, len, prot);
00096 }
00097
00098 ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
00099 const OPTIONS *options)
00100 : base_addr_ (0),
00101 use_fixed_addr_(0),
00102 flags_ (MAP_SHARED),
00103 write_each_page_ (0),
00104 minimum_bytes_ (0),
00105 sa_ (0),
00106 file_mode_ (ACE_DEFAULT_FILE_PERMS)
00107 {
00108 ACE_TRACE ("ACE_MMAP_Memory_Pool::ACE_MMAP_Memory_Pool");
00109
00110 #if (defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)) || defined (ACE_WIN32)
00111
00112 guess_on_fault_ = false;
00113 #else
00114
00115
00116 if (options)
00117 guess_on_fault_ = options->guess_on_fault_;
00118 else
00119
00120 guess_on_fault_ = true;
00121 #endif
00122
00123
00124 if (options)
00125 {
00126 if (options->flags_ != 0)
00127 this->flags_ = options->flags_;
00128 use_fixed_addr_ = options->use_fixed_addr_;
00129
00130 if (use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED)
00131 {
00132 this->base_addr_ = const_cast<void *> (options->base_addr_);
00133 ACE_SET_BITS (flags_, MAP_FIXED);
00134 }
00135 this->write_each_page_ = options->write_each_page_;
00136 this->minimum_bytes_ = options->minimum_bytes_;
00137 if (options->sa_ != 0)
00138 this->sa_ = options->sa_;
00139 this->file_mode_ = options->file_mode_;
00140 }
00141
00142 if (backing_store_name == 0)
00143 {
00144
00145
00146 #if defined (ACE_DEFAULT_BACKING_STORE)
00147
00148 ACE_OS::strcpy (this->backing_store_name_,
00149 ACE_DEFAULT_BACKING_STORE);
00150 #else
00151 if (ACE::get_temp_dir (this->backing_store_name_,
00152 MAXPATHLEN - 17) == -1)
00153
00154 {
00155 ACE_ERROR ((LM_ERROR,
00156 ACE_LIB_TEXT ("Temporary path too long, ")
00157 ACE_LIB_TEXT ("defaulting to current directory\n")));
00158 this->backing_store_name_[0] = 0;
00159 }
00160
00161
00162 ACE_OS::strcat (this->backing_store_name_,
00163 ACE_LIB_TEXT ("ace-malloc-XXXXXX"));
00164
00165
00166 if (options->unique_)
00167 ACE_OS::mktemp(this->backing_store_name_);
00168 #endif
00169 }
00170 else
00171 ACE_OS::strsncpy (this->backing_store_name_,
00172 backing_store_name,
00173 (sizeof this->backing_store_name_ / sizeof (ACE_TCHAR)));
00174
00175 #if !defined (ACE_WIN32)
00176 if (this->signal_handler_.register_handler (SIGSEGV, this) == -1)
00177 ACE_ERROR ((LM_ERROR,
00178 "%p\n", this->backing_store_name_));
00179 #endif
00180 }
00181
00182 ACE_MMAP_Memory_Pool::~ACE_MMAP_Memory_Pool (void)
00183 {
00184 }
00185
00186
00187
00188 int
00189 ACE_MMAP_Memory_Pool::commit_backing_store_name (size_t rounded_bytes,
00190 ACE_LOFF_T &map_size)
00191 {
00192 ACE_TRACE ("ACE_MMAP_Memory_Pool::commit_backing_store_name");
00193
00194 size_t seek_len;
00195
00196 if (this->write_each_page_)
00197
00198
00199 seek_len = this->round_up (1);
00200 else
00201
00202 seek_len = rounded_bytes;
00203
00204
00205
00206
00207
00208 for (size_t cur_block = 0;
00209 cur_block < rounded_bytes;
00210 cur_block += seek_len)
00211 {
00212 map_size = ACE_OS::lseek (this->mmap_.handle (),
00213 static_cast<off_t> (seek_len - 1),
00214 SEEK_END);
00215
00216 if (map_size == -1
00217 || ACE_OS::write (this->mmap_.handle (),
00218 "",
00219 1) == -1)
00220 ACE_ERROR_RETURN ((LM_ERROR,
00221 ACE_LIB_TEXT ("(%P|%t) %p\n"),
00222 this->backing_store_name_),
00223 -1);
00224 }
00225
00226 #if defined (ACE_OPENVMS)
00227 ::fsync(this->mmap_.handle());
00228 #endif
00229
00230
00231 ++map_size;
00232
00233 return 0;
00234 }
00235
00236
00237
00238 int
00239 ACE_MMAP_Memory_Pool::map_file (ACE_LOFF_T map_size)
00240 {
00241 ACE_TRACE ("ACE_MMAP_Memory_Pool::map_file");
00242 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00243 void* obase_addr = this->base_addr_;
00244 #endif
00245
00246
00247 this->mmap_.unmap ();
00248
00249 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00250 if(use_fixed_addr_ == ACE_MMAP_Memory_Pool_Options::NEVER_FIXED)
00251 this->base_addr_ = 0;
00252 #endif
00253
00254
00255 if (this->mmap_.map (map_size,
00256 PROT_RDWR,
00257 this->flags_,
00258 this->base_addr_,
00259 0,
00260 this->sa_) == -1
00261 || this->base_addr_ != 0
00262 #ifdef ACE_HAS_WINCE
00263 && this->mmap_.addr () == 0)
00264 #else
00265 && this->mmap_.addr () != this->base_addr_)
00266 #endif // ACE_HAS_WINCE
00267 {
00268 #if 0
00269 ACE_ERROR ((LM_ERROR,
00270 ACE_LIB_TEXT ("(%P|%t) addr = %u, base_addr = %u, map_size = %u, %p\n"),
00271 this->mmap_.addr (),
00272 this->base_addr_,
00273 map_size,
00274 this->backing_store_name_));
00275 #endif
00276 return -1;
00277 }
00278 else
00279 {
00280 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00281 this->base_addr_ = this->mmap_.addr ();
00282 if(obase_addr && this->base_addr_ != obase_addr)
00283 ACE_BASED_POINTER_REPOSITORY::instance ()->unbind (obase_addr);
00284 ACE_BASED_POINTER_REPOSITORY::instance ()->bind (this->base_addr_,
00285 map_size);
00286 #endif
00287 return 0;
00288 }
00289 }
00290
00291
00292
00293
00294
00295 void *
00296 ACE_MMAP_Memory_Pool::acquire (size_t nbytes,
00297 size_t &rounded_bytes)
00298 {
00299 ACE_TRACE ("ACE_MMAP_Memory_Pool::acquire");
00300 rounded_bytes = this->round_up (nbytes);
00301
00302
00303
00304
00305 ACE_LOFF_T map_size;
00306
00307 if (this->commit_backing_store_name (rounded_bytes,
00308 map_size) == -1)
00309 return 0;
00310 else if (this->map_file (map_size) == -1)
00311 return 0;
00312
00313
00314
00315
00316
00317 return (void *) ((char *) this->mmap_.addr () + (this->mmap_.size () - rounded_bytes));
00318 }
00319
00320
00321
00322 void *
00323 ACE_MMAP_Memory_Pool::init_acquire (size_t nbytes,
00324 size_t &rounded_bytes,
00325 int &first_time)
00326 {
00327 ACE_TRACE ("ACE_MMAP_Memory_Pool::init_acquire");
00328
00329 first_time = 0;
00330
00331 if (nbytes < static_cast <size_t> (this->minimum_bytes_))
00332 nbytes = static_cast <size_t> (this->minimum_bytes_);
00333
00334 if (this->mmap_.open (this->backing_store_name_,
00335 O_RDWR | O_CREAT | O_TRUNC | O_EXCL,
00336 this->file_mode_, this->sa_) != -1)
00337 {
00338
00339 first_time = 1;
00340 return this->acquire (nbytes, rounded_bytes);
00341 }
00342 else if (errno == EEXIST)
00343 {
00344 errno = 0;
00345
00346 if (this->mmap_.map (this->backing_store_name_,
00347 -1,
00348 O_RDWR,
00349 this->file_mode_,
00350 PROT_RDWR,
00351 this->flags_,
00352 this->base_addr_,
00353 0,
00354 this->sa_) == -1)
00355 ACE_ERROR_RETURN ((LM_ERROR,
00356 ACE_LIB_TEXT ("%p\n"),
00357 ACE_LIB_TEXT ("MMAP_Memory_Pool::init_acquire, EEXIST")),
00358 0);
00359
00360 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
00361
00362 ACE_BASED_POINTER_REPOSITORY::instance ()->bind (this->mmap_.addr(),
00363 this->mmap_.size());
00364 #endif
00365
00366 return this->mmap_.addr ();
00367 }
00368 else
00369 ACE_ERROR_RETURN ((LM_ERROR,
00370 ACE_LIB_TEXT ("%p\n"),
00371 ACE_LIB_TEXT ("MMAP_Memory_Pool::init_acquire")),
00372 0);
00373 }
00374
00375 #if defined (ACE_WIN32)
00376 int
00377 ACE_MMAP_Memory_Pool::seh_selector (void *ep)
00378 {
00379 DWORD const ecode = ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionCode;
00380
00381 if (ecode == EXCEPTION_ACCESS_VIOLATION)
00382 {
00383 void * fault_addr = (void *)
00384 ((EXCEPTION_POINTERS *) ep)->ExceptionRecord->ExceptionInformation[1];
00385
00386 if (this->remap (fault_addr) == 0)
00387 return 1;
00388 }
00389
00390 return 0;
00391 }
00392 #endif
00393
00394 int
00395 ACE_MMAP_Memory_Pool::remap (void *addr)
00396 {
00397 ACE_TRACE ("ACE_MMAP_Memory_Pool::remap");
00398
00399 off_t const current_map_size = ACE_OS::filesize (this->mmap_.handle ());
00400
00401
00402 if (!(addr < (void *) ((char *) this->mmap_.addr () + current_map_size)
00403 && addr >= this->mmap_.addr ()))
00404 return -1;
00405
00406
00407 return this->map_file (current_map_size);
00408 }
00409
00410 ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options (const void *base_addr,
00411 int use_fixed_addr,
00412 int write_each_page,
00413 ACE_LOFF_T minimum_bytes,
00414 u_int flags,
00415 int guess_on_fault,
00416 LPSECURITY_ATTRIBUTES sa,
00417 mode_t file_mode,
00418 bool unique)
00419 : base_addr_ (base_addr),
00420 use_fixed_addr_ (use_fixed_addr),
00421 write_each_page_ (write_each_page),
00422 minimum_bytes_ (minimum_bytes),
00423 flags_ (flags),
00424 guess_on_fault_ (guess_on_fault),
00425 sa_ (sa),
00426 file_mode_ (file_mode),
00427 unique_ (unique)
00428 {
00429 ACE_TRACE ("ACE_MMAP_Memory_Pool_Options::ACE_MMAP_Memory_Pool_Options");
00430
00431 if (base_addr_ == 0 && use_fixed_addr_ == ALWAYS_FIXED)
00432 use_fixed_addr_ = FIRSTCALL_FIXED;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 int
00446 ACE_MMAP_Memory_Pool::handle_signal (int signum, siginfo_t *siginfo, ucontext_t *)
00447 {
00448 if (signum != SIGSEGV)
00449 return -1;
00450 else
00451 ;
00452
00453
00454
00455 #if defined (ACE_HAS_SIGINFO_T) && !defined (ACE_LACKS_SI_ADDR)
00456
00457
00458
00459 if (siginfo != 0)
00460 {
00461
00462 if (this->remap ((void *) siginfo->si_addr) == -1)
00463 return -1;
00464
00465
00466 return 0;
00467 }
00468 #else
00469 ACE_UNUSED_ARG(siginfo);
00470 #endif
00471
00472
00473
00474
00475
00476
00477 if (guess_on_fault_)
00478 {
00479
00480 ACE_LOFF_T const current_map_size = ACE_OS::filesize (this->mmap_.handle ());
00481
00482 if (static_cast<size_t> (current_map_size) == this->mmap_.size ())
00483 {
00484
00485
00486
00487
00488 this->signal_handler_.remove_handler (SIGSEGV);
00489 return 0;
00490 }
00491
00492
00493 return this->map_file (current_map_size);
00494 }
00495 else
00496 return -1;
00497 }
00498
00499 void *
00500 ACE_MMAP_Memory_Pool::base_addr (void) const
00501 {
00502 ACE_TRACE ("ACE_MMAP_Memory_Pool::base_addr");
00503 return this->base_addr_;
00504 }
00505
00506 size_t
00507 ACE_MMAP_Memory_Pool::round_up (size_t nbytes)
00508 {
00509 ACE_TRACE ("ACE_MMAP_Memory_Pool::round_up");
00510 return ACE::round_to_pagesize (static_cast<off_t> (nbytes));
00511 }
00512
00513 ACE_ALLOC_HOOK_DEFINE(ACE_Lite_MMAP_Memory_Pool)
00514
00515 ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool (const ACE_TCHAR *backing_store_name,
00516 const OPTIONS *options)
00517 : ACE_MMAP_Memory_Pool (backing_store_name, options)
00518 {
00519 ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::ACE_Lite_MMAP_Memory_Pool");
00520 }
00521
00522 ACE_Lite_MMAP_Memory_Pool::~ACE_Lite_MMAP_Memory_Pool (void)
00523 {
00524 }
00525
00526 int
00527 ACE_Lite_MMAP_Memory_Pool::sync (ssize_t, int)
00528 {
00529 ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
00530 return 0;
00531 }
00532
00533 int
00534 ACE_Lite_MMAP_Memory_Pool::sync (void *, size_t, int)
00535 {
00536 ACE_TRACE ("ACE_Lite_MMAP_Memory_Pool::sync");
00537 return 0;
00538 }
00539
00540 ACE_END_VERSIONED_NAMESPACE_DECL