*** pool.hpp.~1.16.~ 2006-12-04 07:03:38.000000000 -0800 --- pool.hpp 2007-02-15 11:47:00.000000000 -0800 *************** *** 287,297 **** details::PODptr prev; // This is a current & previous iterator pair over the free memory chunk list ! // Note that "prev_free" in this case does NOT point to the previous memory // chunk in the free list, but rather the last free memory chunk before the // current block. ! void * free = this->first; ! void * prev_free = 0; const size_type partition_size = alloc_size(); --- 287,297 ---- details::PODptr prev; // This is a current & previous iterator pair over the free memory chunk list ! // Note that "prev_freeptr" in this case does NOT point to the previous memory // chunk in the free list, but rather the last free memory chunk before the // current block. ! void * freeptr = this->first; ! void * prev_freeptr = 0; const size_type partition_size = alloc_size(); *************** *** 300,309 **** { // At this point: // ptr points to a valid memory block ! // free points to either: // 0 if there are no more free chunks // the first free chunk in this or some next memory block ! // prev_free points to either: // the last free chunk in some previous memory block // 0 if there is no such free chunk // prev is either: --- 300,309 ---- { // At this point: // ptr points to a valid memory block ! // freeptr points to either: // 0 if there are no more free chunks // the first free chunk in this or some next memory block ! // prev_freeptr points to either: // the last free chunk in some previous memory block // 0 if there is no such free chunk // prev is either: *************** *** 313,319 **** // If there are no more free memory chunks, then every remaining // block is allocated out to its fullest capacity, and we can't // release any more memory ! if (free == 0) return ret; // We have to check all the chunks. If they are *all* free (i.e., present --- 313,319 ---- // If there are no more free memory chunks, then every remaining // block is allocated out to its fullest capacity, and we can't // release any more memory ! if (freeptr == 0) return ret; // We have to check all the chunks. If they are *all* free (i.e., present *************** *** 321,368 **** bool all_chunks_free = true; // Iterate 'i' through all chunks in the memory block ! // if free starts in the memory block, be careful to keep it there ! void * saved_free = free; for (char * i = ptr.begin(); i != ptr.end(); i += partition_size) { // If this chunk is not free ! if (i != free) { // We won't be able to free this block all_chunks_free = false; ! // free might have travelled outside ptr ! free = saved_free; // Abort searching the chunks; we won't be able to free this // block because a chunk is not free. break; } ! // We do not increment prev_free because we are in the same block ! free = nextof(free); } ! // post: if the memory block has any chunks, free points to one of them // otherwise, our assertions above are still valid const details::PODptr next = ptr.next(); if (!all_chunks_free) { ! if (is_from(free, ptr.begin(), ptr.element_size())) { std::less lt; void * const end = ptr.end(); do { ! prev_free = free; ! free = nextof(free); ! } while (free && lt(free, end)); } // This invariant is now restored: ! // free points to the first free chunk in some next memory block, or // 0 if there is no such chunk. ! // prev_free points to the last free chunk in this memory block. // We are just about to advance ptr. Maintain the invariant: // prev is the PODptr whose next() is ptr, or !valid() --- 321,368 ---- bool all_chunks_free = true; // Iterate 'i' through all chunks in the memory block ! // if freeptr starts in the memory block, be careful to keep it there ! void * saved_freeptr = freeptr; for (char * i = ptr.begin(); i != ptr.end(); i += partition_size) { // If this chunk is not free ! if (i != freeptr) { // We won't be able to free this block all_chunks_free = false; ! // freeptr might have travelled outside ptr ! freeptr = saved_freeptr; // Abort searching the chunks; we won't be able to free this // block because a chunk is not free. break; } ! // We do not increment prev_freeptr because we are in the same block ! freeptr = nextof(freeptr); } ! // post: if the memory block has any chunks, freeptr points to one of them // otherwise, our assertions above are still valid const details::PODptr next = ptr.next(); if (!all_chunks_free) { ! if (is_from(freeptr, ptr.begin(), ptr.element_size())) { std::less lt; void * const end = ptr.end(); do { ! prev_freeptr = freeptr; ! freeptr = nextof(freeptr); ! } while (freeptr && lt(freeptr, end)); } // This invariant is now restored: ! // freeptr points to the first free chunk in some next memory block, or // 0 if there is no such chunk. ! // prev_freeptr points to the last free chunk in this memory block. // We are just about to advance ptr. Maintain the invariant: // prev is the PODptr whose next() is ptr, or !valid() *************** *** 380,389 **** list = next; // Remove all entries in the free list from this block ! if (prev_free != 0) ! nextof(prev_free) = free; else ! this->first = free; // And release memory UserAllocator::free(ptr.begin()); --- 380,389 ---- list = next; // Remove all entries in the free list from this block ! if (prev_freeptr != 0) ! nextof(prev_freeptr) = freeptr; else ! this->first = freeptr; // And release memory UserAllocator::free(ptr.begin());