3 #ifndef __CDS_MEMORY_MICHAEL_ALLOCATOR_BOUND_CHECK_H
4 #define __CDS_MEMORY_MICHAEL_ALLOCATOR_BOUND_CHECK_H
8 #include <cds/opt/options.h>
10 namespace cds { namespace memory { namespace michael {
17 typedef atomic64u_t trailer_type;
18 static const trailer_type s_BoundCheckerTrailer = 0xbadcafeedeadc0feULL;
22 trailer_size = sizeof(trailer_type) + sizeof(size_t)
25 void make_trailer( void * pStartArea, void * pEndBlock, size_t nAllocSize )
27 char * pArea = reinterpret_cast<char *>(pStartArea);
28 assert( reinterpret_cast<char *>(pEndBlock) - (pArea + nAllocSize) >= trailer_size );
30 trailer_type trailer = s_BoundCheckerTrailer;
31 memcpy( pArea + nAllocSize, &trailer, sizeof(trailer) );
33 // the next assignment is correct because pBlock is at least sizeof(size_t)-byte aligned
34 assert( (reinterpret_cast<uptr_atomic_t>(pEndBlock) & (sizeof(size_t) - 1)) == 0 );
35 *(reinterpret_cast<size_t *>( pEndBlock ) - 1) = nAllocSize;
38 bool check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
40 trailer_type trailer = s_BoundCheckerTrailer;
41 size_t nAllocSize = *(reinterpret_cast<size_t *>( pEndBlock ) - 1);
43 assert( nAllocSize < nBlockSize );
44 return nAllocSize < nBlockSize
45 && memcmp( reinterpret_cast<char *>(pStartArea) + nAllocSize, &trailer, sizeof(trailer) ) == 0;
51 #if defined(CDS_DOXYGEN_INVOKED) || defined(_DEBUG)
52 /// Debug bound checker
54 This is one of value of opt::check_bounds option for Michael's \ref Heap memory allocator.
55 It is intended for debug mode only. It throws an assertion when memory bound violation is detected.
56 In release mode it is equal to <tt>opt::check_bounds<cds::opt::none> </tt>.
58 class debug_bound_checking: public details::bound_checker
61 typedef details::bound_checker base_class;
63 void check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
65 // Bound checking assertion
66 assert( base_class::check_bounds( pStartArea, pEndBlock, nBlockSize ) );
72 typedef cds::opt::none debug_bound_checking;
75 /// Exception of \ref strong_bound_checking bound checker
76 class bound_checker_exception: public std::out_of_range
80 bound_checker_exception()
81 : std::out_of_range( "Memory bound checking violation" )
86 /// Exception throwing bound checker
88 This is one of value of opt::check_bounds option for Michael's \ref Heap memory allocator.
89 It is intended for debug and release mode.
90 When memory bound violation is detected
91 \li In debug mode - an assertion is raised
92 \li In release mode - an exception of type \ref bound_checker_exception is thrown
94 class strong_bound_checking: public details::bound_checker
97 typedef details::bound_checker base_class;
99 void check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
101 if ( !base_class::check_bounds( pStartArea, pEndBlock, nBlockSize ) ) {
102 throw bound_checker_exception();
111 template <typename BOUND_CHECKER>
112 class bound_checker_selector: public BOUND_CHECKER
114 typedef BOUND_CHECKER base_class;
117 trailer_size = base_class::trailer_size
120 void make_trailer( void * pStartArea, void * pEndBlock, size_t nAllocSize )
122 base_class::make_trailer( pStartArea, pEndBlock, nAllocSize );
125 void check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
127 base_class::check_bounds( pStartArea, pEndBlock, nBlockSize );
132 class bound_checker_selector<cds::opt::none>
139 void make_trailer( void * /*pStartArea*/, void * /*pEndBlock*/, size_t /*nAllocSize*/ )
142 void check_bounds( void * /*pStartArea*/, void * /*pEndBlock*/, size_t /*nBlockSize*/ )
145 } // namespace details
149 }}} // namespace cds::memory::michael
151 #endif // #ifndef __CDS_MEMORY_MICHAEL_ALLOCATOR_BOUND_CHECK_H