Protium
Math and Design Features
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
SmallObjectAllocator.cxx
Go to the documentation of this file.
3 
4 inline std::size_t GetOffset( std::size_t numBytes, std::size_t alignment ){
5  return ( numBytes + alignment-1 ) / alignment;
6 }
7 
8 void * DefaultAllocator( std::size_t numBytes, bool doThrow ){
9  return doThrow ? ::operator new( numBytes ) : ::operator new( numBytes, std::nothrow_t() );
10 }
11 
12 void DefaultDeallocator( void * p ){
13  ::operator delete( p );
14 }
15 
17  std::size_t maxObjectSize, std::size_t objectAlignSize ) :
18  fPool( NULL ),
19  fMaxObjectSize( maxObjectSize ),
20  fAlignSize( objectAlignSize ){
21 
22  assert( 0 != objectAlignSize );
23  const std::size_t allocCount = GetOffset( maxObjectSize, objectAlignSize );
24  fPool = new FixedAllocator[ allocCount ];
25  for ( std::size_t i = 0; i < allocCount; ++i )
26  fPool[ i ].Initialize( ( i+1 ) * objectAlignSize, pageSize );
27 }
28 
30  delete [] fPool;
31 }
32 
34  bool found = false;
35  const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
36  std::size_t i = 0;
37  for ( ; i < allocCount; ++i )
38  found or_eq fPool[i].TrimEmptyChunk();
39  for ( i = 0; i < allocCount; ++i )
40  found or_eq fPool[i].TrimChunkList();
41  return found;
42 }
43 
44 void* Protium::Allocation::SmallObjectAllocatorImplementation::Allocate( std::size_t numBytes, bool doThrow ){
45  if ( numBytes > GetMaxObjectSize() )
46  return DefaultAllocator( numBytes, doThrow );
47 
48  assert( fPool != NULL );
49  if ( numBytes == 0 ) numBytes = 1;
50  const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
51  const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
52  (void) allocCount;
53  assert( allocCount > index );
54 
55  FixedAllocator& allocator = fPool[ index ];
56  assert( allocator.BlockSize() >= numBytes );
57  assert( allocator.BlockSize() < numBytes + GetAlignment() );
58  void* place = allocator.Allocate();
59 
60  if ( ( place == NULL ) && TrimExcessMemory() )
61  place = allocator.Allocate();
62 
63  if ( ( place == NULL ) && doThrow )
64  throw std::bad_alloc();
65  return place;
66 }
67 
69  if ( p == NULL ) return;
70  if ( numBytes > GetMaxObjectSize() ){
71  DefaultDeallocator( p );
72  return;
73  }
74 
75  assert( fPool != NULL );
76  if ( numBytes ==0 ) numBytes = 1;
77  const std::size_t index = GetOffset( numBytes, GetAlignment() ) - 1;
78  const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
79  (void) allocCount;
80  assert( index < allocCount );
81  FixedAllocator & allocator = fPool[ index ];
82  assert( allocator.BlockSize() >= numBytes );
83  assert( allocator.BlockSize() < numBytes + GetAlignment() );
84  const bool found = allocator.Deallocate( p, NULL );
85  (void) found;
86  assert( found );
87 }
88 
90  if ( p == NULL ) return;
91  assert( fPool != NULL );
92  const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
93  Chunk * chunk = NULL;
94  FixedAllocator * pAllocator = NULL;
95 
96  for ( std::size_t ii = 0; ii < allocCount; ++ii ) {
97  chunk = fPool[ ii ].HasBlock( p );
98  if ( chunk != NULL ){
99  pAllocator = &fPool[ ii ];
100  break;
101  }
102  }
103  if ( pAllocator == NULL ){
104  DefaultDeallocator( p );
105  return;
106  }
107 
108  assert( NULL != chunk );
109  const bool found = pAllocator->Deallocate( p, chunk );
110  (void) found;
111  assert( found );
112 }
113 
114 
116  if ( fPool == NULL ){
117  assert( false );
118  return true;
119  }
120  if ( 0 == GetAlignment() ) {
121  assert( false );
122  return true;
123  }
124  if ( 0 == GetMaxObjectSize() ) {
125  assert( false );
126  return true;
127  }
128  const std::size_t allocCount = GetOffset( GetMaxObjectSize(), GetAlignment() );
129  for ( std::size_t ii = 0; ii < allocCount; ++ii ){
130  if ( fPool[ ii ].IsCorrupt() )
131  return true;
132  }
133  return false;
134 }
Pool of allocation chunks.
std::size_t GetOffset(std::size_t numBytes, std::size_t alignment)
bool HasBlock(void *p, std::size_t chunkLength) const
Checks if this block belongs to this chunk.
Definition: Chunk.h:54
void * DefaultAllocator(std::size_t numBytes, bool doThrow)
bool Deallocate(void *p, Chunk *hint)
Represents a fixed number of blocks.
Definition: Chunk.h:16
void DefaultDeallocator(void *p)
std::size_t BlockSize() const
Returns block size with which the FixedAllocator was initialized.