00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "defs.h"
00023 #include "smi_fifo.h"
00024 #include "smi_msg.h"
00025 #include "smi_skt.h"
00026 #include "smi_shm.h"
00027 #include "smi_pshm.h"
00028 #include "smi_mq.h"
00029 #include "../c6/pcsync_sig.h"
00030 #include <sys/wait.h>
00031 #ifdef FREEBSD
00032 #include <netinet/in.h>
00033 #endif
00034 #include <arpa/inet.h>
00035
00036 #define NUM_MSGS 500
00037 #define NUM_CLIENTS 4
00038 #define SERVERNAME_LOCAL "MsgTime"
00039 #define SERVERNAME_INET "//localhost:30001"
00040
00041 #define MSG_LEN SMI_MSG_MAX
00042 static int num_msgs = NUM_MSGS;
00043 static int len_msg = 100;
00044 static bool want_check = true;
00045 static bool pcsync = true;
00046 static bool quiet = false;
00047
00048 static bool run_server = true, run_clients = true;
00049 static const char *hostarg = NULL;
00050
00051 typedef enum {MSGCHK_SET, MSGCHK_CALC, MSGCHK_CHK} MSGCHK_OP;
00052
00053 static bool msg_check(void *mbuf, MSGCHK_OP op)
00054 {
00055 struct smi_msg *m = (struct smi_msg *)mbuf;
00056 int n = len_msg / sizeof(long);
00057 long *a = (long *)m->smi_data, sum;
00058 int i;
00059 pid_t pid = getpid();
00060
00061 if (!want_check)
00062 return true;
00063 switch (op) {
00064 case MSGCHK_SET:
00065 for (i = 1; i < n; i++)
00066 a[i] = htonl(pid + i);
00067 break;
00068 case MSGCHK_CALC:
00069 case MSGCHK_CHK:
00070 sum = 0;
00071 for (i = 1; i < n; i++)
00072 sum += ntohl(a[i]);
00073 if (op == MSGCHK_CALC)
00074 a[0] = htonl(sum);
00075 else if (ntohl(a[0]) != sum) {
00076 errno = 0;
00077 fprintf(stderr, "msg_time: message failed check\n");
00078 EC_FAIL
00079 }
00080 }
00081 return true;
00082
00083 EC_CLEANUP_BGN
00084 return false;
00085 EC_CLEANUP_END
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095 #define time_traffic(method)\
00096 static bool method##_time(const char *servername)\
00097 {\
00098 int i, k;\
00099 bool bchild = false;\
00100 pid_t pid_client[NUM_CLIENTS], pid;\
00101 SMIQ *sqp;\
00102 struct pcsync pcs;\
00103 \
00104 printf("\n" #method "(%s):\n", servername);\
00105 timestart();\
00106 if (pcsync)\
00107 ec_false( pcsync_init(&pcs) )\
00108 if (run_clients)\
00109 for (k = 0; k < NUM_CLIENTS; k++)\
00110 switch (pid_client[k] = fork()) {\
00111 case -1:\
00112 syserr("fork 2");\
00113 case 0:\
00114 if (pcsync)\
00115 ec_false( pcsync_wait_for_parent(&pcs) )\
00116 if (pcsync)\
00117 (void)pcsync_end(&pcs);\
00118 if (!quiet)\
00119 printf("\tProcess %d running freely\n",\
00120 (int)getpid());\
00121 bchild = true;\
00122 ec_null( sqp = smi_open_##method(servername, SMI_CLIENT,\
00123 len_msg) )\
00124 for (i = 0; i < num_msgs; i++) {\
00125 struct smi_msg *msg;\
00126 ec_false( smi_send_getaddr_##method(sqp, NULL,\
00127 (void **)&msg) )\
00128 ec_false( msg_check(msg, MSGCHK_SET) )\
00129 ec_false( smi_send_release_##method(sqp) )\
00130 ec_false( smi_receive_getaddr_##method(sqp,\
00131 (void **)&msg) )\
00132 ec_false( msg_check(msg, MSGCHK_CHK) )\
00133 ec_false( smi_receive_release_##method(sqp) )\
00134 }\
00135 if (!quiet)\
00136 printf("\t" #method\
00137 " client (process %d) exiting normally\n",\
00138 (int)getpid());\
00139 ec_false( smi_close_##method(sqp) )\
00140 exit(EXIT_SUCCESS);\
00141 }\
00142 if (pcsync && run_clients && strcmp(#method, "fifo") == 0)\
00143 ec_false( pcsync_unblock_children(&pcs, NUM_CLIENTS, pid_client) )\
00144 if (run_server)\
00145 ec_null( sqp = smi_open_##method(servername, SMI_SERVER,\
00146 len_msg) )\
00147 if (pcsync && run_clients && strcmp(#method, "fifo") != 0)\
00148 ec_false( pcsync_unblock_children(&pcs, NUM_CLIENTS, pid_client) )\
00149 if (pcsync)\
00150 (void)pcsync_end(&pcs);\
00151 if (run_server)\
00152 for (i = 0; i < NUM_CLIENTS * num_msgs; i++) {\
00153 struct smi_msg *msg;\
00154 \
00155 (void)alarm(200);\
00156 ec_false( smi_receive_getaddr_##method(sqp, (void **)&msg) )\
00157 ec_false( msg_check(msg, MSGCHK_CALC) )\
00158 ec_false( smi_send_getaddr_##method(sqp, &msg->smi_client,\
00159 (void **)&msg) )\
00160 ec_false( smi_receive_release_##method(sqp) )\
00161 ec_false( smi_send_release_##method(sqp) )\
00162 }\
00163 if (!quiet)\
00164 printf("\tServer waiting for client termination...\n");\
00165 for (k = 0; k < NUM_CLIENTS; k++) {\
00166 ec_neg1( waitpid(pid_client[k], NULL, 0) )\
00167 if (!quiet)\
00168 printf("\tProcess %d terminated.\n", (int)pid);\
00169 }\
00170 if (!quiet)\
00171 printf("\t" #method " server (process %d) exiting normally\n",\
00172 (int)getpid());\
00173 if (run_server)\
00174 ec_false( smi_close_##method(sqp) )\
00175 timestop(#method);\
00176 return true;\
00177 \
00178 EC_CLEANUP_BGN\
00179 if (bchild)\
00180 exit(EXIT_FAILURE);\
00181 EC_FLUSH(#method " failed")\
00182 return false;\
00183 EC_CLEANUP_END\
00184 }
00185
00186 time_traffic(fifo)
00187 time_traffic(skt)
00188 time_traffic(msg)
00189 time_traffic(mq)
00190 time_traffic(shm)
00191 #if !defined(FREEBSD) && !defined(LINUX)
00192 time_traffic(pshm)
00193 #endif
00194
00195 static void handler(int signum)
00196 {
00197 if (signum == SIGALRM)
00198 (void)write(STDOUT_FILENO, "Alarm Clock -- ignore times\n", 29);
00199 }
00200
00201 int main(int argc, char *argv[])
00202 {
00203 int c;
00204 struct sigaction act;
00205
00206 memset(&act, 0, sizeof(act));
00207 act.sa_handler = handler;
00208 ec_neg1( sigaction(SIGALRM, &act, NULL) )
00209 setbuf(stdout, NULL);
00210 while ((c = getopt(argc, argv, ":ch:stl:xn:qp")) != -1)
00211 switch(c) {
00212 case 'c':
00213 run_clients = false;
00214 break;
00215 case 'h':
00216 hostarg = optarg;
00217 break;
00218 case 'l':
00219 len_msg = atoi(optarg);
00220 break;
00221 case 'n':
00222 num_msgs = atoi(optarg);
00223 break;
00224 case 's':
00225 run_server = false;
00226 break;
00227 case 't':
00228 num_msgs = 100;
00229 break;
00230 case 'q':
00231 quiet = true;
00232 break;
00233 case 'x':
00234 want_check = false;
00235 break;
00236 case 'p':
00237 pcsync = false;
00238 break;
00239 case ':':
00240 fprintf(stderr, "Option -h requires argument.\n");
00241
00242 default:
00243 fprintf(stderr, "Usage: mt [-c] [-s] [-t] [-h host]"
00244 " [-n nummsgs] [-l msglen] [-q] [-p]\n");
00245 exit(EXIT_FAILURE);
00246 }
00247
00248 #if 1
00249 system("ipcrem >/dev/null 2>/dev/null");
00250 #else
00251 printf("ipcrem not executed\n");
00252 #endif
00253 smi_client_nowait = true;
00254 printf("%d messages of %d bytes; %d clients\n", num_msgs,
00255 len_msg, NUM_CLIENTS);
00256 if (hostarg != NULL)
00257 skt_time(hostarg);
00258 else {
00259 fifo_time(SERVERNAME_LOCAL);
00260 skt_time(SERVERNAME_LOCAL);
00261 skt_time(SERVERNAME_INET);
00262 shm_time(SERVERNAME_LOCAL);
00263 msg_time(SERVERNAME_LOCAL);
00264 mq_time(SERVERNAME_LOCAL);
00265 #if !defined(FREEBSD) && !defined(LINUX)
00266 pshm_time(SERVERNAME_LOCAL);
00267 #endif
00268 }
00269 printf("Done\n");
00270 exit(EXIT_SUCCESS);
00271
00272 EC_CLEANUP_BGN
00273 exit(EXIT_FAILURE);
00274 EC_CLEANUP_END
00275 }