123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- /*
- * lat_msgqueue.c - simple message queue latency test
- *
- * Three programs in one -
- * server usage: tcp_xact -s
- * client usage: tcp_xact hostname
- * shutwn: tcp_xact -hostname
- *
- * Copyright (c) 1994 Larry McVoy. Distributed under the FSF GPL with
- * additional restriction that results may published only if
- * (1) the benchmark is unmodified, and
- * (2) the version in the sccsid below is included in the report.
- * Support for this development by Sun Microsystems is gratefully acknowledged.
- */
- char *id = "$Id$\n";
- #include "bench.h"
- #include <sys/ipc.h>
- #include <sys/msg.h>
- int
- create_q(int key)
- {
- return msgget(key, IPC_CREAT|0600);
- }
- int
- open_q(int key)
- {
- return msgget(key, 0);
- }
- void
- close_q(int id)
- {
- msgctl(id, IPC_RMID, NULL);
- }
- void
- create_close_q(int key)
- {
- int id = create_q(key);
- close_q(id);
- }
- void
- create_open_close_q(int key)
- {
- int id = create_q(key);
- open_q(key);
- close_q(id);
- }
- void
- create_server(int pipes[2])
- {
- int i, begin = 0, end = 0;
- int key, id = 0;
- while (read(pipes[0], &key, sizeof(int)) == sizeof(int)) {
- if (id) close_q(id);
- id = create_q(key);
- if (write(pipes[1], &id, sizeof(int)) < sizeof(int)) {
- perror("write");
- exit(1);
- }
- }
- if (id) close_q(id);
- }
- int
- client_create_q(int pipes[2], int key)
- {
- int id;
- if (write(pipes[1], &key, sizeof(int)) < sizeof(int)) {
- perror("write");
- exit(1);
- }
- if (read(pipes[0], &id, sizeof(int)) < sizeof(int)) {
- perror("read");
- exit(1);
- }
- return id;
- }
- int
- client_create_open_q(int pipes[2], int key)
- {
- int id;
- if (write(pipes[1], &key, sizeof(int)) < sizeof(int)) {
- perror("write");
- exit(1);
- }
- if (read(pipes[0], &id, sizeof(int)) < sizeof(int)) {
- perror("read");
- exit(1);
- }
- return open_q(key);
- }
- void
- send_q(int *id, int n)
- {
- if (n % 5000 == 0) {
- close_q(*id);
- *id = create_q(0);
- }
- struct {
- long mtype;
- char mtext[1];
- } buf;
- buf.mtype = 1;
- msgsnd(*id, &buf, 1, 0);
- }
- void
- receive_q(int id)
- {
- struct {
- long mtype;
- char mtext[1];
- } buf;
- if (msgrcv(id, &buf, 1, 1, 0) < 1) {
- perror("msgrcv");
- exit(1);
- }
- }
- void
- send_receive_q(int *id, int n)
- {
- send_q(id, n);
- receive_q(*id);
- }
- void
- send_server(int pipes[2], int *id)
- {
- int n;
- while (read(pipes[0], &n, sizeof(int)) == sizeof(int)) {
- send_q(id, n);
- if (write(pipes[1], id, sizeof(int)) < sizeof(int)) {
- perror("write");
- exit(1);
- }
- }
- }
- void
- client_send_q(int pipes[2], int n)
- {
- int id;
- if (write(pipes[1], &n, sizeof(int)) < sizeof(int)) {
- perror("write");
- exit(1);
- }
- if (read(pipes[0], &id, sizeof(int)) < sizeof(int)) {
- perror("read");
- exit(1);
- }
- }
- void
- client_send_receive_q(int pipes[2], int n)
- {
- int id;
- if (write(pipes[1], &n, sizeof(int)) < sizeof(int)) {
- perror("write");
- exit(1);
- }
- if (read(pipes[0], &id, sizeof(int)) < sizeof(int)) {
- perror("read");
- exit(1);
- }
- receive_q(id);
- }
- int
- main(int ac, char **av)
- {
- if (ac < 2) goto usage;
- if (!strcmp("create", av[1])) {
- int i, cnt = 0;
- BENCH(create_close_q(++cnt), REAL_SHORT);
- micro("message queue creation and close latency", get_n());
- } else if (!strcmp("fork-create", av[1])) {
- if (fork() == 0) {
- int i, cnt = 0;
- BENCH(create_close_q(++cnt), REAL_SHORT);
- micro("message queue creation lnd close atency after fork",
- get_n());
- exit(0);
- }
- wait(NULL);
- } else if (!strcmp("open", av[1])) {
- int i, cnt = 0;
- BENCHO(create_open_close_q(++cnt), create_close_q(++cnt), REAL_SHORT);
- micro("message queue open latency", get_n());
- for (i = 1 ; i <= cnt ; i++)
- close_q(open_q(i));
- } else if (!strcmp("fork-open", av[1])) {
- int pipes[4];
- if (pipe(pipes) < 0 || pipe(pipes + 2) < 0) {
- perror("pipe");
- exit(1);
- }
- if (fork() == 0) {
- close(pipes[0]); close(pipes[3]); pipes[0] = pipes[2];
- int i, cnt = 0;
- BENCHO(client_create_open_q(pipes, ++cnt),
- client_create_q(pipes, ++cnt), REAL_SHORT);
- micro("message queue open latency after fork",
- get_n());
- exit(0);
- }
- close(pipes[1]); close(pipes[2]); pipes[1] = pipes[3];
- create_server(pipes);
- } else if (!strcmp("send", av[1])) {
- int id = create_q(0);
- int cnt = 0;
- BENCH(send_q(&id, ++cnt), REAL_SHORT);
- micro("message queue sending latency", get_n());
- close_q(id);
- } else if (!strcmp("fork-send", av[1])) {
- int id = create_q(0);
- int cnt = 0;
- if (fork() == 0) {
- BENCH(send_q(&id, ++cnt), REAL_SHORT);
- micro("message queue sending latency after fork",
- get_n());
- close_q(id);
- exit(0);
- }
- wait(NULL);
- } else if (!strcmp("receive", av[1])) {
- int id = create_q(0);
- int cnt = 0;
- BENCHO(send_receive_q(&id, ++cnt), send_q(&id, ++cnt), REAL_SHORT);
- micro("message queue receiving latency", get_n());
- close_q(id);
- } else if (!strcmp("fork-receive", av[1])) {
- int id = create_q(0);
- int cnt = 0;
- int pipes[4];
- if (pipe(pipes) < 0 || pipe(pipes + 2) < 0) {
- perror("pipe");
- exit(1);
- }
- if (fork() == 0) {
- close(pipes[0]); close(pipes[3]); pipes[0] = pipes[2];
- BENCHO(client_send_receive_q(pipes, ++cnt),
- client_send_q(pipes, ++cnt), REAL_SHORT);
- micro("message queue receiving latency after fork",
- get_n());
- exit(0);
- }
- close(pipes[1]); close(pipes[2]); pipes[1] = pipes[3];
- send_server(pipes, &id);
- close_q(id);
- } else {
- usage: printf("Usage: %s create|fork-create|open|fork-open"
- "|send|fork-send|receive|fork-receive\n", av[0]);
- }
- return(0);
- }
|