Ticket #3976: pool_valgrind_3.patch
File pool_valgrind_3.patch, 10.8 KB (added by , 13 years ago) |
---|
-
boost/pool/pool.hpp
33 33 // boost::simple_segregated_storage 34 34 #include <boost/pool/simple_segregated_storage.hpp> 35 35 36 #ifdef VALGRIND 37 #include <valgrind/memcheck.h> 38 #endif // VALGRIND 39 36 40 #ifdef BOOST_NO_STDC_NAMESPACE 37 41 namespace std { using ::malloc; using ::free; } 38 42 #endif … … 118 122 { return *(reinterpret_cast<char **>(ptr_next_ptr())); } 119 123 120 124 PODptr next() const 121 { return PODptr<size_type>(next_ptr(), next_size()); } 125 { 126 char* new_next_ptr = 0; 127 size_type new_next_size = 0; 128 BOOST_POOL_WITH_DEFINED(next_ptr(), new_next_ptr = next_ptr();); 129 BOOST_POOL_WITH_DEFINED(next_size(), new_next_size = next_size();); 130 return PODptr<size_type>(new_next_ptr, new_next_size); 131 } 122 132 void next(const PODptr & arg) const 123 133 { 124 next_ptr() = arg.begin(); 125 next_size() = arg.total_size(); 134 BOOST_POOL_WITH_DEFINED(next_ptr(), 135 BOOST_POOL_WITH_DEFINED(next_size(), 136 { 137 next_ptr() = arg.begin(); 138 next_size() = arg.total_size(); 139 } 140 ); 141 ); 126 142 } 127 143 }; 128 144 … … 194 210 explicit pool(const size_type nrequested_size, 195 211 const size_type nnext_size = 32) 196 212 :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size) 197 { } 213 { 214 #ifdef VALGRIND 215 VALGRIND_CREATE_MEMPOOL(this, 0, 0); 216 #endif // VALGRIND 217 } 198 218 199 ~pool() { purge_memory(); } 219 ~pool() { 220 purge_memory(); 221 #ifdef VALGRIND 222 VALGRIND_DESTROY_MEMPOOL(this); 223 #endif // VALGRIND 224 } 200 225 201 226 // Releases memory blocks that don't have chunks allocated 202 227 // pre: lists are ordered … … 218 243 // Returns 0 if out-of-memory 219 244 void * malloc() 220 245 { 246 void * result = 0; 221 247 // Look for a non-empty storage 222 248 if (!store().empty()) 223 return store().malloc(); 224 return malloc_need_resize(); 249 result = store().malloc(); 250 else 251 result = malloc_need_resize(); 252 #ifdef VALGRIND 253 if (result != 0) 254 VALGRIND_MEMPOOL_ALLOC(this, result, requested_size); 255 #endif // VALGRIND 256 return result; 225 257 } 226 258 227 259 void * ordered_malloc() 228 260 { 261 void * result = 0; 229 262 // Look for a non-empty storage 230 263 if (!store().empty()) 231 return store().malloc(); 232 return ordered_malloc_need_resize(); 264 result = store().malloc(); 265 else 266 result = ordered_malloc_need_resize(); 267 #ifdef VALGRIND 268 if (result != 0) 269 VALGRIND_MEMPOOL_ALLOC(this, result, requested_size); 270 #endif // VALGRIND 271 return result; 233 272 } 234 273 235 274 // Returns 0 if out-of-memory … … 239 278 // pre: 'chunk' must have been previously 240 279 // returned by *this.malloc(). 241 280 void free(void * const chunk) 242 { store().free(chunk); } 281 { 282 store().free(chunk); 283 #ifdef VALGRIND 284 VALGRIND_MEMPOOL_FREE(this, chunk); 285 #endif // VALGRIND 286 } 243 287 244 288 // pre: 'chunk' must have been previously 245 289 // returned by *this.malloc(). 246 290 void ordered_free(void * const chunk) 247 { store().ordered_free(chunk); } 291 { 292 store().ordered_free(chunk); 293 #ifdef VALGRIND 294 VALGRIND_MEMPOOL_FREE(this, chunk); 295 #endif // VALGRIND 296 } 248 297 249 298 // pre: 'chunk' must have been previously 250 299 // returned by *this.malloc(n). … … 256 305 ((total_req_size % partition_size) ? true : false); 257 306 258 307 store().free_n(chunks, num_chunks, partition_size); 308 #ifdef VALGRIND 309 VALGRIND_MEMPOOL_FREE(this, chunks); 310 #endif // VALGRIND 259 311 } 260 312 261 313 // pre: 'chunk' must have been previously … … 268 320 ((total_req_size % partition_size) ? true : false); 269 321 270 322 store().ordered_free_n(chunks, num_chunks, partition_size); 323 #ifdef VALGRIND 324 VALGRIND_MEMPOOL_FREE(this, chunks); 325 #endif // VALGRIND 271 326 } 272 327 273 328 // is_from() tests a chunk to determine if it was allocated from *this … … 421 476 } while (iter.valid()); 422 477 423 478 list.invalidate(); 424 this->first = 0; 479 BOOST_POOL_WITH_DEFINED(this->first, 480 this->first = 0; 481 ); 425 482 next_size = start_size; 426 483 484 #ifdef VALGRIND 485 VALGRIND_MEMPOOL_TRIM(this, 0, 0); 486 #endif // VALGRIND 487 427 488 return true; 428 489 } 429 490 … … 510 571 511 572 void * ret = store().malloc_n(num_chunks, partition_size); 512 573 513 if (ret != 0) 574 if (ret != 0) { 575 #ifdef VALGRIND 576 VALGRIND_MEMPOOL_ALLOC(this, ret, total_req_size); 577 #endif // VALGRIND 514 578 return ret; 579 } 515 580 516 581 // Not enougn memory in our storages; make a new storage, 517 582 BOOST_USING_STD_MAX(); … … 521 586 char * const ptr = UserAllocator::malloc(POD_size); 522 587 if (ptr == 0) 523 588 return 0; 589 590 #ifdef VALGRIND 591 VALGRIND_MAKE_MEM_NOACCESS(ptr, POD_size); 592 #endif // VALGRIND 593 524 594 const details::PODptr<size_type> node(ptr, POD_size); 525 595 526 596 // Split up block so we can use what wasn't requested … … 548 618 { 549 619 // if we're about to hit the end or 550 620 // if we've found where "node" goes 551 if (prev.next_ptr() == 0 552 || std::greater<void *>()(prev.next_ptr(), node.begin())) 621 void* prev_next_ptr = 0; 622 BOOST_POOL_WITH_DEFINED(prev.next_ptr(), 623 prev_next_ptr = prev.next_ptr(); 624 ); 625 if (prev_next_ptr == 0 626 || std::greater<void *>()(prev_next_ptr, node.begin())) 553 627 break; 554 628 555 629 prev = prev.next(); … … 559 633 prev.next(node); 560 634 } 561 635 636 #ifdef VALGRIND 637 VALGRIND_MEMPOOL_ALLOC(this, node.begin(), total_req_size); 638 #endif // VALGRIND 639 562 640 // and return it. 563 641 return node.begin(); 564 642 } -
boost/pool/simple_segregated_storage.hpp
14 14 15 15 #include <boost/pool/poolfwd.hpp> 16 16 17 #ifdef VALGRIND 18 #include <valgrind/memcheck.h> 19 20 #define BOOST_POOL_WITH_DEFINED(expr, body) \ 21 do { \ 22 VALGRIND_MAKE_MEM_DEFINED(&(expr), sizeof((expr))); \ 23 do {body} while (0); \ 24 VALGRIND_MAKE_MEM_NOACCESS(&(expr), sizeof((expr))); \ 25 } while (0) 26 #else // VALGRIND 27 #define BOOST_POOL_WITH_DEFINED(expr, body) do {body} while (0) 28 #endif // !VALGRIND 29 17 30 namespace boost { 18 31 19 32 template <typename SizeType> … … 69 82 { 70 83 // Segregate this block and merge its free list into the 71 84 // free list referred to by "first" 72 first = segregate(block, nsz, npartition_sz, first); 85 BOOST_POOL_WITH_DEFINED(first, 86 first = segregate(block, nsz, npartition_sz, first); 87 ); 73 88 } 74 89 75 90 // Same preconditions as 'segregate' … … 82 97 // in the proper order 83 98 84 99 // Find where "block" would go in the free list 85 void * const loc = find_prev(block); 100 void * loc = 0; 101 BOOST_POOL_WITH_DEFINED(block, 102 BOOST_POOL_WITH_DEFINED(first, 103 loc = find_prev(block); 104 ); 105 ); 86 106 87 107 // Place either at beginning or in middle/end 88 108 if (loc == 0) 89 add_block(block, nsz, npartition_sz); 90 else 91 nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc)); 109 BOOST_POOL_WITH_DEFINED(block, 110 BOOST_POOL_WITH_DEFINED(first, 111 add_block(block, nsz, npartition_sz); 112 ); 113 ); 114 else { 115 BOOST_POOL_WITH_DEFINED(nextof(loc), 116 BOOST_POOL_WITH_DEFINED(block, 117 nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc)); 118 ); 119 ); 120 } 92 121 } 93 122 94 123 // default destructor … … 101 130 void * const ret = first; 102 131 103 132 // Increment the "first" pointer to point to the next chunk 104 first = nextof(first); 133 BOOST_POOL_WITH_DEFINED(nextof(first), 134 first = nextof(first); 135 ); 105 136 return ret; 106 137 } 107 138 … … 110 141 // post: !empty() 111 142 void free(void * const chunk) 112 143 { 113 nextof(chunk) = first; 144 BOOST_POOL_WITH_DEFINED(nextof(chunk), 145 nextof(chunk) = first; 146 ); 114 147 first = chunk; 115 148 } 116 149 … … 130 163 free(chunk); 131 164 else 132 165 { 133 nextof(chunk) = nextof(loc); 134 nextof(loc) = chunk; 166 BOOST_POOL_WITH_DEFINED(nextof(chunk), 167 BOOST_POOL_WITH_DEFINED(nextof(loc), 168 { 169 nextof(chunk) = nextof(loc); 170 nextof(loc) = chunk; 171 } 172 ); 173 ); 135 174 } 136 175 } 137 176 … … 174 213 { 175 214 // if we're about to hit the end or 176 215 // if we've found where "ptr" goes 177 if (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr)) 216 bool test = false; 217 BOOST_POOL_WITH_DEFINED(nextof(iter), 218 test = (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr)); 219 ); 220 if (test) 178 221 return iter; 179 222 180 iter = nextof(iter); 223 BOOST_POOL_WITH_DEFINED(nextof(iter), 224 iter = nextof(iter); 225 ); 181 226 } 182 227 } 183 228 … … 196 241 + ((sz - partition_sz) / partition_sz) * partition_sz; 197 242 198 243 // Set it to point to the end 199 nextof(old) = end; 244 BOOST_POOL_WITH_DEFINED(nextof(old), 245 nextof(old) = end; 246 ); 200 247 201 248 // Handle border case where sz == partition_sz (i.e., we're handling an array 202 249 // of 1 element) … … 206 253 // Iterate backwards, building a singly-linked list of pointers 207 254 for (char * iter = old - partition_sz; iter != block; 208 255 old = iter, iter -= partition_sz) 209 nextof(iter) = old; 256 BOOST_POOL_WITH_DEFINED(nextof(iter), 257 nextof(iter) = old; 258 ); 210 259 211 260 // Point the first pointer, too 212 nextof(block) = old; 261 BOOST_POOL_WITH_DEFINED(nextof(block), 262 nextof(block) = old; 263 ); 213 264 214 265 return block; 215 266 } … … 230 281 void * simple_segregated_storage<SizeType>::try_malloc_n( 231 282 void * & start, size_type n, const size_type partition_size) 232 283 { 233 void * iter = nextof(start); 284 void * iter = 0; 285 BOOST_POOL_WITH_DEFINED(nextof(start), 286 iter = nextof(start); 287 ); 234 288 while (--n != 0) 235 289 { 236 void * next = nextof(iter); 290 void * next = 0; 291 BOOST_POOL_WITH_DEFINED(nextof(iter), 292 next = nextof(iter); 293 ); 237 294 if (next != static_cast<char *>(iter) + partition_size) 238 295 { 239 296 // next == 0 (end-of-list) or non-contiguous chunk found … … 255 312 void * iter; 256 313 do 257 314 { 258 if (nextof(start) == 0) 315 bool nextof_start_is_null = false; 316 BOOST_POOL_WITH_DEFINED(nextof(start), 317 nextof_start_is_null = (nextof(start) == 0); 318 ); 319 if (nextof_start_is_null) 259 320 return 0; 260 321 iter = try_malloc_n(start, n, partition_size); 261 322 } while (iter == 0); 262 void * const ret = nextof(start); 263 nextof(start) = nextof(iter); 323 void * ret = 0; 324 BOOST_POOL_WITH_DEFINED(nextof(start), 325 BOOST_POOL_WITH_DEFINED(nextof(iter), 326 { 327 ret = nextof(start); 328 nextof(start) = nextof(iter); 329 } 330 ); 331 ); 264 332 return ret; 265 333 } 266 334