tizen 2.3 release
[external/buxton.git] / demo / timing.c
1 /*
2  * This file is part of buxton.
3  *
4  * Copyright (C) 2013 Intel Corporation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  */
26
27 #define _GNU_SOURCE
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <time.h>
31 #include <math.h>
32
33 #include "buxton.h"
34 #include "util.h"
35
36 #define error(...) { printf(__VA_ARGS__); }
37
38 static int iterations = 100000;
39
40 static void callback(BuxtonResponse response, void *userdata)
41 {
42         bool *r;
43
44         if (!userdata) {
45                 return;
46         }
47
48         r = (bool *)userdata;
49
50         if (buxton_response_status(response) == 0) {
51                 *r = true;
52         }
53 }
54
55 enum test_type {
56         TEST_GET,
57         TEST_SET,
58         TEST_SET_UNSET,
59         TEST_TYPE_MAX
60 };
61
62 enum data_type {
63         TEST_INT32,
64         TEST_UINT32,
65         TEST_INT64,
66         TEST_UINT64,
67         TEST_BOOLEAN,
68         TEST_STRING,
69         TEST_STRING4K,
70         TEST_FLOAT,
71         TEST_DOUBLE,
72         TEST_DATA_TYPE_MAX
73 };
74
75 struct testcase {
76         char name[32];
77         enum test_type t;
78         enum data_type d;
79 };
80
81 #define TEST_COUNT (TEST_TYPE_MAX * TEST_DATA_TYPE_MAX)
82 static struct testcase testcases[TEST_COUNT] = {
83         { "set_int32",          TEST_SET,       TEST_INT32    },
84         { "get_int32",          TEST_GET,       TEST_INT32    },
85         { "set_unset_int32",    TEST_SET_UNSET, TEST_INT32    },
86         { "set_uint32",         TEST_SET,       TEST_UINT32   },
87         { "get_uint32",         TEST_GET,       TEST_UINT32   },
88         { "set_unset_uint32",   TEST_SET_UNSET, TEST_UINT32   },
89         { "set_int64",          TEST_SET,       TEST_INT64    },
90         { "get_int64",          TEST_GET,       TEST_INT64    },
91         { "set_unset_int64",    TEST_SET_UNSET, TEST_INT64    },
92         { "set_uint64",         TEST_SET,       TEST_UINT64   },
93         { "get_uint64",         TEST_GET,       TEST_UINT64   },
94         { "set_unset_uint64",   TEST_SET_UNSET, TEST_UINT64   },
95         { "set_boolean",        TEST_SET,       TEST_BOOLEAN  },
96         { "get_boolean",        TEST_GET,       TEST_BOOLEAN  },
97         { "set_unset_boolean",  TEST_SET_UNSET, TEST_BOOLEAN  },
98         { "set_string",         TEST_SET,       TEST_STRING   },
99         { "get_string",         TEST_GET,       TEST_STRING   },
100         { "set_unset_string",   TEST_SET_UNSET, TEST_STRING   },
101         { "set_string4k",       TEST_SET,       TEST_STRING4K },
102         { "get_string4k",       TEST_GET,       TEST_STRING4K },
103         { "set_unset_string4k", TEST_SET_UNSET, TEST_STRING4K },
104         { "set_float",          TEST_SET,       TEST_FLOAT    },
105         { "get_float",          TEST_GET,       TEST_FLOAT    },
106         { "set_unset_float",    TEST_SET_UNSET, TEST_FLOAT    },
107         { "set_double",         TEST_SET,       TEST_DOUBLE   },
108         { "get_double",         TEST_GET,       TEST_DOUBLE   },
109         { "set_unset_double",   TEST_SET_UNSET, TEST_DOUBLE   }
110 };
111
112 static BuxtonClient __client;
113 static BuxtonData __data;
114 static BuxtonKey __key;
115
116 static bool init_group(void)
117 {
118         BuxtonKey group;
119         bool r;
120         bool d = false;
121
122         group = buxton_key_create("TimingTest", NULL, "user", STRING);
123         r = buxton_create_group(__client, group, callback, &d, true);
124
125         free(group);
126
127         return (!r && d);
128 }
129
130 static bool testcase_init(struct testcase *tc)
131 {
132         char name[64] = "";
133         int32_t i;
134         uint32_t ui;
135         int64_t i6;
136         uint64_t ui6;
137         bool b;
138         char *string;
139         float f;
140         double d;
141         void *value = NULL;
142
143         switch (tc->d) {
144                 case TEST_INT32:
145                         sprintf(name, "TimingTest-%d-int32", getpid());
146                         __key = buxton_key_create("TimingTest", name, "user", INT32);
147                         i = -672;
148                         value = &i;
149                         break;
150                 case TEST_UINT32:
151                         sprintf(name, "TimingTest-%d-uint32", getpid());
152                         __key = buxton_key_create("TimingTest", name, "user", UINT32);
153                         ui = 672;
154                         value = &ui;
155                         break;
156                 case TEST_INT64:
157                         sprintf(name, "TimingTest-%d-int64", getpid());
158                         __key = buxton_key_create("TimingTest", name, "user", INT64);
159                         i6 = -672 * 672;
160                         value = &i6;
161                         break;
162                 case TEST_UINT64:
163                         sprintf(name, "TimingTest-%d-uint64", getpid());
164                         __key = buxton_key_create("TimingTest", name, "user", UINT64);
165                         ui6 = 672 * 672;
166                         value = &ui6;
167                         break;
168                 case TEST_BOOLEAN:
169                         sprintf(name, "TimingTest-%d-boolean", getpid());
170                         __key = buxton_key_create("TimingTest", name, "user", BOOLEAN);
171                         b = true;
172                         value = &b;
173                         break;
174                 case TEST_STRING:
175                         sprintf(name, "TimingTest-%d-string", getpid());
176                         __key = buxton_key_create("TimingTest", name, "user", STRING);
177                         string = "672";
178                         value = string;
179                         break;
180                 case TEST_STRING4K:
181                         sprintf(name, "TimingTest-%d-string4k", getpid());
182                         __key = buxton_key_create("TimingTest", name, "user", STRING);
183                         string = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
184                         value = string;
185                         break;
186                 case TEST_FLOAT:
187                         sprintf(name, "TimingTest-%d-float", getpid());
188                         __key = buxton_key_create("TimingTest", name, "user", FLOAT);
189                         f = (float)3.14;
190                         value = &f;
191                         break;
192                 case TEST_DOUBLE:
193                         sprintf(name, "TimingTest-%d-double", getpid());
194                         __key = buxton_key_create("TimingTest", name, "user", DOUBLE);
195                         d = 3.14;
196                         value = &d;
197                         break;
198                 default:
199                         return false;
200         }
201
202         return !buxton_set_value(__client, __key, value, callback, NULL, true);
203 }
204
205 static bool testcase_cleanup(struct testcase *tc)
206 {
207         bool ret = (!buxton_set_value(__client, __key, &__data, callback, NULL, true) &&
208                 !buxton_unset_value(__client,  __key, callback, NULL, true));
209         buxton_key_free(__key);
210         return ret;
211 }
212
213 static bool testcase_run(struct testcase *tc)
214 {
215         bool d = false;
216         bool r, s;
217         switch (tc->t) {
218                 case TEST_GET:
219                         r = buxton_get_value(__client, __key, callback, &d, true);
220                         return (!r && d);
221                 case TEST_SET:
222                         r = buxton_set_value(__client, __key, &__data, callback, &d, true);
223                         return (!r && d);
224                 case TEST_SET_UNSET:
225                         r = buxton_set_value(__client, __key, &__data, callback, &d, true);
226                         s = buxton_unset_value(__client, __key, callback, &d, true);
227                         return (!s && !r && d);
228                 default:
229                         return false;
230         }
231 }
232
233 static bool timed_func(unsigned long long *elapsed, struct testcase *tc)
234 {
235         struct timespec tsi, tsf;
236         bool ret;
237
238         clock_gettime(CLOCK_MONOTONIC, &tsi);
239         ret = testcase_run(tc);
240         clock_gettime(CLOCK_MONOTONIC, &tsf);
241
242         *elapsed = (unsigned long long)((tsf.tv_nsec - tsi.tv_nsec) + ((tsf.tv_sec - tsi.tv_sec) * 1000000000));
243         return ret;
244 }
245
246 static void test(struct testcase *tc)
247 {
248         unsigned long long elapsed;
249         unsigned long long total;
250         unsigned long long errors = 0;
251         double meansqr;
252         double mean;
253         double sigma;
254         int i;
255
256         total = 0;
257         meansqr = 0.0;
258         mean = 0.0;
259
260         testcase_init(tc);
261
262         for (i = 0; i < iterations; i++) {
263                 if (!timed_func(&elapsed, tc)) {
264                         errors++;
265                 }
266
267                 mean += (double)elapsed;
268                 meansqr += (double)elapsed * (double)elapsed;
269                 total += elapsed;
270         }
271         mean /= (double)iterations;
272         meansqr /= (double)iterations;
273         sigma = sqrt(meansqr - (mean * mean));
274
275         testcase_cleanup(tc);
276
277         printf("%-24s  %10.3lfus  %10.3lfus  %10llu\n",
278                tc->name, mean / 1000.0, sigma / 1000.0, errors);
279 }
280
281 int main(int argc, char **argv)
282 {
283         int ret = EXIT_SUCCESS;
284         int i;
285
286         if (argc == 2) {
287                 iterations = atoi(argv[1]);
288                 if (iterations <= 0) {
289                         exit(EXIT_FAILURE);
290                 }
291         } else if (argc != 1) {
292                 error("Usage: %s [iterations]\n", argv[0]);
293                 exit(EXIT_FAILURE);
294         }
295
296         if (!buxton_open(&__client)) {
297                 error("Unable to open BuxtonClient\n");
298                 exit(EXIT_FAILURE);
299         }
300
301         init_group();
302
303         printf("Buxton protocol latency timing tool. Using %i iterations per test.\n", iterations);
304         printf("Test Name:                   Average:        Sigma:     Errors:\n");
305
306         for (i = 0; i < TEST_COUNT; i++)
307                 test(&testcases[i]);
308
309         buxton_close(__client);
310         exit(ret);
311 }
312