2
0

su_perf.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * This file is part of the Sofia-SIP package
  3. *
  4. * Copyright (C) 2005 Nokia Corporation.
  5. *
  6. * Contact: Pekka Pessi <pekka.pessi@nokia.com>
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. * 02110-1301 USA
  22. *
  23. */
  24. /**@ingroup su_root_ex
  25. * @CFILE su_perf.c
  26. *
  27. * Performance test for su message passing
  28. *
  29. * @internal
  30. *
  31. * @author Pekka Pessi <Pekka.Pessi@nokia.com>
  32. *
  33. * @date Created: Thu Mar 18 19:40:51 1999 pessi
  34. */
  35. #include "config.h"
  36. #include <stdlib.h>
  37. #include <assert.h>
  38. #include <stdio.h>
  39. #include <string.h>
  40. struct perf;
  41. #define SU_ROOT_MAGIC_T struct perf
  42. #define SU_MSG_ARG_T struct message
  43. #include "sofia-sip/su.h"
  44. #include "sofia-sip/su_wait.h"
  45. struct perf {
  46. enum { PINGER = 1, PONGER = 2 } const sort;
  47. char const *const name;
  48. unsigned running : 1;
  49. unsigned target;
  50. unsigned n;
  51. su_root_t *root;
  52. struct sockaddr_in sin;
  53. };
  54. struct message {
  55. su_time_t started;
  56. };
  57. void
  58. do_exit(struct perf *x, su_msg_r msg, struct message *m)
  59. {
  60. su_root_break(su_task_root(su_msg_to(msg)));
  61. }
  62. int
  63. do_init(su_root_t *root, struct perf *p)
  64. {
  65. p->root = root;
  66. return 0;
  67. }
  68. void
  69. do_print(struct perf *p, su_msg_r msg, struct message *m)
  70. {
  71. su_time_t now = su_now();
  72. double dur = su_time_diff(now, m->started);
  73. printf("su_perf: %g message exchanges per second"
  74. " (%d message exchanges in %g seconds)\n",
  75. (double)p->n / dur, p->n, dur);
  76. su_msg_create(msg, su_root_parent(p->root), su_root_task(p->root),
  77. do_exit, sizeof(*m));
  78. *su_msg_data(msg) = *m;
  79. su_msg_send(msg);
  80. }
  81. void
  82. do_ping(struct perf *p, su_msg_r msg, struct message *m)
  83. {
  84. if (p->sort == PINGER) {
  85. p->n++;
  86. if (p->n % 100 == 0) {
  87. if (su_duration(su_now(), m->started) > p->target) {
  88. do_print(p, msg, m);
  89. return;
  90. }
  91. }
  92. }
  93. su_msg_reply(msg, msg, do_ping, sizeof(*m));
  94. *su_msg_data(msg) = *m;
  95. su_msg_send(msg);
  96. }
  97. void
  98. do_destroy(su_root_t *t, struct perf *p)
  99. {
  100. p->running = 0;
  101. }
  102. void usage(char *name)
  103. {
  104. fprintf(stderr, "usage: %s [-1] [n]\n", name);
  105. exit(2);
  106. }
  107. /*
  108. * Measure how many message passes can be done in a second.
  109. *
  110. * Create a ponger and pinger, responding to incoming message do_ping
  111. *
  112. * After "target" rounds, print out elapsed time and number of messages
  113. * passed.
  114. *
  115. */
  116. int main(int argc, char *argv[])
  117. {
  118. su_root_t *root;
  119. su_clone_r ping = SU_CLONE_R_INIT, pong = SU_CLONE_R_INIT;
  120. su_msg_r start_msg = SU_MSG_R_INIT;
  121. struct perf
  122. pinger = { PINGER, "ping", 1, 0 },
  123. ponger = { PONGER, "pong", 1, 0x7fffffff};
  124. int have_threads = 1;
  125. char *argv0 = argv[0];
  126. char *argv1 = argv[1];
  127. if (argv1 && strcmp(argv1, "-1") == 0)
  128. have_threads = 0, argv1 = argv[2];
  129. if (!argv1)
  130. argv1 = "10000";
  131. if (strlen(argv1) != strspn(argv1, "0123456789"))
  132. usage(argv0);
  133. pinger.target = strtoul(argv1, NULL, 0);
  134. su_init(); atexit(su_deinit);
  135. root = su_root_create(NULL);
  136. su_root_threading(root, have_threads);
  137. if (su_clone_start(root, ping, &pinger, do_init, do_destroy) != 0)
  138. perror("su_clone_start"), exit(1);
  139. if (su_clone_start(root, pong, &ponger, do_init, do_destroy) != 0)
  140. perror("su_clone_start"), exit(1);
  141. if (su_msg_create(start_msg, su_clone_task(pong), su_clone_task(ping),
  142. do_ping, sizeof(struct message)) == 0) {
  143. su_msg_data(start_msg)->started = su_now();
  144. su_msg_send(start_msg);
  145. su_root_run(root);
  146. }
  147. #if 0
  148. su_clone_wait(root, ping);
  149. su_clone_wait(root, pong);
  150. while (pinger.running || ponger.running)
  151. su_root_step(root, 100L);
  152. #endif
  153. su_root_destroy(root);
  154. return 0;
  155. }