Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjlib / src / pjlib-test / pool_perf.c
1 /* $Id$ */
2 /* 
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
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.
10  *
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.
15  *
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 
19  */
20 #include "test.h"
21
22 #if INCLUDE_POOL_PERF_TEST
23
24 #include <pjlib.h>
25 #include <pj/compat/malloc.h>
26
27 #if !PJ_HAS_HIGH_RES_TIMER
28 # error Need high resolution timer for this test.
29 #endif
30
31 #define THIS_FILE   "test"
32
33 #define LOOP        10
34 #define COUNT       1024
35 static unsigned     sizes[COUNT];
36 static char        *p[COUNT];
37 #define MIN_SIZE    4
38 #define MAX_SIZE    512
39 static unsigned total_size;
40
41
42 static int pool_test_pool()
43 {
44     int i;
45     pj_pool_t *pool = pj_pool_create(mem, NULL, total_size + 4*COUNT, 0, NULL);
46     if (!pool)
47         return -1;
48
49     for (i=0; i<COUNT; ++i) {
50         char *p;
51         if ( (p=(char*)pj_pool_alloc(pool, sizes[i])) == NULL) {
52             PJ_LOG(3,(THIS_FILE,"   error: pool failed to allocate %d bytes",
53                       sizes[i]));
54             pj_pool_release(pool);
55             return -1;
56         }
57         *p = '\0';
58     }
59
60     pj_pool_release(pool);
61     return 0;
62 }
63
64 /* Symbian doesn't have malloc()/free(), so we use new/delete instead */
65 //#if defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0
66 #if 0
67 static int pool_test_malloc_free()
68 {
69     int i; /* must be signed */
70
71     for (i=0; i<COUNT; ++i) {
72                 p[i] = new char[sizes[i]];
73                 if (!p[i]) {
74                         PJ_LOG(3,(THIS_FILE,"   error: malloc failed to allocate %d bytes",
75                                           sizes[i]));
76                         --i;
77                         while (i >= 0) {
78                                 delete [] p[i];
79                                 --i;
80                         }
81                         return -1;
82                 }
83                 *p[i] = '\0';
84     }
85
86     for (i=0; i<COUNT; ++i) {
87         delete [] p[i];
88     }
89
90     return 0;
91 }
92
93 #else   /* PJ_SYMBIAN */
94
95 static int pool_test_malloc_free()
96 {
97     int i; /* must be signed */
98
99     for (i=0; i<COUNT; ++i) {
100         p[i] = (char*)malloc(sizes[i]);
101         if (!p[i]) {
102             PJ_LOG(3,(THIS_FILE,"   error: malloc failed to allocate %d bytes",
103                       sizes[i]));
104             --i;
105             while (i >= 0)
106                 free(p[i]), --i;
107             return -1;
108         }
109         *p[i] = '\0';
110     }
111
112     for (i=0; i<COUNT; ++i) {
113         free(p[i]);
114     }
115
116     return 0;
117 }
118
119 #endif /* PJ_SYMBIAN */
120
121 int pool_perf_test()
122 {
123     unsigned i;
124     pj_uint32_t pool_time=0, malloc_time=0, pool_time2=0;
125     pj_timestamp start, end;
126     pj_uint32_t best, worst;
127
128     /* Initialize size of chunks to allocate in for the test. */
129     for (i=0; i<COUNT; ++i) {
130         unsigned aligned_size;
131         sizes[i] = MIN_SIZE + (pj_rand() % MAX_SIZE);
132         aligned_size = sizes[i];
133         if (aligned_size & (PJ_POOL_ALIGNMENT-1))
134             aligned_size = ((aligned_size + PJ_POOL_ALIGNMENT - 1)) & ~(PJ_POOL_ALIGNMENT - 1);
135         total_size += aligned_size;
136     }
137
138     /* Add some more for pool admin area */
139     total_size += 512;
140
141     PJ_LOG(3, (THIS_FILE, "Benchmarking pool.."));
142
143     /* Warmup */
144     pool_test_pool();
145     pool_test_malloc_free();
146
147     for (i=0; i<LOOP; ++i) {
148         pj_get_timestamp(&start);
149         if (pool_test_pool()) {
150             return 1;
151         }
152         pj_get_timestamp(&end);
153         pool_time += (end.u32.lo - start.u32.lo);
154
155         pj_get_timestamp(&start);
156         if (pool_test_malloc_free()) {
157             return 2;
158         }
159         pj_get_timestamp(&end);
160         malloc_time += (end.u32.lo - start.u32.lo);
161
162         pj_get_timestamp(&start);
163         if (pool_test_pool()) {
164             return 4;
165         }
166         pj_get_timestamp(&end);
167         pool_time2 += (end.u32.lo - start.u32.lo);
168     }
169
170     PJ_LOG(4,(THIS_FILE,"..LOOP count:                        %u",LOOP));
171     PJ_LOG(4,(THIS_FILE,"..number of alloc/dealloc per loop:  %u",COUNT));
172     PJ_LOG(4,(THIS_FILE,"..pool allocation/deallocation time: %u",pool_time));
173     PJ_LOG(4,(THIS_FILE,"..malloc/free time:                  %u",malloc_time));
174     PJ_LOG(4,(THIS_FILE,"..pool again, second invocation:     %u",pool_time2));
175
176     if (pool_time2==0) pool_time2=1;
177     if (pool_time < pool_time2)
178         best = pool_time, worst = pool_time2;
179     else
180         best = pool_time2, worst = pool_time;
181     
182     /* avoid division by zero */
183     if (best==0) best=1;
184     if (worst==0) worst=1;
185
186     PJ_LOG(3, (THIS_FILE, "..pool speedup over malloc best=%dx, worst=%dx", 
187                           (int)(malloc_time/best),
188                           (int)(malloc_time/worst)));
189     return 0;
190 }
191
192
193 #endif  /* INCLUDE_POOL_PERF_TEST */
194