Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
test_sched.c File Reference

ast_sched performance test module More...

#include "asterisk.h"
#include <inttypes.h>
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include "asterisk/sched.h"
#include "asterisk/test.h"
#include "asterisk/cli.h"
Include dependency graph for test_sched.c:

Go to the source code of this file.

Macros

#define DELAYED_SAME_EXPIRE   300 /* ms */
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (sched_test_order)
 
static char * handle_cli_sched_bench (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int load_module (void)
 
static int sched_cb (const void *data)
 
static int sched_order_1_cb (const void *data)
 
static int sched_order_2_cb (const void *data)
 
static int sched_order_3_cb (const void *data)
 
static int sched_order_4_cb (const void *data)
 
static int sched_order_5_cb (const void *data)
 
static int sched_order_6_cb (const void *data)
 
static int sched_order_7_cb (const void *data)
 
static int sched_order_8_cb (const void *data)
 
static void sched_order_check (struct ast_test *test, int order)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ast_sched performance test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_sched []
 
static int order_check
 
static int order_check_failed
 

Detailed Description

ast_sched performance test module

Author
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com

Definition in file test_sched.c.

Macro Definition Documentation

◆ DELAYED_SAME_EXPIRE

#define DELAYED_SAME_EXPIRE   300 /* ms */

Referenced by AST_TEST_DEFINE().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 357 of file test_sched.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 357 of file test_sched.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 357 of file test_sched.c.

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( sched_test_order  )

Definition at line 107 of file test_sched.c.

References ast_sched_add(), ast_sched_context_create(), ast_sched_context_destroy(), ast_sched_del(), ast_sched_runq(), ast_sched_wait(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, DELAYED_SAME_EXPIRE, sip_to_pjsip::info(), NULL, order_check, order_check_failed, sched_cb(), sched_order_1_cb(), sched_order_2_cb(), sched_order_3_cb(), sched_order_4_cb(), sched_order_5_cb(), sched_order_6_cb(), sched_order_7_cb(), sched_order_8_cb(), TEST_EXECUTE, and TEST_INIT.

108 {
109  struct ast_sched_context *con;
111  int id1, id2, id3, wait;
112 
113  switch (cmd) {
114  case TEST_INIT:
115  info->name = "sched_test_order";
116  info->category = "/main/sched/";
117  info->summary = "Test ordering of events in the scheduler API";
118  info->description =
119  "This test ensures that events are properly ordered by the "
120  "time they are scheduled to execute in the scheduler API.";
121  return AST_TEST_NOT_RUN;
122  case TEST_EXECUTE:
123  break;
124  }
125 
126  if (!(con = ast_sched_context_create())) {
128  "Test failed - could not create scheduler context\n");
129  return AST_TEST_FAIL;
130  }
131 
132  /* Add 3 scheduler entries, and then remove them, ensuring that the result
133  * of ast_sched_wait() looks appropriate at each step along the way. */
134 
135  if ((wait = ast_sched_wait(con)) != -1) {
137  "ast_sched_wait() should have returned -1, returned '%d'\n",
138  wait);
139  goto return_cleanup;
140  }
141 
142  if ((id1 = ast_sched_add(con, 100000, sched_cb, NULL)) == -1) {
143  ast_test_status_update(test, "Failed to add scheduler entry\n");
144  goto return_cleanup;
145  }
146 
147  if ((wait = ast_sched_wait(con)) > 100000) {
149  "ast_sched_wait() should have returned <= 100000, returned '%d'\n",
150  wait);
151  goto return_cleanup;
152  }
153 
154  if ((id2 = ast_sched_add(con, 10000, sched_cb, NULL)) == -1) {
155  ast_test_status_update(test, "Failed to add scheduler entry\n");
156  goto return_cleanup;
157  }
158 
159  if ((wait = ast_sched_wait(con)) > 10000) {
161  "ast_sched_wait() should have returned <= 10000, returned '%d'\n",
162  wait);
163  goto return_cleanup;
164  }
165 
166  if ((id3 = ast_sched_add(con, 1000, sched_cb, NULL)) == -1) {
167  ast_test_status_update(test, "Failed to add scheduler entry\n");
168  goto return_cleanup;
169  }
170 
171  if ((wait = ast_sched_wait(con)) > 1000) {
173  "ast_sched_wait() should have returned <= 1000, returned '%d'\n",
174  wait);
175  goto return_cleanup;
176  }
177 
178  if (ast_sched_del(con, id3) == -1) {
179  ast_test_status_update(test, "Failed to remove scheduler entry\n");
180  goto return_cleanup;
181  }
182 
183  if ((wait = ast_sched_wait(con)) <= 1000) {
185  "ast_sched_wait() should have returned > 1000, returned '%d'\n",
186  wait);
187  goto return_cleanup;
188  }
189 
190  if (ast_sched_del(con, id2) == -1) {
191  ast_test_status_update(test, "Failed to remove scheduler entry\n");
192  goto return_cleanup;
193  }
194 
195  if ((wait = ast_sched_wait(con)) <= 10000) {
197  "ast_sched_wait() should have returned > 10000, returned '%d'\n",
198  wait);
199  goto return_cleanup;
200  }
201 
202  if (ast_sched_del(con, id1) == -1) {
203  ast_test_status_update(test, "Failed to remove scheduler entry\n");
204  goto return_cleanup;
205  }
206 
207  if ((wait = ast_sched_wait(con)) != -1) {
209  "ast_sched_wait() should have returned -1, returned '%d'\n",
210  wait);
211  goto return_cleanup;
212  }
213 
214  /*
215  * Schedule immediate and delayed entries to check the order
216  * that they get executed. They must get executed at the
217  * time they expire in the order they were added.
218  */
219 #define DELAYED_SAME_EXPIRE 300 /* ms */
220  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_1_cb, test), res, return_cleanup);
221  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, 0, sched_order_1_cb, test), res, return_cleanup);
222  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_2_cb, test), res, return_cleanup);
223  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, 0, sched_order_2_cb, test), res, return_cleanup);
224  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_3_cb, test), res, return_cleanup);
225  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, 0, sched_order_3_cb, test), res, return_cleanup);
226  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_4_cb, test), res, return_cleanup);
227  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, 0, sched_order_4_cb, test), res, return_cleanup);
228  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_5_cb, test), res, return_cleanup);
229  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, 0, sched_order_5_cb, test), res, return_cleanup);
230  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_6_cb, test), res, return_cleanup);
231  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, 0, sched_order_6_cb, test), res, return_cleanup);
232  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_7_cb, test), res, return_cleanup);
233  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, 0, sched_order_7_cb, test), res, return_cleanup);
234  ast_test_validate_cleanup(test, -1 < ast_sched_add(con, DELAYED_SAME_EXPIRE, sched_order_8_cb, test), res, return_cleanup);
235 
236  /* Check order of scheduled immediate entries. */
237  order_check = 0;
238  order_check_failed = 0;
239  usleep(50 * 1000);/* Ensure that all the immediate entries are ready to expire */
240  ast_test_validate_cleanup(test, 7 == ast_sched_runq(con), res, return_cleanup);
241  ast_test_validate_cleanup(test, !order_check_failed, res, return_cleanup);
242 
243  /* Check order of scheduled entries expiring at the same time. */
244  order_check = 0;
245  order_check_failed = 0;
246  usleep((DELAYED_SAME_EXPIRE + 50) * 1000);/* Ensure that all the delayed entries are ready to expire */
247  ast_test_validate_cleanup(test, 8 == ast_sched_runq(con), res, return_cleanup);
248  ast_test_validate_cleanup(test, !order_check_failed, res, return_cleanup);
249 
250  if ((wait = ast_sched_wait(con)) != -1) {
252  "ast_sched_wait() should have returned -1, returned '%d'\n",
253  wait);
254  goto return_cleanup;
255  }
256 
257  res = AST_TEST_PASS;
258 
259 return_cleanup:
261 
262  return res;
263 }
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition: sched.c:755
static int sched_order_2_cb(const void *data)
Definition: test_sched.c:65
static int sched_order_7_cb(const void *data)
Definition: test_sched.c:95
#define NULL
Definition: resample.c:96
#define DELAYED_SAME_EXPIRE
static int order_check
Definition: test_sched.c:46
static int sched_order_5_cb(const void *data)
Definition: test_sched.c:83
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
static int sched_order_4_cb(const void *data)
Definition: test_sched.c:77
static int sched_order_1_cb(const void *data)
Definition: test_sched.c:59
static int sched_cb(const void *data)
Definition: test_sched.c:41
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
static int order_check_failed
Definition: test_sched.c:47
def info(msg)
int ast_sched_del(struct ast_sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event.
Definition: sched.c:610
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
static int sched_order_8_cb(const void *data)
Definition: test_sched.c:101
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition: sched.c:431
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269
ast_test_result_state
Definition: test.h:200
static int sched_order_6_cb(const void *data)
Definition: test_sched.c:89
static int sched_order_3_cb(const void *data)
Definition: test_sched.c:71

◆ handle_cli_sched_bench()

static char* handle_cli_sched_bench ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 265 of file test_sched.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_free, ast_malloc, ast_random(), ast_sched_add(), ast_sched_context_create(), ast_sched_context_destroy(), ast_sched_del(), ast_tvdiff_us(), ast_tvnow(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, sched_cb(), and ast_cli_entry::usage.

266 {
267  struct ast_sched_context *con;
268  struct timeval start;
269  unsigned int num, i;
270  int *sched_ids = NULL;
271 
272  switch (cmd) {
273  case CLI_INIT:
274  e->command = "sched benchmark";
275  e->usage = ""
276  "Usage: sched benchmark <num>\n"
277  "";
278  return NULL;
279  case CLI_GENERATE:
280  return NULL;
281  }
282 
283  if (a->argc != e->args + 1) {
284  return CLI_SHOWUSAGE;
285  }
286 
287  if (sscanf(a->argv[e->args], "%u", &num) != 1) {
288  return CLI_SHOWUSAGE;
289  }
290 
291  if (!(con = ast_sched_context_create())) {
292  ast_cli(a->fd, "Test failed - could not create scheduler context\n");
293  return CLI_FAILURE;
294  }
295 
296  if (!(sched_ids = ast_malloc(sizeof(*sched_ids) * num))) {
297  ast_cli(a->fd, "Test failed - memory allocation failure\n");
298  goto return_cleanup;
299  }
300 
301  ast_cli(a->fd, "Testing ast_sched_add() performance - timing how long it takes "
302  "to add %u entries at random time intervals from 0 to 60 seconds\n", num);
303 
304  start = ast_tvnow();
305 
306  for (i = 0; i < num; i++) {
307  long when = labs(ast_random()) % 60000;
308  if ((sched_ids[i] = ast_sched_add(con, when, sched_cb, NULL)) == -1) {
309  ast_cli(a->fd, "Test failed - sched_add returned -1\n");
310  goto return_cleanup;
311  }
312  }
313 
314  ast_cli(a->fd, "Test complete - %" PRIi64 " us\n", ast_tvdiff_us(ast_tvnow(), start));
315 
316  ast_cli(a->fd, "Testing ast_sched_del() performance - timing how long it takes "
317  "to delete %u entries with random time intervals from 0 to 60 seconds\n", num);
318 
319  start = ast_tvnow();
320 
321  for (i = 0; i < num; i++) {
322  if (ast_sched_del(con, sched_ids[i]) == -1) {
323  ast_cli(a->fd, "Test failed - sched_del returned -1\n");
324  goto return_cleanup;
325  }
326  }
327 
328  ast_cli(a->fd, "Test complete - %" PRIi64 " us\n", ast_tvdiff_us(ast_tvnow(), start));
329 
330 return_cleanup:
332  if (sched_ids) {
333  ast_free(sched_ids);
334  }
335 
336  return CLI_SUCCESS;
337 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int args
This gets set in ast_cli_register()
Definition: cli.h:185
const int fd
Definition: cli.h:159
long int ast_random(void)
Definition: main/utils.c:2064
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
static int sched_cb(const void *data)
Definition: test_sched.c:41
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
Definition: sched.c:236
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
int ast_sched_del(struct ast_sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event.
Definition: sched.c:610
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:565
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
int64_t ast_tvdiff_us(struct timeval end, struct timeval start)
Computes the difference (in microseconds) between two struct timeval instances.
Definition: time.h:78
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
Definition: sched.c:269

◆ load_module()

static int load_module ( void  )
static

Definition at line 350 of file test_sched.c.

References ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_SUCCESS, and AST_TEST_REGISTER.

351 {
352  AST_TEST_REGISTER(sched_test_order);
355 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct ast_cli_entry cli_sched[]
Definition: test_sched.c:339

◆ sched_cb()

static int sched_cb ( const void *  data)
static

Definition at line 41 of file test_sched.c.

Referenced by AST_TEST_DEFINE(), and handle_cli_sched_bench().

42 {
43  return 0;
44 }

◆ sched_order_1_cb()

static int sched_order_1_cb ( const void *  data)
static

Definition at line 59 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

60 {
61  sched_order_check((void *) data, 1);
62  return 0;
63 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_2_cb()

static int sched_order_2_cb ( const void *  data)
static

Definition at line 65 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

66 {
67  sched_order_check((void *) data, 2);
68  return 0;
69 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_3_cb()

static int sched_order_3_cb ( const void *  data)
static

Definition at line 71 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

72 {
73  sched_order_check((void *) data, 3);
74  return 0;
75 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_4_cb()

static int sched_order_4_cb ( const void *  data)
static

Definition at line 77 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

78 {
79  sched_order_check((void *) data, 4);
80  return 0;
81 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_5_cb()

static int sched_order_5_cb ( const void *  data)
static

Definition at line 83 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

84 {
85  sched_order_check((void *) data, 5);
86  return 0;
87 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_6_cb()

static int sched_order_6_cb ( const void *  data)
static

Definition at line 89 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

90 {
91  sched_order_check((void *) data, 6);
92  return 0;
93 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_7_cb()

static int sched_order_7_cb ( const void *  data)
static

Definition at line 95 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

96 {
97  sched_order_check((void *) data, 7);
98  return 0;
99 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_8_cb()

static int sched_order_8_cb ( const void *  data)
static

Definition at line 101 of file test_sched.c.

References sched_order_check().

Referenced by AST_TEST_DEFINE().

102 {
103  sched_order_check((void *) data, 8);
104  return 0;
105 }
static void sched_order_check(struct ast_test *test, int order)
Definition: test_sched.c:49

◆ sched_order_check()

static void sched_order_check ( struct ast_test test,
int  order 
)
static

Definition at line 49 of file test_sched.c.

References ast_test_status_update, order_check, and order_check_failed.

Referenced by sched_order_1_cb(), sched_order_2_cb(), sched_order_3_cb(), sched_order_4_cb(), sched_order_5_cb(), sched_order_6_cb(), sched_order_7_cb(), and sched_order_8_cb().

50 {
51  ++order_check;
52  if (order_check != order) {
53  ast_test_status_update(test, "Unexpected execution order: expected:%d got:%d\n",
56  }
57 }
static int order_check
Definition: test_sched.c:46
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
integer order
Definition: analys.c:66
static int order_check_failed
Definition: test_sched.c:47

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 343 of file test_sched.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), and AST_TEST_UNREGISTER.

344 {
345  AST_TEST_UNREGISTER(sched_test_order);
347  return 0;
348 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct ast_cli_entry cli_sched[]
Definition: test_sched.c:339
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "ast_sched performance test module" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 357 of file test_sched.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 357 of file test_sched.c.

◆ cli_sched

struct ast_cli_entry cli_sched[]
static
Initial value:
= {
{ .handler = handle_cli_sched_bench , .summary = "Benchmark ast_sched add/del performance" ,},
}
static char * handle_cli_sched_bench(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: test_sched.c:265

Definition at line 339 of file test_sched.c.

◆ order_check

int order_check
static

Definition at line 46 of file test_sched.c.

Referenced by AST_TEST_DEFINE(), and sched_order_check().

◆ order_check_failed

int order_check_failed
static

Definition at line 47 of file test_sched.c.

Referenced by AST_TEST_DEFINE(), and sched_order_check().