©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c7/msg_time.c

Go to the documentation of this file.
00001 /*
00002     IPC timing comparisons
00003     AUP2, Sec. 7.15
00004 
00005     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00006     May be copied only for purposes and under conditions described
00007     on the Web page www.basepath.com/aup/copyright.htm.
00008 
00009     The Example Files are provided "as is," without any warranty;
00010     without even the implied warranty of merchantability or fitness
00011     for a particular purpose. The author and his publisher are not
00012     responsible for any damages, direct or incidental, resulting
00013     from the use or non-use of these Example Files.
00014 
00015     The Example Files may contain defects, and some contain deliberate
00016     coding mistakes that were included for educational reasons.
00017     You are responsible for determining if and how the Example Files
00018     are to be used.
00019 
00020 */
00021 /*[top]*/
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> /* required for arpa/inet.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     Problem: Server can't just exit when finished, as closing its queue kills semaphores (etc.) that may be needed.
00090 */
00091 /*
00092     We end up with an opened server in each child, which isn't right, but should not affect timing. Delaying opening the server until the child processes are created would involve making the children wait for the server to start, which involves extra mechanisms. The smi routines typically don't provide for this.
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             /* fall through */
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 }

Generated on Fri Apr 23 10:56:58 2004 for AUP2 Example Source by doxygen 1.3.1