bool did_alloc(void* p) const { unique_lock_type ul(mtx_); for (const_iterator it = heap_list_.begin(); it != heap_list_.end(); ++it) { typename list_type::value_type heap = *it; bool did_allocate = false; { util::scoped_unlock<unique_lock_type> ull(ul); did_allocate = heap->did_alloc(p); } if (did_allocate) return true; } return false; }
void free(void* p, std::size_t count = 1) { unique_lock_type ul(mtx_); if (NULL == p || !threads::threadmanager_is(running)) return; // if this is called from outside a HPX thread we need to // re-schedule the request if (reschedule(p, count)) return; // Find the heap which allocated this pointer. for (iterator it = heap_list_.begin(); it != heap_list_.end(); ++it) { typename list_type::value_type heap = *it; bool did_allocate = false; { util::scoped_unlock<unique_lock_type> ull(ul); did_allocate = heap->did_alloc(p); if (did_allocate) heap->free(p, count); } if (did_allocate) { #if defined(HPX_DEBUG) free_count_ += count; #endif return; } } HPX_THROW_EXCEPTION(bad_parameter, name() + "::free", boost::str(boost::format( "pointer %1% was not allocated by this %2%") % p % name())); }
// operations void* alloc(std::size_t count = 1) { unique_lock_type guard(mtx_); if (HPX_UNLIKELY(0 == count)) { HPX_THROW_EXCEPTION(bad_parameter, name() + "::alloc", "cannot allocate 0 objects"); } //std::size_t size = 0; value_type* p = NULL; { if (!heap_list_.empty()) { //size = heap_list_.size(); for (iterator it = heap_list_.begin(); it != heap_list_.end(); ++it) { typename list_type::value_type heap = *it; bool allocated = false; { util::scoped_unlock<unique_lock_type> ul(guard); allocated = heap->alloc(&p, count); } if (allocated) { #if defined(HPX_DEBUG) // Allocation succeeded, update statistics. alloc_count_ += count; if (alloc_count_ - free_count_ > max_alloc_count_) max_alloc_count_ = alloc_count_- free_count_; #endif return p; } #if defined(HPX_DEBUG) LOSH_(info) << (boost::format( "%1%::alloc: failed to allocate from heap[%2%] " "(heap[%2%] has allocated %3% objects and has " "space for %4% more objects)") % name() % (*it)->heap_count_ % (*it)->size() % (*it)->free_size()); #endif } } } // Create new heap. bool did_create = false; { #if defined(HPX_DEBUG) heap_list_.push_front(typename list_type::value_type( new heap_type(class_name_.c_str(), heap_count_ + 1, heap_step))); #else heap_list_.push_front(typename list_type::value_type( new heap_type(class_name_.c_str(), 0, heap_step))); #endif iterator itnew = heap_list_.begin(); typename list_type::value_type heap = *itnew; bool result = false; { util::scoped_unlock<unique_lock_type> ul(guard); result = heap->alloc(&p, count); } if (HPX_UNLIKELY(!result || NULL == p)) { // out of memory HPX_THROW_EXCEPTION(out_of_memory, name() + "::alloc", boost::str(boost::format( "new heap failed to allocate %1% objects") % count)); } #if defined(HPX_DEBUG) alloc_count_ += count; ++heap_count_; LOSH_(info) << (boost::format( "%1%::alloc: creating new heap[%2%], size is now %3%") % name() % heap_count_ % heap_list_.size()); #endif did_create = true; } if (did_create) return p; guard.unlock(); // Try again, we just got a new heap, so we should be good. return alloc(count); }
void* one_size_heap_list::alloc(std::size_t count) { unique_lock_type guard(mtx_); if (HPX_UNLIKELY(0 == count)) { guard.unlock(); HPX_THROW_EXCEPTION(bad_parameter, name() + "::alloc", "cannot allocate 0 objects"); } //std::size_t size = 0; void* p = nullptr; { if (!heap_list_.empty()) { //size = heap_list_.size(); for (auto & heap : heap_list_) { bool allocated = false; { util::unlock_guard<unique_lock_type> ul(guard); allocated = heap->alloc(&p, count); } if (allocated) { #if defined(HPX_DEBUG) // Allocation succeeded, update statistics. alloc_count_ += count; if (alloc_count_ - free_count_ > max_alloc_count_) max_alloc_count_ = alloc_count_- free_count_; #endif return p; } #if defined(HPX_DEBUG) LOSH_(info) << hpx::util::format( "{1}::alloc: failed to allocate from heap[{2}] " "(heap[{2}] has allocated {3} objects and has " "space for {4} more objects)", name(), heap->heap_count(), heap->size(), heap->free_size()); #endif } } } // Create new heap. bool did_create = false; { #if defined(HPX_DEBUG) heap_list_.push_front(create_heap_( class_name_.c_str(), heap_count_ + 1, parameters_)); #else heap_list_.push_front(create_heap_( class_name_.c_str(), 0, parameters_)); #endif iterator itnew = heap_list_.begin(); typename list_type::value_type heap = *itnew; bool result = false; { util::unlock_guard<unique_lock_type> ul(guard); result = heap->alloc((void**)&p, count); } if (HPX_UNLIKELY(!result || nullptr == p)) { // out of memory guard.unlock(); HPX_THROW_EXCEPTION(out_of_memory, name() + "::alloc", hpx::util::format( "new heap failed to allocate {1} objects", count)); } #if defined(HPX_DEBUG) alloc_count_ += count; ++heap_count_; LOSH_(info) << hpx::util::format( "{1}::alloc: creating new heap[{2}], size is now {3}", name(), heap_count_, heap_list_.size()); #endif did_create = true; } if (did_create) return p; guard.unlock(); // Try again, we just got a new heap, so we should be good. return alloc(count); }