Embedded Multicore Building Blocks V1.0.0
memory_allocation.h
1 /*
2  * Copyright (c) 2014-2017, Siemens AG. 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 are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_BASE_MEMORY_ALLOCATION_H_
28 #define EMBB_BASE_MEMORY_ALLOCATION_H_
29 
30 #include <embb/base/exceptions.h>
31 #include <embb/base/internal/config.h>
32 #include <embb/base/c/internal/unused.h>
33 #include <limits>
34 #include <cstddef>
35 
36 #include <new>
37 #include <embb/base/c/memory_allocation.h>
38 
46 namespace embb {
47 namespace base {
55 class Allocation {
56  public:
77  template<typename Type>
78  static Type* New() {
79  void* memory = embb_alloc(sizeof(Type));
80  if (memory == NULL) EMBB_THROW(NoMemoryException, "When allocating memory");
81  return new(memory) Type();
82  }
83 
84  #ifdef DOXYGEN
85 
107  template<typename Type, typename Arg1, ...>
108  static Type* New(
109  Arg1 argument1,
111  ...
112  );
113 
114 #else // DOXYGEN
115 
119  template<typename Type, typename Arg1>
120  static Type* New(Arg1 arg1) {
121  void* memory = embb_alloc(sizeof(Type));
122  if (memory == NULL) EMBB_THROW(NoMemoryException, "When allocating memory");
123  return new(memory) Type(arg1);
124  }
125 
129  template<typename Type, typename Arg1, typename Arg2>
130  static Type* New(Arg1 arg1, Arg2 arg2) {
131  void* memory = embb_alloc(sizeof(Type));
132  if (memory == NULL) EMBB_THROW(NoMemoryException, "When allocating memory");
133  return new(memory) Type(arg1, arg2);
134  }
135 
139  template<typename Type, typename Arg1, typename Arg2, typename Arg3>
140  static Type* New(Arg1 arg1, Arg2 arg2, Arg3 arg3) {
141  void* memory = embb_alloc(sizeof(Type));
142  if (memory == NULL) EMBB_THROW(NoMemoryException, "When allocating memory");
143  return new(memory) Type(arg1, arg2, arg3);
144  }
145 
149  template<typename Type, typename Arg1, typename Arg2, typename Arg3,
150  typename Arg4>
151  static Type* New(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) {
152  void* memory = embb_alloc(sizeof(Type));
153  if (memory == NULL) EMBB_THROW(NoMemoryException, "When allocating memory");
154  return new(memory) Type(arg1, arg2, arg3, arg4);
155  }
156 
160  template<typename Type, typename Arg1, typename Arg2, typename Arg3,
161  typename Arg4, typename Arg5>
162  static Type* New(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) {
163  void* memory = embb_alloc(sizeof(Type));
164  if (memory == NULL) EMBB_THROW(NoMemoryException, "When allocating memory");
165  return new(memory) Type(arg1, arg2, arg3, arg4, arg5);
166  }
167 
168 #endif // else DOXYGEN
169 
175  template<typename Type>
176  static void Delete(
177  Type* to_delete
179  ) {
180  to_delete->~Type();
181  embb_free(static_cast<void*>(to_delete));
182  }
183 
193  static size_t AllocatedBytes();
194 
217  static void* Allocate(
218  size_t size
220  );
221 
234  static void Free(
235  void * ptr
237  );
238 
273  static void* AllocateAligned(
274  size_t alignment,
276  size_t size
278  );
279 
292  static void FreeAligned(
293  void * ptr
295  );
296 
323  static void* AllocateCacheAligned(
324  size_t size
326  );
327 };
328 
341 class Allocatable {
342  public:
358  static void* operator new(
359  size_t size
361  );
362 
373  static void operator delete(
374  void* ptr,
376  size_t size
378  );
379 
408  static void* operator new[](
409  size_t size
411  );
412 
423  static void operator delete[](
424  void* ptr,
426  size_t size
428  );
429 };
430 
447  public:
463  static void* operator new(
464  size_t size
466  );
467 
476  static void operator delete(
477  void* ptr,
479  size_t size
481  );
482 
498  static void* operator new[](
499  size_t size
501  );
502 
513  static void operator delete[](
514  void* ptr,
516  size_t size
518  );
519 };
520 
521 /*
522  * Forward declaration
523  */
524 template <typename Type>
525 class Allocator;
526 
527 /*
528  * Specialization for void
529  */
530 template <>
531 class Allocator < void > {
532  public:
533  typedef void* pointer;
534  typedef const void* const_pointer;
535  typedef void value_type;
536 
537  template <typename OtherType> struct rebind {
538  typedef Allocator<OtherType> other;
539  };
540 };
541 
555 template <typename Type>
556 class Allocator {
557  public:
559  typedef size_t size_type;
560 
562  typedef ptrdiff_t difference_type;
563 
565  typedef Type* pointer;
566 
568  typedef const Type* const_pointer;
569 
571  typedef Type& reference;
572 
574  typedef const Type& const_reference;
575 
577  typedef Type value_type;
578 
582  template <typename OtherType> struct rebind {
585  };
586 
590  Allocator() throw() {}
591 
596  const Allocator&
598  ) throw() {}
599 
605  template <typename OtherType> Allocator(
606  const Allocator<OtherType>&
608  )
609  throw() {}
610 
614  ~Allocator() throw() {}
615 
623  pointer address(
624  reference x
626  ) const {
627  return &x;
628  }
629 
637  const_pointer address(
638  const_reference x
640  ) const {
641  return &x;
642  }
643 
653  pointer allocate(
654  size_type n,
656  const void* = 0
658  ) {
659  if (n > max_size())
661  "Amount of requested memory too high");
662  return reinterpret_cast<pointer>
663  (embb::base::Allocation::Allocate(n*sizeof(value_type)));
664  }
665 
672  pointer p,
674  size_type
675  ) {
677  }
678 
686  size_type max_size() const throw() {
687  return std::numeric_limits<size_type>::max() / sizeof(value_type);
688  }
689 
695  void construct(
696  pointer p,
698  const value_type& val
700  ) {
701  new(p)value_type(val);
702  }
703 
709  void destroy(
710  pointer p
712  ) {
713  EMBB_UNUSED(p);
714  p->~value_type();
715  }
716 
717  private:
718  /*
719  * \threadsafe
720  */
721  Allocator& operator=(const Allocator&);
722 };
723 
724 /*
725  * Forward declaration
726  */
727 template <typename Type>
729 
730 /*
731  * Specialization for void
732  */
733 template <>
734 class AllocatorCacheAligned < void > {
735  public:
736  typedef void* pointer;
737  typedef const void* const_pointer;
738  typedef void value_type;
739 
740  template <typename OtherType> struct rebind {
741  typedef AllocatorCacheAligned<OtherType> other;
742  };
743 };
744 
758 template< typename Type >
759 class AllocatorCacheAligned : public Allocator < Type > {
760  public:
762  typedef size_t size_type;
763 
765  typedef ptrdiff_t difference_type;
766 
768  typedef Type* pointer;
769 
771  typedef const Type* const_pointer;
772 
774  typedef Type& reference;
775 
777  typedef const Type& const_reference;
778 
780  typedef Type value_type;
781 
785  template <typename OtherType> struct rebind {
788  };
789 
793  AllocatorCacheAligned() throw() { }
794 
799  const AllocatorCacheAligned& a
801  ) throw()
802  : Allocator < Type >(a) { }
803 
809  template<typename OtherType>
813  ) throw() { }
814 
819 
829  pointer allocate(
830  size_type n,
832  const void* = 0
834  ) {
835  if (n > this->max_size())
837  "Amount of requested memory too high");
838  return reinterpret_cast<pointer>
839  (embb::base::Allocation::AllocateCacheAligned(n*sizeof(value_type)));
840  }
841 
848  pointer p,
850  size_type
851  ) {
853  }
854  // Inherit everything else.
855 };
856 
857 /*
858  * Comparison operator for Allocator objects.
859  * Not for manual use.
860  */
861 template<typename O>
862 inline bool operator==(const Allocator<O>&, const Allocator<O>&) {
863  return true;
864 }
865 
866 /*
867  * Comparison operator for Allocator objects.
868  * Not for manual use.
869  */
870 template<typename T, typename U>
871 inline bool operator==(const Allocator<T>&, const Allocator<U>&) {
872  return true;
873 }
874 
875 /*
876  * Comparison operator for Allocator objects.
877  * Not for manual use.
878  */
879 template<typename O>
880 inline bool operator!=(const Allocator<O>&, const Allocator<O>&) {
881  return false;
882 }
883 
884 /*
885  * Comparison operator for Allocator objects.
886  * Not for manual use.
887  */
888 template<typename T, typename U>
889 inline bool
890 operator!=(const Allocator<T>&, const Allocator<U>&) {
891  return false;
892 }
893 
894 /*
895  * Comparison operator for AllocatorCacheAligned objects.
896  * Not for manual use.
897  */
898 template<typename O>
899 inline bool operator==(
901  return true;
902 }
903 
904 /*
905  * Comparison operator for AllocatorCacheAligned objects.
906  * Not for manual use.
907  */
908 template<typename T, typename U>
909 inline bool operator==(
911  return true;
912 }
913 
914 /*
915  * Comparison operator for AllocatorCacheAligned objects.
916  * Not for manual use.
917  */
918 template<typename O>
919 inline bool operator!=(
921  return false;
922 }
923 
924 /*
925  * Comparison operator for AllocatorCacheAligned objects.
926  * Not for manual use.
927  */
928 template<typename T, typename U>
929 inline bool operator!=(
931  return false;
932 }
933 } // namespace base
934 } // namespace embb
935 
936 #include <embb/base/internal/memory_allocation-inl.h>
937 
938 #endif // EMBB_BASE_MEMORY_ALLOCATION_H_
Definition: lock_free_mpmc_queue.h:40
Rebind allocator to type OtherType.
Definition: memory_allocation.h:582
Allocator according to the C++ standard.
Definition: memory_allocation.h:728
void deallocate(pointer p, size_type)
Deallocates storage of destroyed elements.
Definition: memory_allocation.h:847
Indicates lack of memory necessary to allocate a resource.
Definition: exceptions.h:196
Type * pointer
Pointer to element type.
Definition: memory_allocation.h:565
Allocator< OtherType > other
Type to rebind to.
Definition: memory_allocation.h:584
AllocatorCacheAligned(const AllocatorCacheAligned< OtherType > &)
Constructs allocator object.
Definition: memory_allocation.h:810
static void Free(void *ptr)
Frees memory that has been allocated by Allocation::Allocate() for some pointer ptr.
void embb_free(void *ptr)
Frees memory that has been allocated by embb_alloc() for some pointer ptr.
Allocator(const Allocator &)
Copies allocator object.
Definition: memory_allocation.h:595
size_t size_type
Quantity of elements type.
Definition: memory_allocation.h:762
void deallocate(pointer p, size_type)
Deallocates storage of destroyed elements.
Definition: memory_allocation.h:671
static void FreeAligned(void *ptr)
Frees memory that has been allocated by Allocation::AllocateAligned() or Allocation::AllocateCacheAli...
ptrdiff_t difference_type
Difference between two pointers type.
Definition: memory_allocation.h:765
pointer allocate(size_type n, const void *=0)
Allocates but doesn&#39;t initialize storage for elements of type Type.
Definition: memory_allocation.h:653
static size_t AllocatedBytes()
Returns the total number of bytes currently allocated.
size_t size_type
Quantity of elements type.
Definition: memory_allocation.h:559
const Type * const_pointer
Pointer to constant element type.
Definition: memory_allocation.h:771
Overloaded new/delete operators.
Definition: memory_allocation.h:446
Type & reference
Reference to element type.
Definition: memory_allocation.h:571
pointer allocate(size_type n, const void *=0)
Allocates but doesn&#39;t initialize storage for elements of type Type.
Definition: memory_allocation.h:829
Rebind allocator to type OtherType.
Definition: memory_allocation.h:785
Allocator according to the C++ standard.
Definition: memory_allocation.h:525
static Type * New()
Allocates memory for an instance of type Type and default-initializes it.
Definition: memory_allocation.h:78
Type value_type
Element type.
Definition: memory_allocation.h:577
static void * Allocate(size_t size)
Allocates size bytes of memory (unaligned).
const Type & const_reference
Reference to constant element type.
Definition: memory_allocation.h:777
Type value_type
Element type.
Definition: memory_allocation.h:780
Overloaded new/delete operators.
Definition: memory_allocation.h:341
Allocator< OtherType > other
Type to rebind to.
Definition: memory_allocation.h:787
Allocator(const Allocator< OtherType > &)
Constructs allocator object.
Definition: memory_allocation.h:605
pointer address(reference x) const
Gets address of an object.
Definition: memory_allocation.h:623
void construct(pointer p, const value_type &val)
Initializes elements of allocated storage with specified value.
Definition: memory_allocation.h:695
const_pointer address(const_reference x) const
Gets address of a constant object.
Definition: memory_allocation.h:637
~Allocator()
Destructs allocator object.
Definition: memory_allocation.h:614
~AllocatorCacheAligned()
Destructs allocator object.
Definition: memory_allocation.h:818
bool operator!=(const Duration< Tick > &lhs, const Duration< Tick > &rhs)
Compares two durations (inequality).
Definition: duration.h:183
void * embb_alloc(size_t size)
Allocates size bytes of memory.
static void * AllocateAligned(size_t alignment, size_t size)
Allocates size bytes of memory with alignment alignment.
Type & reference
Reference to element type.
Definition: memory_allocation.h:774
AllocatorCacheAligned(const AllocatorCacheAligned &a)
Copies allocator object.
Definition: memory_allocation.h:798
size_type max_size() const
Allocation maximum
Definition: memory_allocation.h:686
const Type & const_reference
Reference to constant element type.
Definition: memory_allocation.h:574
static void Delete(Type *to_delete)
Destructs an instance of type Type and frees the allocated memory.
Definition: memory_allocation.h:176
AllocatorCacheAligned()
Constructs allocator object.
Definition: memory_allocation.h:793
ptrdiff_t difference_type
Difference between two pointers type.
Definition: memory_allocation.h:562
Type * pointer
Pointer to element type.
Definition: memory_allocation.h:768
Allocator()
Constructs allocator object.
Definition: memory_allocation.h:590
static void * AllocateCacheAligned(size_t size)
Allocates size bytes of cache-aligned memory.
const Type * const_pointer
Pointer to constant element type.
Definition: memory_allocation.h:568
Common (static) functionality for unaligned and aligned memory allocation.
Definition: memory_allocation.h:55
bool operator==(const Duration< Tick > &lhs, const Duration< Tick > &rhs)
Compares two durations (equality).
Definition: duration.h:166
void destroy(pointer p)
Destroys elements of initialized storage.
Definition: memory_allocation.h:709