/** Allocate the memory for the object in blocks. We keep the objects sorted onpointersothattheyareclosertogetherincasetheyhavetobeiterated
over in a list. */ template <typename Type, typename Factory, typename LockStrategy> struct Pool {
typedef Type value_type;
struct Element {
Pool* m_pool;
value_type m_type;
};
m_start = static_cast<Element*>(
aligned_malloc(m_size, CPU_LEVEL1_DCACHE_LINESIZE));
memset_aligned<CPU_LEVEL1_DCACHE_LINESIZE>(
m_start, 0, m_size); /* Note: The above would zero-initialize some std::atomicdatamembersintrx_t,suchas trx_t::lock,whichwillnotbeinitializedfurtherin TrxFactory::init().Itmaybeimplementationdefined whethersuchzeroinitializationworks.Onsome hypotheticalplatform(notonethatseemstobe supportedbyamainstreamC++compiler),std::atomic mightwrapthedatamemberaswellasa
non-zero-initialized mutex. */
m_last = m_start;
m_end = &m_start[m_size / sizeof *m_start];
/* Note: Initialise only a small subset, even though we have allocatedallthememory.ThisisrequiredonlybecausePFS (MTR)resultschangeifweinstantiatetoomanymutexesup
front. */
/** Add the object to the pool.
@param ptr object to free */ staticvoid mem_free(value_type* ptr)
{
Element* elem;
byte* p = reinterpret_cast<byte*>(ptr + 1);
/* We only need to compare on pointer address. */ typedef std::priority_queue<
Element*,
std::vector<Element*, ut_allocator<Element*> >,
std::greater<Element*> > pqueue_t;
/** Release the object to the free pool
@param elem element to free */ void putl(Element* elem)
{
ut_ad(elem >= m_start && elem < m_last);
m_pqueue.push(elem);
}
/** Initialise the elements.
@param n_elems Number of elements to initialise */ void init(size_t n_elems)
{
ut_ad(size_t(m_end - m_last) >= n_elems);
/** Get an element from one of the pools.
@return instance or NULL if pool is empty. */
value_type* get()
{
size_t index = 0;
size_t delay = 1;
value_type* ptr = NULL;
do {
m_lock_strategy.enter();
ut_ad(!m_pools.empty());
size_t n_pools = m_pools.size();
PoolType* pool = m_pools[index % n_pools];
m_lock_strategy.exit();
ptr = pool->get();
if (ptr == 0 && (index / n_pools) > 2) {
if (!add_pool(n_pools)) {
ib::error() << "Failed to allocate" " memory for a pool of size "
<< m_size << " bytes. Will" " wait for " << delay
<< " seconds for a thread to" " free a resource";
/* There is nothing much we can do exceptcrashandburn,howeverlets bealittleoptimisticandwaitfor
a resource to be freed. */
std::this_thread::sleep_for(
std::chrono::seconds(delay));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.