Sierra Toolkit  Version of the Day
fixed_allocator_eastl.h
1 /*
2 Copyright (C) 2009-2010 Electronic Arts, Inc. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 
8 1. Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11  notice, this list of conditions and the following disclaimer in the
12  documentation and/or other materials provided with the distribution.
13 3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
14  its contributors may be used to endorse or promote products derived
15  from this software without specific prior written permission.
16 
17 THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
30 // EASTL/fixed_allocator.h
31 //
32 // Copyright (c) 2005, Electronic Arts. All rights reserved.
33 // Written and maintained by Paul Pedriana.
35 
37 // This file implements the following
38 // fixed_allocator
39 // fixed_allocator_with_overflow
41 
42 
43 #ifndef EASTL_FIXED_ALLOCATOR_H
44 #define EASTL_FIXED_ALLOCATOR_H
45 
46 
47 #include <stk_util/util/config_eastl.h>
48 #include <stk_util/util/fixed_pool_eastl.h>
49 #include <stk_util/util/functional_eastl.h>
50 #include <stk_util/util/memory_eastl.h>
51 #include <stk_util/util/allocator_eastl.h>
52 #include <stk_util/util/type_traits_eastl.h>
53 
54 #ifdef _MSC_VER
55  #pragma warning(push, 0)
56  #include <new>
57  #pragma warning(pop)
58 #else
59  #include <new>
60 #endif
61 
62 
63 namespace eastl
64 {
65 
67  // fixed_allocator
69 
109  class EASTL_API fixed_allocator : public fixed_pool_base
110  {
111  public:
117  fixed_allocator(const char* /*pName*/ = EASTL_FIXED_POOL_DEFAULT_NAME)
118  : fixed_pool_base(NULL)
119  {
120  }
121 
122 
131  : fixed_pool_base(NULL)
132  {
133  }
134 
135 
143  {
144  return *this;
145  }
146 
147 
148  // init
149  //
150  // No init here, as the base class version is sufficient.
151  //
152  //void init(void* pMemory, size_t memorySize, size_t nodeSize,
153  // size_t alignment, size_t alignmentOffset = 0);
154 
155 
161  void* allocate(size_t /*n*/, int /*flags*/ = 0)
162  {
163  // To consider: Verify that 'n' is what the user initialized us with.
164 
165  Link* pLink = mpHead;
166 
167  if(pLink) // If we have space...
168  {
169  #if EASTL_FIXED_SIZE_TRACKING_ENABLED
170  if(++mnCurrentSize > mnPeakSize)
171  mnPeakSize = mnCurrentSize;
172  #endif
173 
174  mpHead = pLink->mpNext;
175  return pLink;
176  }
177  else
178  {
179  // If there's no free node in the free list, just
180  // allocate another from the reserved memory area
181 
182  if(mpNext != mpCapacity)
183  {
184  pLink = mpNext;
185 
186  mpNext = reinterpret_cast<Link*>(reinterpret_cast<char8_t*>(mpNext) + mnNodeSize);
187 
188  #if EASTL_FIXED_SIZE_TRACKING_ENABLED
189  if(++mnCurrentSize > mnPeakSize)
190  mnPeakSize = mnCurrentSize;
191  #endif
192 
193  return pLink;
194  }
195 
196  // EASTL_ASSERT(false); To consider: enable this assert. However, we intentionally disable it because this isn't necessarily an assertable error.
197  return NULL;
198  }
199  }
200 
201 
204  void* allocate(size_t n, size_t /*alignment*/, size_t /*offset*/, int flags = 0)
205  {
206  return allocate(n, flags);
207  }
208 
209 
216  void deallocate(void* p, size_t)
217  {
218  #if EASTL_FIXED_SIZE_TRACKING_ENABLED
219  --mnCurrentSize;
220  #endif
221 
222  ((Link*)p)->mpNext = mpHead;
223  mpHead = ((Link*)p);
224  }
225 
226 
228 
229 
230  const char* get_name() const
231  {
232  return EASTL_FIXED_POOL_DEFAULT_NAME;
233  }
234 
235 
236  void set_name(const char*)
237  {
238  // Nothing to do. We don't allocate memory.
239  }
240 
241  }; // fixed_allocator
242 
243  bool operator==(const fixed_allocator& a, const fixed_allocator& b);
244  bool operator!=(const fixed_allocator& a, const fixed_allocator& b);
245 
246 
247 
249  // fixed_allocator_with_overflow
251 
288  {
289  public:
295  fixed_allocator_with_overflow(const char* pName = EASTL_FIXED_POOL_DEFAULT_NAME)
296  : fixed_pool_base(NULL),
297  mOverflowAllocator(pName)
298  {
299  }
300 
301 
310  : fixed_pool_base(NULL)
311  {
312  }
313 
314 
322  {
323  #if EASTL_ALLOCATOR_COPY_ENABLED
324  mOverflowAllocator = x.mOverflowAllocator;
325  #else
326  (void)x;
327  #endif
328 
329  return *this;
330  }
331 
332 
335  void init(void* pMemory, size_t memorySize, size_t nodeSize,
336  size_t alignment, size_t alignmentOffset = 0)
337  {
338  fixed_pool_base::init(pMemory, memorySize, nodeSize, alignment, alignmentOffset);
339 
340  mpPoolBegin = pMemory;
341  mpPoolEnd = (void*)((uintptr_t)pMemory + memorySize);
342  mnNodeSize = (eastl_size_t)nodeSize;
343  }
344 
345 
351  void* allocate(size_t /*n*/, int /*flags*/ = 0)
352  {
353  // To consider: Verify that 'n' is what the user initialized us with.
354 
355  void* p;
356 
357  if(mpHead) // If we have space...
358  {
359  p = mpHead;
360  mpHead = mpHead->mpNext;
361  }
362  else
363  p = mOverflowAllocator.allocate(mnNodeSize);
364 
365  #if EASTL_FIXED_SIZE_TRACKING_ENABLED
366  if(p && (++mnCurrentSize > mnPeakSize))
367  mnPeakSize = mnCurrentSize;
368  #endif
369 
370  return p;
371  }
372 
373 
376  void* allocate(size_t n, size_t /*alignment*/, size_t /*offset*/, int flags = 0)
377  {
378  return allocate(n, flags);
379  }
380 
381 
388  void deallocate(void* p, size_t)
389  {
390  #if EASTL_FIXED_SIZE_TRACKING_ENABLED
391  --mnCurrentSize;
392  #endif
393 
394  if((p >= mpPoolBegin) && (p < mpPoolEnd))
395  {
396  ((Link*)p)->mpNext = mpHead;
397  mpHead = ((Link*)p);
398  }
399  else
400  mOverflowAllocator.deallocate(p, (size_t)mnNodeSize);
401  }
402 
403 
405 
406 
407  const char* get_name() const
408  {
409  return mOverflowAllocator.get_name();
410  }
411 
412 
413  void set_name(const char* pName)
414  {
415  mOverflowAllocator.set_name(pName);
416  }
417 
418  protected:
419  EASTLAllocatorType mOverflowAllocator; // To consider: Allow the user to define the type of this, presumably via a template parameter.
420  void* mpPoolBegin; // To consider: We have these member variables and ideally we shouldn't need them. The problem is that
421  void* mpPoolEnd; // the information about the pool buffer and object size is stored in the owning container
422  eastl_size_t mnNodeSize; // and we can't have access to it without increasing the amount of code we need and by templating
423  // more code. It may turn out that simply storing data here is smaller in the end.
424  }; // fixed_allocator_with_overflow // Granted, this class is usually used for debugging purposes, but perhaps there is an elegant solution.
425 
426  bool operator==(const fixed_allocator_with_overflow& a, const fixed_allocator_with_overflow& b);
427  bool operator!=(const fixed_allocator_with_overflow& a, const fixed_allocator_with_overflow& b);
428 
429 
430 
431 
432 
433 
435  // global operators
437 
438  inline bool operator==(const fixed_allocator&, const fixed_allocator&)
439  {
440  return false;
441  }
442 
443  inline bool operator!=(const fixed_allocator&, const fixed_allocator&)
444  {
445  return false;
446  }
447 
448  inline bool operator==(const fixed_allocator_with_overflow&, const fixed_allocator_with_overflow&)
449  {
450  return false;
451  }
452 
453  inline bool operator!=(const fixed_allocator_with_overflow&, const fixed_allocator_with_overflow&)
454  {
455  return false;
456  }
457 
458 
459 } // namespace eastl
460 
461 
462 
463 
464 #endif // Header include guard
void deallocate(void *p, size_t)
fixed_allocator_with_overflow(const char *pName=EASTL_FIXED_POOL_DEFAULT_NAME)
fixed_allocator(const char *=EASTL_FIXED_POOL_DEFAULT_NAME)
void * allocate(size_t n, size_t, size_t, int flags=0)
fixed_allocator_with_overflow & operator=(const fixed_allocator_with_overflow &x)
fixed_allocator(const fixed_allocator &)
fixed_allocator & operator=(const fixed_allocator &)
void * allocate(size_t n, size_t, size_t, int flags=0)
fixed_allocator_with_overflow(const fixed_allocator_with_overflow &)
void init(void *pMemory, size_t memorySize, size_t nodeSize, size_t alignment, size_t alignmentOffset=0)
EA Standard Template Library.
void init(void *pMemory, size_t memorySize, size_t nodeSize, size_t alignment, size_t alignmentOffset=0)
void * allocate(size_t, int=0)