Ticket #3976: pool_valgrind_2.patch
File pool_valgrind_2.patch, 9.2 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 … … 194 198 explicit pool(const size_type nrequested_size, 195 199 const size_type nnext_size = 32) 196 200 :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size) 197 { } 201 { 202 #ifdef VALGRIND 203 VALGRIND_CREATE_MEMPOOL(this, 0, 0); 204 #endif // VALGRIND 205 } 198 206 199 ~pool() { purge_memory(); } 207 ~pool() { 208 purge_memory(); 209 #ifdef VALGRIND 210 VALGRIND_DESTROY_MEMPOOL(this); 211 #endif // VALGRIND 212 } 200 213 201 214 // Releases memory blocks that don't have chunks allocated 202 215 // pre: lists are ordered … … 218 231 // Returns 0 if out-of-memory 219 232 void * malloc() 220 233 { 234 void * result = 0; 221 235 // Look for a non-empty storage 222 236 if (!store().empty()) 223 return store().malloc(); 224 return malloc_need_resize(); 237 result = store().malloc(); 238 else 239 result = malloc_need_resize(); 240 #ifdef VALGRIND 241 if (result != 0) 242 VALGRIND_MEMPOOL_ALLOC(this, result, requested_size); 243 #endif // VALGRIND 244 return result; 225 245 } 226 246 227 247 void * ordered_malloc() 228 248 { 249 void * result = 0; 229 250 // Look for a non-empty storage 230 251 if (!store().empty()) 231 return store().malloc(); 232 return ordered_malloc_need_resize(); 252 result = store().malloc(); 253 else 254 result = ordered_malloc_need_resize(); 255 #ifdef VALGRIND 256 if (result != 0) 257 VALGRIND_MEMPOOL_ALLOC(this, result, requested_size); 258 #endif // VALGRIND 259 return result; 233 260 } 234 261 235 262 // Returns 0 if out-of-memory … … 239 266 // pre: 'chunk' must have been previously 240 267 // returned by *this.malloc(). 241 268 void free(void * const chunk) 242 { store().free(chunk); } 269 { 270 store().free(chunk); 271 #ifdef VALGRIND 272 VALGRIND_MEMPOOL_FREE(this, chunk); 273 #endif // VALGRIND 274 } 243 275 244 276 // pre: 'chunk' must have been previously 245 277 // returned by *this.malloc(). 246 278 void ordered_free(void * const chunk) 247 { store().ordered_free(chunk); } 279 { 280 store().ordered_free(chunk); 281 #ifdef VALGRIND 282 VALGRIND_MEMPOOL_FREE(this, chunk); 283 #endif // VALGRIND 284 } 248 285 249 286 // pre: 'chunk' must have been previously 250 287 // returned by *this.malloc(n). … … 256 293 ((total_req_size % partition_size) ? true : false); 257 294 258 295 store().free_n(chunks, num_chunks, partition_size); 296 #ifdef VALGRIND 297 VALGRIND_MEMPOOL_FREE(this, chunks); 298 #endif // VALGRIND 259 299 } 260 300 261 301 // pre: 'chunk' must have been previously … … 268 308 ((total_req_size % partition_size) ? true : false); 269 309 270 310 store().ordered_free_n(chunks, num_chunks, partition_size); 311 #ifdef VALGRIND 312 VALGRIND_MEMPOOL_FREE(this, chunks); 313 #endif // VALGRIND 271 314 } 272 315 273 316 // is_from() tests a chunk to determine if it was allocated from *this … … 421 464 } while (iter.valid()); 422 465 423 466 list.invalidate(); 424 this->first = 0; 467 BOOST_POOL_WITH_DEFINED(this->first, 468 this->first = 0; 469 ); 425 470 next_size = start_size; 426 471 472 #ifdef VALGRIND 473 VALGRIND_MEMPOOL_TRIM(this, 0, 0); 474 #endif // VALGRIND 475 427 476 return true; 428 477 } 429 478 … … 510 559 511 560 void * ret = store().malloc_n(num_chunks, partition_size); 512 561 513 if (ret != 0) 562 if (ret != 0) { 563 #ifdef VALGRIND 564 VALGRIND_MEMPOOL_ALLOC(this, ret, total_req_size); 565 #endif // VALGRIND 514 566 return ret; 567 } 515 568 516 569 // Not enougn memory in our storages; make a new storage, 517 570 BOOST_USING_STD_MAX(); … … 521 574 char * const ptr = UserAllocator::malloc(POD_size); 522 575 if (ptr == 0) 523 576 return 0; 577 578 #ifdef VALGRIND 579 VALGRIND_MAKE_MEM_NOACCESS(ptr, POD_size); 580 #endif // VALGRIND 581 524 582 const details::PODptr<size_type> node(ptr, POD_size); 525 583 526 584 // Split up block so we can use what wasn't requested … … 559 617 prev.next(node); 560 618 } 561 619 620 #ifdef VALGRIND 621 VALGRIND_MEMPOOL_ALLOC(this, node.begin(), total_req_size); 622 #endif // VALGRIND 623 562 624 // and return it. 563 625 return node.begin(); 564 626 } -
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> … … 82 95 // in the proper order 83 96 84 97 // Find where "block" would go in the free list 85 void * const loc = find_prev(block); 98 void * loc = 0; 99 BOOST_POOL_WITH_DEFINED(block, 100 BOOST_POOL_WITH_DEFINED(first, 101 loc = find_prev(block); 102 ); 103 ); 86 104 87 105 // Place either at beginning or in middle/end 88 106 if (loc == 0) 89 add_block(block, nsz, npartition_sz); 90 else 91 nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc)); 107 BOOST_POOL_WITH_DEFINED(block, 108 BOOST_POOL_WITH_DEFINED(first, 109 add_block(block, nsz, npartition_sz); 110 ); 111 ); 112 else { 113 BOOST_POOL_WITH_DEFINED(nextof(loc), 114 BOOST_POOL_WITH_DEFINED(block, 115 nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc)); 116 ); 117 ); 118 } 92 119 } 93 120 94 121 // default destructor … … 101 128 void * const ret = first; 102 129 103 130 // Increment the "first" pointer to point to the next chunk 104 first = nextof(first); 131 BOOST_POOL_WITH_DEFINED(nextof(first), 132 first = nextof(first); 133 ); 105 134 return ret; 106 135 } 107 136 … … 110 139 // post: !empty() 111 140 void free(void * const chunk) 112 141 { 113 nextof(chunk) = first; 142 BOOST_POOL_WITH_DEFINED(nextof(chunk), 143 nextof(chunk) = first; 144 ); 114 145 first = chunk; 115 146 } 116 147 … … 130 161 free(chunk); 131 162 else 132 163 { 133 nextof(chunk) = nextof(loc); 134 nextof(loc) = chunk; 164 BOOST_POOL_WITH_DEFINED(nextof(chunk), 165 BOOST_POOL_WITH_DEFINED(nextof(loc), 166 { 167 nextof(chunk) = nextof(loc); 168 nextof(loc) = chunk; 169 } 170 ); 171 ); 135 172 } 136 173 } 137 174 … … 174 211 { 175 212 // if we're about to hit the end or 176 213 // if we've found where "ptr" goes 177 if (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr)) 214 bool test = false; 215 BOOST_POOL_WITH_DEFINED(nextof(iter), 216 test = (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr)); 217 ); 218 if (test) 178 219 return iter; 179 220 180 iter = nextof(iter); 221 BOOST_POOL_WITH_DEFINED(nextof(iter), 222 iter = nextof(iter); 223 ); 181 224 } 182 225 } 183 226 … … 196 239 + ((sz - partition_sz) / partition_sz) * partition_sz; 197 240 198 241 // Set it to point to the end 199 nextof(old) = end; 242 BOOST_POOL_WITH_DEFINED(nextof(old), 243 nextof(old) = end; 244 ); 200 245 201 246 // Handle border case where sz == partition_sz (i.e., we're handling an array 202 247 // of 1 element) … … 206 251 // Iterate backwards, building a singly-linked list of pointers 207 252 for (char * iter = old - partition_sz; iter != block; 208 253 old = iter, iter -= partition_sz) 209 nextof(iter) = old; 254 BOOST_POOL_WITH_DEFINED(nextof(iter), 255 nextof(iter) = old; 256 ); 210 257 211 258 // Point the first pointer, too 212 nextof(block) = old; 259 BOOST_POOL_WITH_DEFINED(nextof(block), 260 nextof(block) = old; 261 ); 213 262 214 263 return block; 215 264 } … … 230 279 void * simple_segregated_storage<SizeType>::try_malloc_n( 231 280 void * & start, size_type n, const size_type partition_size) 232 281 { 233 void * iter = nextof(start); 282 void * iter = 0; 283 BOOST_POOL_WITH_DEFINED(nextof(start), 284 iter = nextof(start); 285 ); 234 286 while (--n != 0) 235 287 { 236 void * next = nextof(iter); 288 void * next = 0; 289 BOOST_POOL_WITH_DEFINED(nextof(iter), 290 next = nextof(iter); 291 ); 237 292 if (next != static_cast<char *>(iter) + partition_size) 238 293 { 239 294 // next == 0 (end-of-list) or non-contiguous chunk found … … 255 310 void * iter; 256 311 do 257 312 { 258 if (nextof(start) == 0) 313 bool nextof_start_is_null = false; 314 BOOST_POOL_WITH_DEFINED(nextof(start), 315 nextof_start_is_null = (nextof(start) == 0); 316 ); 317 if (nextof_start_is_null) 259 318 return 0; 260 319 iter = try_malloc_n(start, n, partition_size); 261 320 } while (iter == 0); 262 void * const ret = nextof(start); 263 nextof(start) = nextof(iter); 321 void * ret = 0; 322 BOOST_POOL_WITH_DEFINED(nextof(start), 323 BOOST_POOL_WITH_DEFINED(nextof(iter), 324 { 325 ret = nextof(start); 326 nextof(start) = nextof(iter); 327 } 328 ); 329 ); 264 330 return ret; 265 331 } 266 332