00001 // $Id: MMAP_Allocator.cpp 73861 2006-08-04 09:07:09Z johnnyw $ 00002 00003 #include "tao/MMAP_Allocator.h" 00004 00005 #if TAO_HAS_SENDFILE == 1 00006 00007 #include "ace/Mem_Map.h" 00008 #include "ace/Default_Constants.h" 00009 00010 00011 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00012 00013 namespace 00014 { 00015 // Default size mmap()ed memory pool will be the sum of the control 00016 // block size and the default CDR buffer chosen by the user. The 00017 // final size may be rounded up by the allocator to be aligned on 00018 // the appropriate boundary/page. 00019 // 00020 // @@ This type really should be ACE_LOFF_T but ACE's mmap()-based 00021 // classes currently do not handle large file offsets. 00022 // -Ossama 00023 off_t const the_default_buf_size = 00024 sizeof (ACE_Control_Block) + ACE_DEFAULT_CDR_BUFSIZE; 00025 00026 ACE_MMAP_Memory_Pool_Options const the_pool_options ( 00027 ACE_DEFAULT_BASE_ADDR, 00028 ACE_MMAP_Memory_Pool_Options::ALWAYS_FIXED, 00029 0, // No need to sync 00030 the_default_buf_size, 00031 MAP_SHARED, // Written data must be reflected in the backing store 00032 // file in order for sendfile() to be able to read it. 00033 1, 00034 0, 00035 /* 0 */ ACE_DEFAULT_FILE_PERMS, 00036 true); // Generate for each mmap an unqiue pool 00037 } 00038 00039 00040 // Ideally we should open the backing store with shm_open() so that we 00041 // can avoid creating an on-disk backing store. An on-disk backing 00042 // store could potentially cause sendfile() to block on disk I/O, 00043 // which is undesirable. Unfortunately, ACE_Mem_Map currently 00044 // provides no way to configure which "open" function to use, 00045 // i.e. open(2) or shm_open(3). Alternatively we could shm_open() the 00046 // backing store file beforehand. Unfortunately, 00047 // ACE_{Lite_}MMAP_Memory_Pool currently doesn't provide a means to 00048 // pass the file descriptor for the desired backing store to the 00049 // underlying ACE_Mem_Map object. 00050 // 00051 // It may be tempting to mmap() /dev/zero. That would certainly 00052 // provide the desired transient "scratch space" memory that we can 00053 // write and read to and from, respectively. Unfortunately, the data 00054 // in /dev/zero-based memory mapped buffer can only be read through 00055 // the buffer itself, not through the file descriptor (e.g. using 00056 // read(2)) for the open()ed /dev/zero device. Reading through the 00057 // /dev/zero file descriptor simply returns zero, as /dev/zero was 00058 // designed to do. So unfortunate. :) 00059 TAO_MMAP_Allocator::TAO_MMAP_Allocator (void) 00060 : TAO_MMAP_Allocator_Base ((char const *) 0 /* pool name */, 00061 0, // No need to explicitly name the lock. 00062 &the_pool_options) 00063 { 00064 } 00065 00066 TAO_MMAP_Allocator::~TAO_MMAP_Allocator (void) 00067 { 00068 } 00069 00070 // @@ Should be const but underlying allocator methods are not! 00071 ACE_HANDLE 00072 TAO_MMAP_Allocator::handle (void) 00073 { 00074 return this->alloc ().memory_pool ().mmap ().handle (); 00075 } 00076 00077 // @@ Should be const but underlying allocator methods are not! 00078 off_t 00079 TAO_MMAP_Allocator::offset (void * p) 00080 { 00081 ACE_Mem_Map const & m = this->alloc ().memory_pool ().mmap (); 00082 00083 ptrdiff_t const off = reinterpret_cast<ptrdiff_t> (p); 00084 ptrdiff_t const base = reinterpret_cast<ptrdiff_t> (m.addr ()); 00085 ptrdiff_t const end = base + m.size (); 00086 00087 // Check if p is in the range of the mmap pool, if not we return -1 00088 if (off < base || off > end) 00089 return -1; 00090 00091 off_t const the_offset = static_cast<off_t> (off - base); 00092 00093 return (the_offset < 0 ? static_cast<off_t> (-1) : the_offset); 00094 } 00095 00096 TAO_END_VERSIONED_NAMESPACE_DECL 00097 00098 #endif /* TAO_HAS_SENDFILE==1 */