123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /*
- * This file is part of the Sofia-SIP package
- *
- * Copyright (C) 2005 Nokia Corporation.
- *
- * Contact: Pekka Pessi <pekka.pessi@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
- /**@ingroup su_root_ex
- * @CFILE su_perf.c
- *
- * Performance test for su message passing
- *
- * @internal
- *
- * @author Pekka Pessi <Pekka.Pessi@nokia.com>
- *
- * @date Created: Thu Mar 18 19:40:51 1999 pessi
- */
- #include "config.h"
- #include <stdlib.h>
- #include <assert.h>
- #include <stdio.h>
- #include <string.h>
- struct perf;
- #define SU_ROOT_MAGIC_T struct perf
- #define SU_MSG_ARG_T struct message
- #include "sofia-sip/su.h"
- #include "sofia-sip/su_wait.h"
- struct perf {
- enum { PINGER = 1, PONGER = 2 } const sort;
- char const *const name;
- unsigned running : 1;
- unsigned target;
- unsigned n;
- su_root_t *root;
- struct sockaddr_in sin;
- };
- struct message {
- su_time_t started;
- };
- void
- do_exit(struct perf *x, su_msg_r msg, struct message *m)
- {
- su_root_break(su_task_root(su_msg_to(msg)));
- }
- int
- do_init(su_root_t *root, struct perf *p)
- {
- p->root = root;
- return 0;
- }
- void
- do_print(struct perf *p, su_msg_r msg, struct message *m)
- {
- su_time_t now = su_now();
- double dur = su_time_diff(now, m->started);
- printf("su_perf: %g message exchanges per second"
- " (%d message exchanges in %g seconds)\n",
- (double)p->n / dur, p->n, dur);
- su_msg_create(msg, su_root_parent(p->root), su_root_task(p->root),
- do_exit, sizeof(*m));
- *su_msg_data(msg) = *m;
- su_msg_send(msg);
- }
- void
- do_ping(struct perf *p, su_msg_r msg, struct message *m)
- {
- if (p->sort == PINGER) {
- p->n++;
- if (p->n % 100 == 0) {
- if (su_duration(su_now(), m->started) > p->target) {
- do_print(p, msg, m);
- return;
- }
- }
- }
- su_msg_reply(msg, msg, do_ping, sizeof(*m));
- *su_msg_data(msg) = *m;
- su_msg_send(msg);
- }
- void
- do_destroy(su_root_t *t, struct perf *p)
- {
- p->running = 0;
- }
- void usage(char *name)
- {
- fprintf(stderr, "usage: %s [-1] [n]\n", name);
- exit(2);
- }
- /*
- * Measure how many message passes can be done in a second.
- *
- * Create a ponger and pinger, responding to incoming message do_ping
- *
- * After "target" rounds, print out elapsed time and number of messages
- * passed.
- *
- */
- int main(int argc, char *argv[])
- {
- su_root_t *root;
- su_clone_r ping = SU_CLONE_R_INIT, pong = SU_CLONE_R_INIT;
- su_msg_r start_msg = SU_MSG_R_INIT;
- struct perf
- pinger = { PINGER, "ping", 1, 0 },
- ponger = { PONGER, "pong", 1, 0x7fffffff};
- int have_threads = 1;
- char *argv0 = argv[0];
- char *argv1 = argv[1];
- if (argv1 && strcmp(argv1, "-1") == 0)
- have_threads = 0, argv1 = argv[2];
- if (!argv1)
- argv1 = "10000";
- if (strlen(argv1) != strspn(argv1, "0123456789"))
- usage(argv0);
- pinger.target = strtoul(argv1, NULL, 0);
- su_init(); atexit(su_deinit);
- root = su_root_create(NULL);
- su_root_threading(root, have_threads);
- if (su_clone_start(root, ping, &pinger, do_init, do_destroy) != 0)
- perror("su_clone_start"), exit(1);
- if (su_clone_start(root, pong, &ponger, do_init, do_destroy) != 0)
- perror("su_clone_start"), exit(1);
- if (su_msg_create(start_msg, su_clone_task(pong), su_clone_task(ping),
- do_ping, sizeof(struct message)) == 0) {
- su_msg_data(start_msg)->started = su_now();
- su_msg_send(start_msg);
- su_root_run(root);
- }
- #if 0
- su_clone_wait(root, ping);
- su_clone_wait(root, pong);
- while (pinger.running || ponger.running)
- su_root_step(root, 100L);
- #endif
- su_root_destroy(root);
- return 0;
- }
|