Menu

Allocator.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002 *
00003 * Copyright (c) 2010 Philipp Werner <philipp.werner@st.ovgu.de>
00004 * All rights reserved.
00005 *
00006 *    Redistribution and use in source and binary forms, with or without
00007 *    modification, are permitted provided that the following conditions
00008 *    are met:
00009 *
00010 *    * Redistributions of source code must retain the above copyright
00011 *      notice, this list of conditions and the following disclaimer.
00012 *
00013 *    * Redistributions in binary form must reproduce the above copyright
00014 *      notice, this list of conditions and the following disclaimer in
00015 *      the documentation and/or other materials provided with the
00016 *      distribution.
00017 *
00018 *    * Neither the name of the copyright holders nor the names of
00019 *      contributors may be used to endorse or promote products derived
00020 *      from this software without specific prior written permission.
00021 *
00022 *
00023 *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00024 *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00025 *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00026 *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027 *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028 *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029 *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030 *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031 *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033 *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 *
00036 * $Id$
00037 *
00038 ******************************************************************************/
00039 
00040 #ifndef __ALLOCATOR_H_811BED41A54BF9__
00041 #define __ALLOCATOR_H_811BED41A54BF9__
00042 
00043 
00044 #include <stdint.h>
00045 
00046 #include "object/RawStorage.h"
00047 #include "object/PlacementNew.h"
00048 
00049 // Used for RawStorageAllocator
00050 #include "logging/singleton.h"
00051 
00052 
00091 namespace object {
00092 
00101     template <class tag, uint64_t mem_size>
00102     class RawStorageAllocator {
00103 
00104             typedef RawStorage<mem_size> ThisType;
00105         public:
00106 
00108             typedef typename ThisType::SizeT SizeT;
00109 
00110         protected:
00111 
00113             static ThisType & instance() {
00114                 return logging::detail::singleton<ThisType>::instance();
00115             }
00116 
00117         public:
00118 
00124             static uint8_t * alloc(SizeT bytes) {
00125                 return instance().alloc(bytes);
00126             }
00127 
00132             static void free(uint8_t * p) {
00133                 instance().free(p);
00134             }
00135 
00142             template <typename T>
00143             static T * alloc_array(SizeT num) {
00144                 return reinterpret_cast<T *>(alloc(sizeof(T) * num));
00145             }
00146 
00152             template <typename T>
00153             static void free_array(T * p) {
00154                 return free(reinterpret_cast<uint8_t *>(p));
00155             }
00156 
00161             template <typename T>
00162             static void destroy(T * p) {
00163                 p->~T();
00164                 free(reinterpret_cast<uint8_t *>(p));
00165             }
00166     };
00167 
00168 
00177     template <class tag, uint64_t mem_size>
00178     class OneBlockAllocator {
00179 
00180             struct Buffer {
00181                 FOR_FAMOUSO_ASSERT_ONLY(bool allocated);
00182                 uint8_t data[mem_size];
00183 
00184                 typedef typename SmallestUnsignedTypeSelector<mem_size>::type SizeT;
00185 
00186                 Buffer() FOR_FAMOUSO_ASSERT_ONLY(: allocated(false)) {
00187                 }
00188 
00189                 uint8_t * alloc(SizeT n) {
00190                     if (!n || n > mem_size)
00191                         return 0;
00192                     else {
00193                         FAMOUSO_ASSERT(!allocated);
00194                         FOR_FAMOUSO_ASSERT_ONLY(allocated = true);
00195                         return data;
00196                     }
00197                 }
00198 
00199                 void free(uint8_t *) {
00200                     FAMOUSO_ASSERT(allocated);
00201                     FOR_FAMOUSO_ASSERT_ONLY(allocated = false);
00202                 }
00203             };
00204 
00205         public:
00206 
00208             typedef typename Buffer::SizeT SizeT;
00209 
00210         protected:
00211 
00213             static Buffer & instance() {
00214                 static Buffer buffer;
00215                 return buffer;
00216             }
00217 
00218         public:
00219 
00225             static uint8_t * alloc(SizeT bytes) {
00226                 return instance().alloc(bytes);
00227             }
00228 
00233             static void free(uint8_t * p) {
00234                 instance().free(p);
00235             }
00236 
00243             template <typename T>
00244             static T * alloc_array(SizeT num) {
00245                 return reinterpret_cast<T *>(alloc(sizeof(T) * num));
00246             }
00247 
00253             template <typename T>
00254             static void free_array(T * p) {
00255                 return free(reinterpret_cast<uint8_t *>(p));
00256             }
00257 
00262             template <typename T>
00263             static void destroy(T * p) {
00264                 p->~T();
00265                 free(reinterpret_cast<uint8_t *>(p));
00266             }
00267     };
00268 
00269 #ifndef __AVR__
00270 
00274     class NewAllocator {
00275         public:
00277             typedef unsigned int SizeT;
00278 
00284             static uint8_t * alloc(SizeT bytes) {
00285                 return new(std::nothrow) uint8_t [bytes];
00286             }
00287 
00292             static void free(uint8_t * p) {
00293                 delete [] p;
00294             }
00295 
00302             template <typename T>
00303             static T * alloc_array(SizeT num) {
00304                 return reinterpret_cast<T*>(alloc(sizeof(T) * num));
00305             }
00306 
00312             template <typename T>
00313             static void free_array(T * p) {
00314                 return free(reinterpret_cast<uint8_t *>(p));
00315             }
00316 
00321             template <typename T>
00322             static void destroy(T * p) {
00323                 p->~T();
00324                 free(reinterpret_cast<uint8_t *>(p));
00325             }
00326     };
00327 #endif
00328 
00329 
00330 #ifndef DEFAULT_RAWSTORAGEALLOCATOR_MEM_SIZE
00331 
00332 #ifdef __AVR__
00333 #define DEFAULT_RAWSTORAGEALLOCATOR_MEM_SIZE 0xff
00334 #else
00335 
00343 #define DEFAULT_RAWSTORAGEALLOCATOR_MEM_SIZE 0xffff
00344 #endif
00345 
00346 #endif
00347 
00351     class DefaultRawStorageAllocatorTag;
00352 
00353 #ifdef __AVR__
00354     typedef RawStorageAllocator<DefaultRawStorageAllocatorTag, DEFAULT_RAWSTORAGEALLOCATOR_MEM_SIZE> Allocator;
00355 #else
00356 
00366     typedef NewAllocator Allocator;
00367 #endif
00368 
00369 } // namespace object
00370 
00371 
00391 template <typename tag, uint64_t mem_size>
00392 void * operator new(std::size_t size, const object::RawStorageAllocator<tag, mem_size> & allocator) throw() {
00393     return allocator.alloc(size);
00394 }
00395 
00396 
00397 #ifndef __AVR__
00398 
00417 void * operator new(std::size_t size, const object::NewAllocator & allocator) throw() {
00418     return allocator.alloc(size);
00419 }
00420 #endif
00421 
00422 
00423 #endif // __ALLOCATOR_H_811BED41A54BF9__
00424