Пример #1
0
/**
 * Grow @str for @n new chunks.
 * New branches of the string tree are created on 2nd level only,
 * i.e. there is no possibility to grow number of chunks of duplicate string.
 * Pass pointer to one of the duplicates to do so.
 * @return pointer to the first of newly added chunk.
 *
 * TODO do we need exponential growing?
 */
static TfwStr *
__str_grow_tree(TfwPool *pool, TfwStr *str, unsigned int flag, int n)
{
	if (str->flags & flag) {
		unsigned int l;
		void *p;

		if (unlikely(TFW_STR_CHUNKN_LIM(str))) {
			TFW_WARN("Reaching chunks hard limit\n");
			return NULL;
		}

		l = TFW_STR_CHUNKN(str) * sizeof(TfwStr);
		p = tfw_pool_realloc(pool, str->ptr, l,
				     l + n * sizeof(TfwStr));
		if (!p)
			return NULL;
		str->ptr = p;
		TFW_STR_CHUNKN_ADD(str, n);
	}
	else {
		TfwStr *a = tfw_pool_alloc(pool, (n + 1) * sizeof(TfwStr));
		if (!a)
			return NULL;
		a[0] = *str;
		str->ptr = a;
		__TFW_STR_CHUNKN_SET(str, n + 1);
	}

	str = (TfwStr *)str->ptr + TFW_STR_CHUNKN(str) - n;
	memset(str, 0, sizeof(TfwStr) * n);

	return str;
}
Пример #2
0
static TfwStr *
alloc_str(void)
{
	TfwStr *s;

	s = tfw_pool_alloc(str_pool, sizeof(*s));
	BUG_ON(!s);
	TFW_STR_INIT(s);

	return s;
}
Пример #3
0
static TfwRrPtrSet *
alloc_srv_set(TfwPool *pool, size_t max_srv_n)
{
	size_t size = tfw_ptrset_size(max_srv_n);
	TfwRrPtrSet *ptrset = tfw_pool_alloc(pool, size);
	if (!ptrset) {
		ERR("Can't allocate memory from pool: %p\n", pool);
		return NULL;
	}
	tfw_ptrset_init(ptrset, max_srv_n);

	return ptrset;
}
Пример #4
0
TfwHttpMsg *
tfw_http_msg_alloc(int type)
{
	TfwHttpMsg *hm = (type & Conn_Clnt)
			 ? (TfwHttpMsg *)tfw_pool_new(TfwHttpReq, TFW_POOL_ZERO)
			 : (TfwHttpMsg *)tfw_pool_new(TfwHttpResp, TFW_POOL_ZERO);
	if (!hm)
		return NULL;

	ss_skb_queue_head_init(&hm->msg.skb_list);

	hm->h_tbl = (TfwHttpHdrTbl *)tfw_pool_alloc(hm->pool, TFW_HHTBL_SZ(1));
	hm->h_tbl->size = __HHTBL_SZ(1);
	hm->h_tbl->off = TFW_HTTP_HDR_RAW;
	memset(hm->h_tbl->tbl, 0, __HHTBL_SZ(1) * sizeof(TfwHttpHdr));

	INIT_LIST_HEAD(&hm->msg.msg_list);

	return hm;
}
Пример #5
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;
}
Пример #6
0
int __init
pool_benchmark(void)
{
	long i, j, t0, t1;
	ngx_pool_t *np;
	TfwPool *tp;

	printk(KERN_ERR "object sizes: Small - %lu, Big - %lu Huge - %lu\n",
	       sizeof(Small), sizeof(Big), sizeof(Huge));

	t0 = jiffies;
	for (i = 0; i < N_ALLOC; ++i) {
		p_arr[i] = (void *)__get_free_pages(GFP_KERNEL, 0);
		touch_obj(p_arr[i]);
	}
	for (i = 0; i < N_ALLOC; ++i)
		free_pages((unsigned long)p_arr[i], 0);
	t1 = jiffies;
	printk(KERN_ERR "alloc & free:  %ldms\n", t1 - t0);

	/*****************************************************************/
	np = ngx_create_pool(PAGE_SIZE);
	BUG_ON(!np);
	t0 = jiffies;
	for (i = 0; i < N; ++i) {
		Small *o = (Small *)ngx_palloc(np, sizeof(Small));
		touch_obj(o);
	}
	t1 = jiffies;
	ngx_destroy_pool(np);
	/* HZ = 1000 for my kernel. */
	printk(KERN_ERR "ngx_pool (Small):  %ldms\n", t1 - t0);

	np = ngx_create_pool(PAGE_SIZE);
	BUG_ON(!np);
	t0 = jiffies;
	for (i = 0; i < N * sizeof(Small) / sizeof(Big); ++i) {
		Big *o = (Big *)ngx_palloc(np, sizeof(Big));
		touch_obj(o);
	}
	t1 = jiffies;
	ngx_destroy_pool(np);
	printk(KERN_ERR "ngx_pool (Big):  %ldms\n", t1 - t0);

	np = ngx_create_pool(PAGE_SIZE);
	BUG_ON(!np);
	t0 = jiffies;
	for (i = 0; i < N; ++i) {
		if (unlikely(!(i & 0xfff))) {
			Huge *o = (Huge *)ngx_palloc(np, sizeof(*o));
			touch_obj(o);
			if (!(i & 1))
				ngx_pfree(np, o);
		}
		else if (unlikely(!(i & 3))) {
			Big *o = (Big *)ngx_palloc(np, sizeof(*o));
			touch_obj(o);
		}
		else {
			Small *o = (Small *)ngx_palloc(np, sizeof(*o));
			touch_obj(o);
		}
	}
	t1 = jiffies;
	ngx_destroy_pool(np);
	printk(KERN_ERR "ngx_pool w/ free (Mix):  %ldms\n", t1 - t0);

	t0 = jiffies;
	for (i = 0; i < N / 100; ++i) {
		np = ngx_create_pool(PAGE_SIZE);
		for (j = 0; j < 100; ++j) {
			if (unlikely(!(i & 3))) {
				Big *o = (Big *)ngx_palloc(np, sizeof(*o));
				touch_obj(o);
			} else {
				Small *o;
				o = (Small *)ngx_palloc(np, sizeof(*o));
				touch_obj(o);
			}
		}
		ngx_destroy_pool(np);
	}
	t1 = jiffies;
	printk(KERN_ERR "ngx_pool cr. & destr.:  %ldms\n", t1 - t0);

	/*****************************************************************/
	tp = __tfw_pool_new(0);
	BUG_ON(!tp);
	t0 = jiffies;
	for (i = 0; i < N; ++i) {
		Small *o = (Small *)tfw_pool_alloc(tp, sizeof(Small));
		touch_obj(o);
	}
	t1 = jiffies;
	tfw_pool_destroy(tp);
	printk(KERN_ERR "tfw_pool (Small):  %ldms\n", t1 - t0);

	tp = __tfw_pool_new(0);
	BUG_ON(!tp);
	t0 = jiffies;
	for (i = 0; i < N; ++i) {
		Small *o = (Small *)tfw_pool_alloc(tp, sizeof(Small));
		touch_obj(o);
		if (unlikely(!(i & 3)))
			tfw_pool_free(tp, o, sizeof(Small));
	}
	t1 = jiffies;
	tfw_pool_destroy(tp);
	printk(KERN_ERR "tfw_pool w/ free (Small):  %ldms\n", t1 - t0);

	tp = __tfw_pool_new(0);
	BUG_ON(!tp);
	t0 = jiffies;
	for (i = 0; i < N * sizeof(Small) / sizeof(Big); ++i) {
		Big *o = (Big *)tfw_pool_alloc(tp, sizeof(Big));
		touch_obj(o);
	}
	t1 = jiffies;
	tfw_pool_destroy(tp);
	printk(KERN_ERR "tfw_pool (Big):  %ldms\n", t1 - t0);

	tp = __tfw_pool_new(0);
	BUG_ON(!tp);
	t0 = jiffies;
	for (i = 0; i < N * sizeof(Small) / sizeof(Big); ++i) {
		Big *o = (Big *)tfw_pool_alloc(tp, sizeof(Big));
		touch_obj(o);
		if (unlikely(!(i & 3)))
			tfw_pool_free(tp, o, sizeof(Big));
	}
	t1 = jiffies;
	tfw_pool_destroy(tp);
	printk(KERN_ERR "tfw_pool w/ free (Big):  %ldms\n", t1 - t0);

	tp = __tfw_pool_new(0);
	BUG_ON(!tp);
	t0 = jiffies;
	for (i = 0; i < N; ++i) {
		if (unlikely(!(i & 0xfff))) {
			Huge *o = (Huge *)tfw_pool_alloc(tp, sizeof(*o));
			touch_obj(o);
			if (!(i & 1))
				tfw_pool_free(tp, o, sizeof(*o));
		}
		else if (unlikely(!(i & 3))) {
			Big *o = (Big *)tfw_pool_alloc(tp, sizeof(*o));
			touch_obj(o);
			if (!(i & 1))
				tfw_pool_free(tp, o, sizeof(*o));
		}
		else {
			Small *o = (Small *)tfw_pool_alloc(tp, sizeof(*o));
			touch_obj(o);
		}
	}
	t1 = jiffies;
	tfw_pool_destroy(tp);
	printk(KERN_ERR "tfw_pool w/ free (Mix):  %ldms\n", t1 - t0);

	t0 = jiffies;
	for (i = 0; i < N / 100; ++i) {
		tp = __tfw_pool_new(0);
		for (j = 0; j < 100; ++j) {
			if (unlikely(!(i & 3))) {
				Big *o = (Big *)tfw_pool_alloc(tp, sizeof(*o));
				touch_obj(o);
			} else {
				Small *o;
				o = (Small *)tfw_pool_alloc(tp, sizeof(*o));
				touch_obj(o);
			}
		}
		tfw_pool_destroy(tp);
	}
	t1 = jiffies;
	printk(KERN_ERR "tfw_pool cr. & destr.:  %ldms\n", t1 - t0);

	return 0;
}