aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_benchmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_benchmark.c')
-rw-r--r--libraries/eina/src/lib/eina_benchmark.c372
1 files changed, 372 insertions, 0 deletions
diff --git a/libraries/eina/src/lib/eina_benchmark.c b/libraries/eina/src/lib/eina_benchmark.c
new file mode 100644
index 0000000..1ba2a00
--- /dev/null
+++ b/libraries/eina/src/lib/eina_benchmark.c
@@ -0,0 +1,372 @@
1/* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#ifdef HAVE_CONFIG_H
20# include "config.h"
21#endif
22
23#ifdef HAVE_ALLOCA_H
24# include <alloca.h>
25#elif defined __GNUC__
26# define alloca __builtin_alloca
27#elif defined _AIX
28# define alloca __alloca
29#elif defined _MSC_VER
30# include <malloc.h>
31# define alloca _alloca
32#else
33# include <stddef.h>
34# ifdef __cplusplus
35extern "C"
36# endif
37void *alloca (size_t);
38#endif
39
40#include <stdlib.h>
41#include <stdio.h>
42#include <string.h>
43
44#ifdef HAVE_EVIL
45# include <Evil.h>
46#endif
47
48#include "eina_config.h"
49#include "eina_private.h"
50#include "eina_log.h"
51#include "eina_benchmark.h"
52#include "eina_inlist.h"
53#include "eina_list.h"
54#include "eina_counter.h"
55
56/*============================================================================*
57* Local *
58*============================================================================*/
59
60/**
61 * @cond LOCAL
62 */
63
64#define EINA_BENCHMARK_FILENAME_MASK "bench_%s_%s.gnuplot"
65#define EINA_BENCHMARK_DATA_MASK "bench_%s_%s.%s.data"
66
67typedef struct _Eina_Run Eina_Run;
68struct _Eina_Run
69{
70 EINA_INLIST;
71
72 Eina_Benchmark_Specimens cb;
73 const char *name;
74 int start;
75 int end;
76 int step;
77};
78
79struct _Eina_Benchmark
80{
81 const char *name;
82 const char *run;
83
84 Eina_Inlist *runs;
85 Eina_List *names;
86};
87
88static int _eina_benchmark_log_dom = -1;
89
90#ifdef ERR
91#undef ERR
92#endif
93#define ERR(...) EINA_LOG_DOM_ERR(_eina_benchmark_log_dom, __VA_ARGS__)
94
95#ifdef DBG
96#undef DBG
97#endif
98#define DBG(...) EINA_LOG_DOM_DBG(_eina_benchmark_log_dom, __VA_ARGS__)
99
100/**
101 * @endcond
102 */
103
104/*============================================================================*
105* Global *
106*============================================================================*/
107
108/**
109 * @internal
110 * @brief Initialize the benchmark module.
111 *
112 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
113 *
114 * This function sets up the benchmark module of Eina. It is called by
115 * eina_init().
116 *
117 * @see eina_init()
118 */
119Eina_Bool
120eina_benchmark_init(void)
121{
122 _eina_benchmark_log_dom = eina_log_domain_register("eina_benchmark",
123 EINA_LOG_COLOR_DEFAULT);
124 if (_eina_benchmark_log_dom < 0)
125 {
126 EINA_LOG_ERR("Could not register log domain: eina_benchmark");
127 return EINA_FALSE;
128 }
129
130 return EINA_TRUE;
131}
132
133/**
134 * @internal
135 * @brief Shut down the benchmark module.
136 *
137 * @return #EINA_TRUE on success, #EINA_FALSE on failure.
138 *
139 * This function shuts down the benchmark module set up by
140 * eina_benchmark_init(). It is called by eina_shutdown().
141 *
142 * @see eina_shutdown()
143 */
144Eina_Bool
145eina_benchmark_shutdown(void)
146{
147 eina_log_domain_unregister(_eina_benchmark_log_dom);
148 _eina_benchmark_log_dom = -1;
149 return EINA_TRUE;
150}
151
152/*============================================================================*
153* API *
154*============================================================================*/
155
156EAPI Eina_Benchmark *
157eina_benchmark_new(const char *name, const char *run)
158{
159 Eina_Benchmark *new;
160
161 eina_error_set(0);
162 new = calloc(1, sizeof (Eina_Benchmark));
163 if (!new)
164 {
165 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
166 return NULL;
167 }
168
169 new->name = name;
170 new->run = run;
171
172 return new;
173}
174
175EAPI void
176eina_benchmark_free(Eina_Benchmark *bench)
177{
178 Eina_Array *names;
179
180 if (!bench)
181 return;
182
183 while (bench->runs)
184 {
185 Eina_Run *run = (Eina_Run *)bench->runs;
186
187 bench->runs = eina_inlist_remove(bench->runs, bench->runs);
188 free(run);
189 }
190
191 EINA_LIST_FREE(bench->names, names)
192 {
193 Eina_Array_Iterator it;
194 char *tmp;
195 unsigned int i;
196
197 EINA_ARRAY_ITER_NEXT(names, i, tmp, it)
198 free(tmp);
199
200 eina_array_free(names);
201 }
202
203 free(bench);
204}
205
206EAPI Eina_Bool
207eina_benchmark_register(Eina_Benchmark *bench,
208 const char *name,
209 Eina_Benchmark_Specimens bench_cb,
210 int count_start,
211 int count_end,
212 int count_step)
213{
214 Eina_Run *run;
215
216 if (!bench)
217 return EINA_FALSE;
218
219 if (count_step == 0)
220 return EINA_FALSE;
221
222 eina_error_set(0);
223 run = calloc(1, sizeof (Eina_Run));
224 if (!run)
225 {
226 eina_error_set(EINA_ERROR_OUT_OF_MEMORY);
227 return EINA_FALSE;
228 }
229
230 run->cb = bench_cb;
231 run->name = name;
232 run->start = count_start;
233 run->end = count_end;
234 run->step = count_step;
235
236 bench->runs = eina_inlist_append(bench->runs, EINA_INLIST_GET(run));
237
238 return EINA_TRUE;
239}
240
241EAPI Eina_Array *
242eina_benchmark_run(Eina_Benchmark *bench)
243{
244 FILE *main_script;
245 FILE *current_data;
246 Eina_Array *ea;
247 Eina_Run *run;
248 char *buffer;
249 Eina_Bool first = EINA_FALSE;
250 size_t length;
251
252 if (!bench)
253 return NULL;
254
255 length = strlen(EINA_BENCHMARK_FILENAME_MASK) + strlen(bench->name) + strlen(
256 bench->run);
257
258 buffer = alloca(sizeof (char) * length);
259 if (!buffer)
260 return NULL;
261
262 snprintf(buffer,
263 length,
264 EINA_BENCHMARK_FILENAME_MASK,
265 bench->name,
266 bench->run);
267
268 main_script = fopen(buffer, "w");
269 if (!main_script)
270 return NULL;
271
272 ea = eina_array_new(16);
273 if (!ea)
274 {
275 fclose(main_script);
276 return NULL;
277 }
278
279 eina_array_push(ea, strdup(buffer));
280
281 fprintf(
282 main_script,
283 "set autoscale # scale axes automatically\n"
284 "unset log # remove any log-scaling\n"
285 "unset label # remove any previous labels\n"
286 "set xtic auto # set xtics automatically\n"
287 "set ytic auto # set ytics automatically\n"
288/* "set logscale y\n" */
289 "set terminal png size 1024,768\n"
290 "set output \"output_%s_%s.png\"\n"
291 "set title \"%s %s\n"
292 "set xlabel \"tests\"\n"
293 "set ylabel \"time\"\n"
294 "plot ",
295 bench->name,
296 bench->run,
297 bench->name,
298 bench->run);
299
300 EINA_INLIST_FOREACH(bench->runs, run)
301 {
302 Eina_Counter *counter;
303 char *result;
304 size_t tmp;
305 int i;
306
307 tmp = strlen(EINA_BENCHMARK_DATA_MASK) + strlen(bench->name) + strlen(
308 bench->run) + strlen(run->name);
309 if (tmp > length)
310 {
311 buffer = alloca(sizeof (char) * tmp);
312 length = tmp;
313 }
314
315 snprintf(buffer,
316 length,
317 EINA_BENCHMARK_DATA_MASK,
318 bench->name,
319 bench->run,
320 run->name);
321
322 current_data = fopen(buffer, "w");
323 if (!current_data)
324 continue;
325
326 eina_array_push(ea, strdup(buffer));
327
328 counter = eina_counter_new(run->name);
329
330 for (i = run->start; i < run->end; i += run->step)
331 {
332 fprintf(stderr, "Run %s: %i\n", run->name, i);
333 eina_counter_start(counter);
334
335 run->cb(i);
336
337 eina_counter_stop(counter, i);
338 }
339
340 result = eina_counter_dump(counter);
341 if (result)
342 {
343 fprintf(current_data, "%s", result);
344 free(result);
345 }
346
347 eina_counter_free(counter);
348
349 fclose(current_data);
350
351 if (first == EINA_FALSE)
352 first = EINA_TRUE;
353 else
354 fprintf(main_script, ", \\\n");
355
356 fprintf(main_script,
357 "\"%s\" using 1:2 title \'%s\' with line",
358 buffer, run->name);
359 }
360
361 fprintf(main_script, "\n");
362
363 fclose(main_script);
364
365 bench->names = eina_list_append(bench->names, ea);
366
367 return ea;
368}
369
370/**
371 * @}
372 */