Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.     Texel - A UCI chess engine.
  3.     Copyright (C) 2012-2013  Peter Ă–sterlund, peterosterlund2@gmail.com
  4.  
  5.     This program is free software: you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation, either version 3 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17. */
  18.  
  19. /*
  20.  * alignedAlloc.hpp
  21.  *
  22.  *  Created on: May 22, 2012
  23.  *      Author: petero
  24.  */
  25.  
  26. #ifndef ALIGNEDALLOC_HPP_
  27. #define ALIGNEDALLOC_HPP_
  28.  
  29. #include <cstdint>
  30.  
  31. /** STL allocator that makes sure all allocated memory
  32.  *  blocks are aligned to a 64-byte boundary. */
  33. template <typename T>
  34. class AlignedAllocator {
  35. private:
  36.     enum { ALIGN = 64 };
  37.     using U64 = uint64_t;
  38. public:
  39.     using pointer = T*;
  40.     using const_pointer = const T*;
  41.     using void_pointer = void*;
  42.     using const_void_pointer = const void*;
  43.     using reference = T&;
  44.     using const_reference = const T&;
  45.     using size_type = size_t;
  46.     using difference_type = ptrdiff_t;
  47.     using value_type = T;
  48.     template <typename U> struct rebind { using other = AlignedAllocator<U>; };
  49.  
  50.     T* allocate(size_t n) {
  51.         size_t needed_size = n*sizeof(T) + sizeof(U64) + ALIGN;
  52.         void* mem = malloc(needed_size);
  53.         if (!mem)
  54.             throw std::bad_alloc();
  55.         U64 ret = ((U64)mem) + sizeof(U64);
  56.         ret = (ret + ALIGN - 1) & ~(ALIGN - 1);
  57.         *(U64*)(ret - sizeof(U64)) = (U64)mem;
  58.         return (T*)ret;
  59.     }
  60.  
  61.     void deallocate(T* p, size_t n) {
  62.         U64 mem = *(U64*)(((U64)p) - sizeof(U64));
  63.         free((void*)mem);
  64.     }
  65.  
  66.     size_t max_size() const {
  67.         return (std::numeric_limits<size_t>::max() - ALIGN - sizeof(U64)) / sizeof(T);
  68.     }
  69.  
  70.     void construct(T* p, const T& value) {
  71.         new (p) T(value);
  72.     }
  73.  
  74.     void destroy(T* p) {
  75.         p->~T();
  76.     }
  77.  
  78.     template <typename U>
  79.     bool operator==(const AlignedAllocator<U>& other) const {
  80.         return true;
  81.     }
  82.  
  83.     template <typename U>
  84.     bool operator!=(const AlignedAllocator<U>& other) const {
  85.         return false;
  86.     }
  87. };
  88.  
  89. #endif /* ALIGNEDALLOC_HPP_ */
  90.