2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_MEMORY_MICHAEL_ALLOCATOR_BOUND_CHECK_H
32 #define CDSLIB_MEMORY_MICHAEL_ALLOCATOR_BOUND_CHECK_H
36 #include <cds/opt/options.h>
38 namespace cds { namespace memory { namespace michael {
45 typedef uint64_t trailer_type;
46 static const trailer_type s_BoundCheckerTrailer = 0xbadcafeedeadc0feULL;
50 trailer_size = sizeof(trailer_type) + sizeof(size_t)
53 void make_trailer( void * pStartArea, void * pEndBlock, size_t nAllocSize )
55 char * pArea = reinterpret_cast<char *>(pStartArea);
56 assert( reinterpret_cast<char *>(pEndBlock) - (pArea + nAllocSize) >= trailer_size );
58 trailer_type trailer = s_BoundCheckerTrailer;
59 memcpy( pArea + nAllocSize, &trailer, sizeof(trailer));
61 // the next assignment is correct because pBlock is at least sizeof(size_t)-byte aligned
62 assert( (reinterpret_cast<uintptr_t>(pEndBlock) & (sizeof(size_t) - 1)) == 0 );
63 *(reinterpret_cast<size_t *>( pEndBlock ) - 1) = nAllocSize;
66 bool check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
68 trailer_type trailer = s_BoundCheckerTrailer;
69 size_t nAllocSize = *(reinterpret_cast<size_t *>( pEndBlock ) - 1);
71 assert( nAllocSize < nBlockSize );
72 return nAllocSize < nBlockSize
73 && memcmp( reinterpret_cast<char *>(pStartArea) + nAllocSize, &trailer, sizeof(trailer)) == 0;
79 #if defined(CDS_DOXYGEN_INVOKED) || defined(_DEBUG)
80 /// Debug bound checker
82 This is one of value of opt::check_bounds option for Michael's \ref Heap memory allocator.
83 It is intended for debug mode only. It throws an assertion when memory bound violation is detected.
84 In release mode it is equal to <tt>opt::check_bounds<cds::opt::none> </tt>.
86 class debug_bound_checking: public details::bound_checker
89 typedef details::bound_checker base_class;
91 void check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
93 // Bound checking assertion
94 assert( base_class::check_bounds( pStartArea, pEndBlock, nBlockSize ));
100 typedef cds::opt::none debug_bound_checking;
103 /// Exception of \ref strong_bound_checking bound checker
104 class bound_checker_exception: public std::out_of_range
108 bound_checker_exception()
109 : std::out_of_range( "Memory bound checking violation" )
114 /// Exception throwing bound checker
116 This is one of value of opt::check_bounds option for Michael's \ref Heap memory allocator.
117 It is intended for debug and release mode.
118 When memory bound violation is detected
119 \li In debug mode - an assertion is raised
120 \li In release mode - an exception of type \ref bound_checker_exception is thrown
122 class strong_bound_checking: public details::bound_checker
125 typedef details::bound_checker base_class;
127 void check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
129 if ( !base_class::check_bounds( pStartArea, pEndBlock, nBlockSize )) {
130 throw bound_checker_exception();
139 template <typename BOUND_CHECKER>
140 class bound_checker_selector: public BOUND_CHECKER
142 typedef BOUND_CHECKER base_class;
145 trailer_size = base_class::trailer_size
148 void make_trailer( void * pStartArea, void * pEndBlock, size_t nAllocSize )
150 base_class::make_trailer( pStartArea, pEndBlock, nAllocSize );
153 void check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize )
155 base_class::check_bounds( pStartArea, pEndBlock, nBlockSize );
160 class bound_checker_selector<cds::opt::none>
167 void make_trailer( void * /*pStartArea*/, void * /*pEndBlock*/, size_t /*nAllocSize*/ )
170 void check_bounds( void * /*pStartArea*/, void * /*pEndBlock*/, size_t /*nBlockSize*/ )
173 } // namespace details
177 }}} // namespace cds::memory::michael
179 #endif // #ifndef CDSLIB_MEMORY_MICHAEL_ALLOCATOR_BOUND_CHECK_H