Significantly improve scheduler performance under high load.
[asterisk/asterisk.git] / tests / test_sched.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief ast_sched performance test module
22  *
23  * \author Russell Bryant <russell@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
29
30 #include "asterisk/module.h"
31 #include "asterisk/cli.h"
32 #include "asterisk/utils.h"
33 #include "asterisk/sched.h"
34
35 static int sched_cb(const void *data)
36 {
37         return 0;
38 }
39
40 static char *handle_cli_sched_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
41 {
42         struct sched_context *con;
43         struct timeval start;
44         unsigned int num, i;
45         int *sched_ids = NULL;
46
47         switch (cmd) {
48         case CLI_INIT:
49                 e->command = "sched test";
50                 e->usage = ""
51                         "Usage: sched test <num>\n"
52                         "";
53                 return NULL;
54         case CLI_GENERATE:
55                 return NULL;
56         }
57
58         if (a->argc != e->args + 1) {
59                 return CLI_SHOWUSAGE;
60         }
61
62         if (sscanf(a->argv[e->args], "%u", &num) != 1) {
63                 return CLI_SHOWUSAGE;
64         }
65
66         if (!(con = sched_context_create())) {
67                 ast_cli(a->fd, "Test failed - could not create scheduler context\n");
68                 return CLI_FAILURE;
69         }
70
71         if (!(sched_ids = ast_malloc(sizeof(*sched_ids) * num))) {
72                 ast_cli(a->fd, "Test failed - memory allocation failure\n");
73                 goto return_cleanup;
74         }
75
76         ast_cli(a->fd, "Testing ast_sched_add() performance - timing how long it takes "
77                         "to add %u entries at random time intervals from 0 to 60 seconds\n", num);
78
79         start = ast_tvnow();
80
81         for (i = 0; i < num; i++) {
82                 int when = abs(ast_random()) % 60000;
83                 if ((sched_ids[i] = ast_sched_add(con, when, sched_cb, NULL)) == -1) {
84                         ast_cli(a->fd, "Test failed - sched_add returned -1\n");
85                         goto return_cleanup;
86                 }
87         }
88
89         ast_cli(a->fd, "Test complete - %ld us\n", ast_tvdiff_us(ast_tvnow(), start));
90
91         ast_cli(a->fd, "Testing ast_sched_del() performance - timing how long it takes "
92                         "to delete %u entries with random time intervals from 0 to 60 seconds\n", num);
93
94         start = ast_tvnow();
95
96         for (i = 0; i < num; i++) {
97                 if (ast_sched_del(con, sched_ids[i]) == -1) {
98                         ast_cli(a->fd, "Test failed - sched_del returned -1\n");
99                         goto return_cleanup;
100                 }
101         }
102
103         ast_cli(a->fd, "Test complete - %ld us\n", ast_tvdiff_us(ast_tvnow(), start));
104
105 return_cleanup:
106         sched_context_destroy(con);
107         if (sched_ids) {
108                 ast_free(sched_ids);
109         }
110
111         return CLI_SUCCESS;
112 }
113
114 static struct ast_cli_entry cli_sched[] = {
115         AST_CLI_DEFINE(handle_cli_sched_test, "Test ast_sched add/del performance"),
116 };
117
118 static int unload_module(void)
119 {
120         ast_cli_unregister_multiple(cli_sched, ARRAY_LEN(cli_sched));
121         return 0;
122 }
123
124 static int load_module(void)
125 {
126         ast_cli_register_multiple(cli_sched, ARRAY_LEN(cli_sched));
127         return AST_MODULE_LOAD_SUCCESS;
128 }
129
130 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ast_sched performance test module");