Ticket #3976: pool_valgrind_2.patch

File pool_valgrind_2.patch, 9.2 KB (added by Jeremiah Willcock, 13 years ago)

Version of patch that removes spurious Valgrind errors in pool internals

  • boost/pool/pool.hpp

     
    3333// boost::simple_segregated_storage
    3434#include <boost/pool/simple_segregated_storage.hpp>
    3535
     36#ifdef VALGRIND
     37#include <valgrind/memcheck.h>
     38#endif // VALGRIND
     39
    3640#ifdef BOOST_NO_STDC_NAMESPACE
    3741 namespace std { using ::malloc; using ::free; }
    3842#endif
     
    194198    explicit pool(const size_type nrequested_size,
    195199        const size_type nnext_size = 32)
    196200    :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    }
    198206
    199     ~pool() { purge_memory(); }
     207    ~pool() {
     208      purge_memory();
     209#ifdef VALGRIND
     210      VALGRIND_DESTROY_MEMPOOL(this);
     211#endif // VALGRIND
     212    }
    200213
    201214    // Releases memory blocks that don't have chunks allocated
    202215    // pre: lists are ordered
     
    218231    // Returns 0 if out-of-memory
    219232    void * malloc()
    220233    {
     234      void * result = 0;
    221235      // Look for a non-empty storage
    222236      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;
    225245    }
    226246
    227247    void * ordered_malloc()
    228248    {
     249      void * result = 0;
    229250      // Look for a non-empty storage
    230251      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;
    233260    }
    234261
    235262    // Returns 0 if out-of-memory
     
    239266    // pre: 'chunk' must have been previously
    240267    //        returned by *this.malloc().
    241268    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    }
    243275
    244276    // pre: 'chunk' must have been previously
    245277    //        returned by *this.malloc().
    246278    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    }
    248285
    249286    // pre: 'chunk' must have been previously
    250287    //        returned by *this.malloc(n).
     
    256293          ((total_req_size % partition_size) ? true : false);
    257294
    258295      store().free_n(chunks, num_chunks, partition_size);
     296#ifdef VALGRIND
     297      VALGRIND_MEMPOOL_FREE(this, chunks);
     298#endif // VALGRIND
    259299    }
    260300
    261301    // pre: 'chunk' must have been previously
     
    268308          ((total_req_size % partition_size) ? true : false);
    269309
    270310      store().ordered_free_n(chunks, num_chunks, partition_size);
     311#ifdef VALGRIND
     312      VALGRIND_MEMPOOL_FREE(this, chunks);
     313#endif // VALGRIND
    271314    }
    272315
    273316    // is_from() tests a chunk to determine if it was allocated from *this
     
    421464  } while (iter.valid());
    422465
    423466  list.invalidate();
    424   this->first = 0;
     467  BOOST_POOL_WITH_DEFINED(this->first,
     468    this->first = 0;
     469  );
    425470  next_size = start_size;
    426471
     472#ifdef VALGRIND
     473  VALGRIND_MEMPOOL_TRIM(this, 0, 0);
     474#endif // VALGRIND
     475
    427476  return true;
    428477}
    429478
     
    510559
    511560  void * ret = store().malloc_n(num_chunks, partition_size);
    512561
    513   if (ret != 0)
     562  if (ret != 0) {
     563#ifdef VALGRIND
     564    VALGRIND_MEMPOOL_ALLOC(this, ret, total_req_size);
     565#endif // VALGRIND
    514566    return ret;
     567  }
    515568
    516569  // Not enougn memory in our storages; make a new storage,
    517570  BOOST_USING_STD_MAX();
     
    521574  char * const ptr = UserAllocator::malloc(POD_size);
    522575  if (ptr == 0)
    523576    return 0;
     577
     578#ifdef VALGRIND
     579  VALGRIND_MAKE_MEM_NOACCESS(ptr, POD_size);
     580#endif // VALGRIND
     581
    524582  const details::PODptr<size_type> node(ptr, POD_size);
    525583
    526584  // Split up block so we can use what wasn't requested
     
    559617    prev.next(node);
    560618  }
    561619
     620#ifdef VALGRIND
     621    VALGRIND_MEMPOOL_ALLOC(this, node.begin(), total_req_size);
     622#endif // VALGRIND
     623
    562624  //  and return it.
    563625  return node.begin();
    564626}
  • boost/pool/simple_segregated_storage.hpp

     
    1414
    1515#include <boost/pool/poolfwd.hpp>
    1616
     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
    1730namespace boost {
    1831
    1932template <typename SizeType>
     
    8295      //  in the proper order
    8396
    8497      // 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      );
    86104
    87105      // Place either at beginning or in middle/end
    88106      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      }
    92119    }
    93120
    94121    // default destructor
     
    101128      void * const ret = first;
    102129
    103130      // 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      );
    105134      return ret;
    106135    }
    107136
     
    110139    // post: !empty()
    111140    void free(void * const chunk)
    112141    {
    113       nextof(chunk) = first;
     142      BOOST_POOL_WITH_DEFINED(nextof(chunk),
     143        nextof(chunk) = first;
     144      );
    114145      first = chunk;
    115146    }
    116147
     
    130161        free(chunk);
    131162      else
    132163      {
    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        );
    135172      }
    136173    }
    137174
     
    174211  {
    175212    // if we're about to hit the end or
    176213    //  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)
    178219      return iter;
    179220
    180     iter = nextof(iter);
     221    BOOST_POOL_WITH_DEFINED(nextof(iter),
     222      iter = nextof(iter);
     223    );
    181224  }
    182225}
    183226
     
    196239      + ((sz - partition_sz) / partition_sz) * partition_sz;
    197240
    198241  // Set it to point to the end
    199   nextof(old) = end;
     242  BOOST_POOL_WITH_DEFINED(nextof(old),
     243    nextof(old) = end;
     244  );
    200245
    201246  // Handle border case where sz == partition_sz (i.e., we're handling an array
    202247  //  of 1 element)
     
    206251  // Iterate backwards, building a singly-linked list of pointers
    207252  for (char * iter = old - partition_sz; iter != block;
    208253      old = iter, iter -= partition_sz)
    209     nextof(iter) = old;
     254    BOOST_POOL_WITH_DEFINED(nextof(iter),
     255      nextof(iter) = old;
     256    );
    210257
    211258  // Point the first pointer, too
    212   nextof(block) = old;
     259  BOOST_POOL_WITH_DEFINED(nextof(block),
     260    nextof(block) = old;
     261  );
    213262
    214263  return block;
    215264}
     
    230279void * simple_segregated_storage<SizeType>::try_malloc_n(
    231280    void * & start, size_type n, const size_type partition_size)
    232281{
    233   void * iter = nextof(start);
     282  void * iter = 0;
     283  BOOST_POOL_WITH_DEFINED(nextof(start),
     284    iter = nextof(start);
     285  );
    234286  while (--n != 0)
    235287  {
    236     void * next = nextof(iter);
     288    void * next = 0;
     289    BOOST_POOL_WITH_DEFINED(nextof(iter),
     290      next = nextof(iter);
     291    );
    237292    if (next != static_cast<char *>(iter) + partition_size)
    238293    {
    239294      // next == 0 (end-of-list) or non-contiguous chunk found
     
    255310  void * iter;
    256311  do
    257312  {
    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)
    259318      return 0;
    260319    iter = try_malloc_n(start, n, partition_size);
    261320  } 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  );
    264330  return ret;
    265331}
    266332