1
/* $Id: pool.c 3553 2011-05-05 06:14:19Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include <pj/pool_buf.h>
24
#include <pj/except.h>
28
* \page page_pjlib_pool_test Test: Pool
30
* This file provides implementation of \b pool_test(). It tests the
31
* functionality of the memory pool.
34
* This file is <b>pjlib-test/pool.c</b>
36
* \include pjlib-test/pool.c
44
/* Normally we should throw exception when memory alloc fails.
45
* Here we do nothing so that the flow will go back to original caller,
46
* which will test the result using NULL comparison. Normally caller will
47
* catch the exception instead of checking for NULLs.
49
static void null_callback(pj_pool_t *pool, pj_size_t size)
55
#define GET_FREE(p) (pj_pool_get_capacity(p)-pj_pool_get_used_size(p))
57
/* Test that the capacity and used size reported by the pool is correct.
59
static int capacity_test(void)
61
pj_pool_t *pool = pj_pool_create(mem, NULL, SIZE, 0, &null_callback);
64
PJ_LOG(3,("test", "...capacity_test()"));
69
freesize = GET_FREE(pool);
71
if (pj_pool_alloc(pool, freesize) == NULL) {
72
PJ_LOG(3,("test", "...error: wrong freesize %u reported",
74
pj_pool_release(pool);
78
pj_pool_release(pool);
82
/* Test that the alignment works. */
83
static int pool_alignment_test(void)
87
enum { MEMSIZE = 64, LOOP = 100 };
90
PJ_LOG(3,("test", "...alignment test"));
92
pool = pj_pool_create(mem, NULL, PJ_POOL_SIZE+MEMSIZE, MEMSIZE, NULL);
96
#define IS_ALIGNED(p) ((((unsigned long)p) & (PJ_POOL_ALIGNMENT-1)) == 0)
98
for (i=0; i<LOOP; ++i) {
99
/* Test first allocation */
100
ptr = pj_pool_alloc(pool, 1);
101
if (!IS_ALIGNED(ptr)) {
102
pj_pool_release(pool);
106
/* Test subsequent allocation */
107
ptr = pj_pool_alloc(pool, 1);
108
if (!IS_ALIGNED(ptr)) {
109
pj_pool_release(pool);
113
/* Test allocation after new block is created */
114
ptr = pj_pool_alloc(pool, MEMSIZE*2+1);
115
if (!IS_ALIGNED(ptr)) {
116
pj_pool_release(pool);
125
pj_pool_release(pool);
130
/* Test that the alignment works for pool on buf. */
131
static int pool_buf_alignment_test(void)
139
PJ_LOG(3,("test", "...pool_buf alignment test"));
141
pool = pj_pool_create_on_buf(NULL, buf, sizeof(buf));
145
for (i=0; i<LOOP; ++i) {
146
/* Test first allocation */
147
ptr = pj_pool_alloc(pool, 1);
148
if (!IS_ALIGNED(ptr)) {
149
pj_pool_release(pool);
153
/* Test subsequent allocation */
154
ptr = pj_pool_alloc(pool, 1);
155
if (!IS_ALIGNED(ptr)) {
156
pj_pool_release(pool);
168
/* Test function to drain the pool's space.
170
static int drain_test(pj_size_t size, pj_size_t increment)
172
pj_pool_t *pool = pj_pool_create(mem, NULL, size, increment,
178
PJ_LOG(3,("test", "...drain_test(%d,%d)", size, increment));
184
freesize = GET_FREE(pool);
190
/* Drain the pool until there's nothing left. */
191
while (freesize > 0) {
195
size = ((pj_rand() & 0x000000FF) + PJ_POOL_ALIGNMENT) &
196
~(PJ_POOL_ALIGNMENT - 1);
200
p = pj_pool_alloc(pool, size);
202
status=-20; goto on_error;
208
/* Check that capacity is zero. */
209
if (GET_FREE(pool) != 0) {
210
PJ_LOG(3,("test", "....error: returned free=%u (expecting 0)",
212
status=-30; goto on_error;
215
/* Try to allocate once more */
216
p = pj_pool_alloc(pool, 257);
218
status=-40; goto on_error;
221
/* Check that capacity is NOT zero. */
222
if (GET_FREE(pool) == 0) {
223
status=-50; goto on_error;
228
pj_pool_release(pool);
232
/* Test the buffer based pool */
233
static int pool_buf_test(void)
235
enum { STATIC_BUF_SIZE = 40 };
236
/* 16 is the internal struct in pool_buf */
237
static char buf[ STATIC_BUF_SIZE + sizeof(pj_pool_t) +
238
sizeof(pj_pool_block) + 2 * PJ_POOL_ALIGNMENT];
243
PJ_LOG(3,("test", "...pool_buf test"));
245
pool = pj_pool_create_on_buf("no name", buf, sizeof(buf));
251
if ((p=pj_pool_alloc(pool, STATIC_BUF_SIZE/2)) == NULL)
254
if ((p=pj_pool_alloc(pool, STATIC_BUF_SIZE/2)) == NULL)
262
/* On the next alloc, exception should be thrown */
264
p = pj_pool_alloc(pool, STATIC_BUF_SIZE);
266
/* This is unexpected, the alloc should fail */
271
/* This is the expected result */
286
rc = capacity_test();
289
rc = pool_alignment_test();
292
rc = pool_buf_alignment_test();
295
for (loop=0; loop<LOOP; ++loop) {
296
/* Test that the pool should grow automaticly. */
297
rc = drain_test(SIZE, SIZE);
298
if (rc != 0) return rc;
300
/* Test situation where pool is not allowed to grow.
301
* We expect the test to return correct error.
303
rc = drain_test(SIZE, 0);
304
if (rc != -40) return rc;
307
rc = pool_buf_test();
316
/* To prevent warning about "translation unit is empty"
317
* when this test is disabled.
320
#endif /* INCLUDE_POOL_TEST */