Esempio n. 1
0
void *
tfw_pool_alloc(TfwPool *p, size_t n)
{
	void *a;

	n = TFW_POOL_ALIGN_SZ(n);

	if (unlikely(p->off + n > TFW_POOL_CHUNK_SZ(p))) {
		TfwPoolChunk *c, *curr = p->curr;
		unsigned int off = TFW_POOL_ALIGN_SZ(sizeof(TfwPoolChunk)) + n;
		unsigned int order = get_order(off);

		c = (TfwPoolChunk *)tfw_pool_alloc_pages(order);
		if (!c)
			return NULL;
		c->next = curr;
		c->order = order;

		curr->off = p->off;

		p->order = order;
		p->off = off;
		p->curr = c;

		return (void *)TFW_POOL_ALIGN_SZ((unsigned long)(c + 1));
	}

	a = (char *)TFW_POOL_CHUNK_END(p);
	p->off += n;

	return a;
}
Esempio n. 2
0
void
tfw_pool_free(TfwPool *p, void *ptr, size_t n)
{
	TfwPoolChunk *c = p->curr;

	n = TFW_POOL_ALIGN_SZ(n);
	/* Stack-like usage is expected. */
	if (likely((char *)ptr + n == (char *)TFW_POOL_CHUNK_END(c)))
		c->off -= n;

	/* Free empty chunk which doesn't contain the pool header. */
	if (unlikely(c != tfw_pool_chunk_first(p)
		     && c->off == TFW_POOL_ALIGN_SZ(sizeof(*c))))
	{
		p->curr = c->next;
		tfw_pool_free_pages(TFW_POOL_CHUNK_BASE(c), c->order);
	}
}
Esempio n. 3
0
/**
 * It's good to call the function against just allocated chunk in stack-manner.
 * Consequent free calls can empty the whole pool but the first chunk with
 * the pool header.
 */
void
tfw_pool_free(TfwPool *p, void *ptr, size_t n)
{
	n = TFW_POOL_ALIGN_SZ(n);

	/* Stack-like usage is expected. */
	if (unlikely((char *)ptr + n != (char *)TFW_POOL_CHUNK_END(p)))
		return;

	p->off -= n;

	/* Free empty chunk which doesn't contain the pool header. */
	if (unlikely(p->off == TFW_POOL_ALIGN_SZ(sizeof(TfwPoolChunk)))) {
		TfwPoolChunk *next = p->curr->next;
		tfw_pool_free_pages(TFW_POOL_CHUNK_BASE(p->curr), p->order);
		p->curr = next;
		p->order = next->order;
		p->off = next->off;
	}
}
Esempio n. 4
0
void *
tfw_pool_realloc(TfwPool *p, void *ptr, size_t old_n, size_t new_n)
{
	void *a;

	BUG_ON(new_n < old_n);

	old_n = TFW_POOL_ALIGN_SZ(old_n);
	new_n = TFW_POOL_ALIGN_SZ(new_n);

	if ((char *)ptr + old_n == (char *)TFW_POOL_CHUNK_END(p)
	    && p->off - old_n + new_n <= TFW_POOL_CHUNK_SZ(p))
	{
		p->off += new_n - old_n;
		return ptr;
	}

	a = tfw_pool_alloc(p, new_n);
	if (likely(a))
		memcpy(a, ptr, old_n);

	return a;
}