Index: boost/pool/pool.hpp =================================================================== --- boost/pool/pool.hpp (revision 60124) +++ boost/pool/pool.hpp (working copy) @@ -33,6 +33,10 @@ // boost::simple_segregated_storage #include +#ifdef VALGRIND +#include +#endif // VALGRIND + #ifdef BOOST_NO_STDC_NAMESPACE namespace std { using ::malloc; using ::free; } #endif @@ -118,11 +122,23 @@ { return *(reinterpret_cast(ptr_next_ptr())); } PODptr next() const - { return PODptr(next_ptr(), next_size()); } + { + char* new_next_ptr = 0; + size_type new_next_size = 0; + BOOST_POOL_WITH_DEFINED(next_ptr(), new_next_ptr = next_ptr();); + BOOST_POOL_WITH_DEFINED(next_size(), new_next_size = next_size();); + return PODptr(new_next_ptr, new_next_size); + } void next(const PODptr & arg) const { - next_ptr() = arg.begin(); - next_size() = arg.total_size(); + BOOST_POOL_WITH_DEFINED(next_ptr(), + BOOST_POOL_WITH_DEFINED(next_size(), + { + next_ptr() = arg.begin(); + next_size() = arg.total_size(); + } + ); + ); } }; @@ -194,9 +210,18 @@ explicit pool(const size_type nrequested_size, const size_type nnext_size = 32) :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size) - { } + { +#ifdef VALGRIND + VALGRIND_CREATE_MEMPOOL(this, 0, 0); +#endif // VALGRIND + } - ~pool() { purge_memory(); } + ~pool() { + purge_memory(); +#ifdef VALGRIND + VALGRIND_DESTROY_MEMPOOL(this); +#endif // VALGRIND + } // Releases memory blocks that don't have chunks allocated // pre: lists are ordered @@ -218,18 +243,32 @@ // Returns 0 if out-of-memory void * malloc() { + void * result = 0; // Look for a non-empty storage if (!store().empty()) - return store().malloc(); - return malloc_need_resize(); + result = store().malloc(); + else + result = malloc_need_resize(); +#ifdef VALGRIND + if (result != 0) + VALGRIND_MEMPOOL_ALLOC(this, result, requested_size); +#endif // VALGRIND + return result; } void * ordered_malloc() { + void * result = 0; // Look for a non-empty storage if (!store().empty()) - return store().malloc(); - return ordered_malloc_need_resize(); + result = store().malloc(); + else + result = ordered_malloc_need_resize(); +#ifdef VALGRIND + if (result != 0) + VALGRIND_MEMPOOL_ALLOC(this, result, requested_size); +#endif // VALGRIND + return result; } // Returns 0 if out-of-memory @@ -239,12 +278,22 @@ // pre: 'chunk' must have been previously // returned by *this.malloc(). void free(void * const chunk) - { store().free(chunk); } + { + store().free(chunk); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(this, chunk); +#endif // VALGRIND + } // pre: 'chunk' must have been previously // returned by *this.malloc(). void ordered_free(void * const chunk) - { store().ordered_free(chunk); } + { + store().ordered_free(chunk); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(this, chunk); +#endif // VALGRIND + } // pre: 'chunk' must have been previously // returned by *this.malloc(n). @@ -256,6 +305,9 @@ ((total_req_size % partition_size) ? true : false); store().free_n(chunks, num_chunks, partition_size); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(this, chunks); +#endif // VALGRIND } // pre: 'chunk' must have been previously @@ -268,6 +320,9 @@ ((total_req_size % partition_size) ? true : false); store().ordered_free_n(chunks, num_chunks, partition_size); +#ifdef VALGRIND + VALGRIND_MEMPOOL_FREE(this, chunks); +#endif // VALGRIND } // is_from() tests a chunk to determine if it was allocated from *this @@ -421,9 +476,15 @@ } while (iter.valid()); list.invalidate(); - this->first = 0; + BOOST_POOL_WITH_DEFINED(this->first, + this->first = 0; + ); next_size = start_size; +#ifdef VALGRIND + VALGRIND_MEMPOOL_TRIM(this, 0, 0); +#endif // VALGRIND + return true; } @@ -510,8 +571,12 @@ void * ret = store().malloc_n(num_chunks, partition_size); - if (ret != 0) + if (ret != 0) { +#ifdef VALGRIND + VALGRIND_MEMPOOL_ALLOC(this, ret, total_req_size); +#endif // VALGRIND return ret; + } // Not enougn memory in our storages; make a new storage, BOOST_USING_STD_MAX(); @@ -521,6 +586,11 @@ char * const ptr = UserAllocator::malloc(POD_size); if (ptr == 0) return 0; + +#ifdef VALGRIND + VALGRIND_MAKE_MEM_NOACCESS(ptr, POD_size); +#endif // VALGRIND + const details::PODptr node(ptr, POD_size); // Split up block so we can use what wasn't requested @@ -548,8 +618,12 @@ { // if we're about to hit the end or // if we've found where "node" goes - if (prev.next_ptr() == 0 - || std::greater()(prev.next_ptr(), node.begin())) + void* prev_next_ptr = 0; + BOOST_POOL_WITH_DEFINED(prev.next_ptr(), + prev_next_ptr = prev.next_ptr(); + ); + if (prev_next_ptr == 0 + || std::greater()(prev_next_ptr, node.begin())) break; prev = prev.next(); @@ -559,6 +633,10 @@ prev.next(node); } +#ifdef VALGRIND + VALGRIND_MEMPOOL_ALLOC(this, node.begin(), total_req_size); +#endif // VALGRIND + // and return it. return node.begin(); } Index: boost/pool/simple_segregated_storage.hpp =================================================================== --- boost/pool/simple_segregated_storage.hpp (revision 60124) +++ boost/pool/simple_segregated_storage.hpp (working copy) @@ -14,6 +14,19 @@ #include +#ifdef VALGRIND +#include + +#define BOOST_POOL_WITH_DEFINED(expr, body) \ + do { \ + VALGRIND_MAKE_MEM_DEFINED(&(expr), sizeof((expr))); \ + do {body} while (0); \ + VALGRIND_MAKE_MEM_NOACCESS(&(expr), sizeof((expr))); \ + } while (0) +#else // VALGRIND +#define BOOST_POOL_WITH_DEFINED(expr, body) do {body} while (0) +#endif // !VALGRIND + namespace boost { template @@ -69,7 +82,9 @@ { // Segregate this block and merge its free list into the // free list referred to by "first" - first = segregate(block, nsz, npartition_sz, first); + BOOST_POOL_WITH_DEFINED(first, + first = segregate(block, nsz, npartition_sz, first); + ); } // Same preconditions as 'segregate' @@ -82,13 +97,27 @@ // in the proper order // Find where "block" would go in the free list - void * const loc = find_prev(block); + void * loc = 0; + BOOST_POOL_WITH_DEFINED(block, + BOOST_POOL_WITH_DEFINED(first, + loc = find_prev(block); + ); + ); // Place either at beginning or in middle/end if (loc == 0) - add_block(block, nsz, npartition_sz); - else - nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc)); + BOOST_POOL_WITH_DEFINED(block, + BOOST_POOL_WITH_DEFINED(first, + add_block(block, nsz, npartition_sz); + ); + ); + else { + BOOST_POOL_WITH_DEFINED(nextof(loc), + BOOST_POOL_WITH_DEFINED(block, + nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc)); + ); + ); + } } // default destructor @@ -101,7 +130,9 @@ void * const ret = first; // Increment the "first" pointer to point to the next chunk - first = nextof(first); + BOOST_POOL_WITH_DEFINED(nextof(first), + first = nextof(first); + ); return ret; } @@ -110,7 +141,9 @@ // post: !empty() void free(void * const chunk) { - nextof(chunk) = first; + BOOST_POOL_WITH_DEFINED(nextof(chunk), + nextof(chunk) = first; + ); first = chunk; } @@ -130,8 +163,14 @@ free(chunk); else { - nextof(chunk) = nextof(loc); - nextof(loc) = chunk; + BOOST_POOL_WITH_DEFINED(nextof(chunk), + BOOST_POOL_WITH_DEFINED(nextof(loc), + { + nextof(chunk) = nextof(loc); + nextof(loc) = chunk; + } + ); + ); } } @@ -174,10 +213,16 @@ { // if we're about to hit the end or // if we've found where "ptr" goes - if (nextof(iter) == 0 || std::greater()(nextof(iter), ptr)) + bool test = false; + BOOST_POOL_WITH_DEFINED(nextof(iter), + test = (nextof(iter) == 0 || std::greater()(nextof(iter), ptr)); + ); + if (test) return iter; - iter = nextof(iter); + BOOST_POOL_WITH_DEFINED(nextof(iter), + iter = nextof(iter); + ); } } @@ -196,7 +241,9 @@ + ((sz - partition_sz) / partition_sz) * partition_sz; // Set it to point to the end - nextof(old) = end; + BOOST_POOL_WITH_DEFINED(nextof(old), + nextof(old) = end; + ); // Handle border case where sz == partition_sz (i.e., we're handling an array // of 1 element) @@ -206,10 +253,14 @@ // Iterate backwards, building a singly-linked list of pointers for (char * iter = old - partition_sz; iter != block; old = iter, iter -= partition_sz) - nextof(iter) = old; + BOOST_POOL_WITH_DEFINED(nextof(iter), + nextof(iter) = old; + ); // Point the first pointer, too - nextof(block) = old; + BOOST_POOL_WITH_DEFINED(nextof(block), + nextof(block) = old; + ); return block; } @@ -230,10 +281,16 @@ void * simple_segregated_storage::try_malloc_n( void * & start, size_type n, const size_type partition_size) { - void * iter = nextof(start); + void * iter = 0; + BOOST_POOL_WITH_DEFINED(nextof(start), + iter = nextof(start); + ); while (--n != 0) { - void * next = nextof(iter); + void * next = 0; + BOOST_POOL_WITH_DEFINED(nextof(iter), + next = nextof(iter); + ); if (next != static_cast(iter) + partition_size) { // next == 0 (end-of-list) or non-contiguous chunk found @@ -255,12 +312,23 @@ void * iter; do { - if (nextof(start) == 0) + bool nextof_start_is_null = false; + BOOST_POOL_WITH_DEFINED(nextof(start), + nextof_start_is_null = (nextof(start) == 0); + ); + if (nextof_start_is_null) return 0; iter = try_malloc_n(start, n, partition_size); } while (iter == 0); - void * const ret = nextof(start); - nextof(start) = nextof(iter); + void * ret = 0; + BOOST_POOL_WITH_DEFINED(nextof(start), + BOOST_POOL_WITH_DEFINED(nextof(iter), + { + ret = nextof(start); + nextof(start) = nextof(iter); + } + ); + ); return ret; }