Home | History | Annotate | Download | only in tirpc_bottomlevel_clnt_call
      1 /*
      2 * Copyright (c) Bull S.A.  2007 All Rights Reserved.
      3 *
      4 * This program is free software; you can redistribute it and/or modify it
      5 * under the terms of version 2 of the GNU General Public License as
      6 * published by the Free Software Foundation.
      7 *
      8 * This program is distributed in the hope that it would be useful, but
      9 * WITHOUT ANY WARRANTY; without even the implied warranty of
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     11 *
     12 * Further, this software is distributed without any warranty that it is
     13 * free of the rightful claim of any third person regarding infringement
     14 * or the like.  Any license provided herein, whether implied or
     15 * otherwise, applies only to this software file.  Patent licenses, if
     16 * any, provided herein do not apply to combinations of this program with
     17 * other software, or any other product whatsoever.
     18 *
     19 * You should have received a copy of the GNU General Public License along
     20 * with this program; if not, write the Free Software Foundation, Inc.,
     21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     22 *
     23 * History:
     24 * Created by: Cyril Lacabanne (Cyril.Lacabanne (at) bull.net)
     25 *
     26 */
     27 
     28 #include <stdio.h>
     29 #include <stdlib.h>
     30 #include <pthread.h>
     31 #include <time.h>
     32 #include <tirpc/netconfig.h>
     33 #include <tirpc/rpc/rpc.h>
     34 #include <tirpc/rpc/types.h>
     35 #include <tirpc/rpc/xdr.h>
     36 #include <tirpc/rpc/svc.h>
     37 #include <errno.h>
     38 
     39 //Standard define
     40 #define PROCNUM 1
     41 #define VERSNUM 1
     42 
     43 //Sys define
     44 #define ADDRBUFSIZE 100
     45 
     46 static double *thread_time_result;
     47 static int maxThd = 1;
     48 int run_mode;
     49 int progNum;
     50 int callNb;
     51 char *nettype = "visible";
     52 char *hostname;
     53 
     54 void *my_thread_process(void *arg)
     55 {
     56 	int i;
     57 	CLIENT *client = NULL;
     58 	struct netconfig *nconf = NULL;
     59 	struct netbuf svcaddr;
     60 	char addrbuf[ADDRBUFSIZE];
     61 	int var_snd = 0;
     62 	int var_rec = -1;
     63 	struct timeval tv;
     64 
     65 	if (run_mode == 1) {
     66 		fprintf(stderr, "Thread %d\n", atoi(arg));
     67 	}
     68 
     69 	tv.tv_sec = 0;
     70 	tv.tv_usec = 100;
     71 
     72 	nconf = getnetconfigent("udp");
     73 	if (nconf == NULL) {
     74 		//syslog(LOG_ERR, "getnetconfigent for udp failed");
     75 		fprintf(stderr, "err nconf\n");
     76 		printf("5\n");
     77 		exit(1);
     78 	}
     79 
     80 	svcaddr.len = 0;
     81 	svcaddr.maxlen = ADDRBUFSIZE;
     82 	svcaddr.buf = addrbuf;
     83 
     84 	if (svcaddr.buf == NULL) {
     85 		/* if malloc() failed, print error messages and exit */
     86 		printf("5\n");
     87 		exit(1);
     88 	}
     89 	//printf("svcaddr reserved (%s)\n", argc[1]);
     90 
     91 	if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, hostname)) {
     92 		fprintf(stderr, "rpcb_getaddr failed!!\n");
     93 		printf("5\n");
     94 		exit(1);
     95 	}
     96 	//printf("svc get\n");
     97 
     98 	client = clnt_dg_create(RPC_ANYFD, &svcaddr,
     99 				progNum, VERSNUM, 1024, 1024);
    100 
    101 	if (client == NULL) {
    102 		clnt_pcreateerror("ERR");
    103 		printf("5\n");
    104 		exit(1);
    105 	}
    106 
    107 	for (i = 0; i < callNb; i++) {
    108 		clnt_call(client, PROCNUM,
    109 			  (xdrproc_t) xdr_int, (char *)&var_snd,
    110 			  (xdrproc_t) xdr_int, (char *)&var_rec, tv);
    111 	}
    112 
    113 	clnt_destroy(client);
    114 
    115 	pthread_exit(0);
    116 }
    117 
    118 int main(int argn, char *argc[])
    119 {
    120 	//Program parameters : argc[1] : HostName or Host IP
    121 	//                                         argc[2] : Server Program Number
    122 	//                                         argc[3] : Maximal number of threads
    123 	//                                         argc[4] : Number of calls per thread
    124 	//                                         other arguments depend on test case
    125 
    126 	//run_mode can switch into stand alone program or program launch by shell script
    127 	//1 : stand alone, debug mode, more screen information
    128 	//0 : launch by shell script as test case, only one printf -> result status
    129 	run_mode = 0;
    130 	int test_status = 1;	//Default test result set to FAILED
    131 	int i;
    132 	long j;
    133 	int threadNb = atoi((char *)argc[3]);
    134 	int curThd = 1;
    135 
    136 	//Thread declarations
    137 	pthread_t *pThreadArray;
    138 	void *ret = NULL;
    139 	pthread_attr_t thread_attr;
    140 	int ssz = 0;
    141 
    142 	//Time measurement declarations
    143 	struct timeval tv1, tv2;
    144 	struct timezone tz;
    145 	long long diff;
    146 	double rslt;
    147 
    148 	//Program initialization
    149 	progNum = atoi((char *)argc[2]);
    150 	callNb = atoi((char *)argc[4]);
    151 	hostname = (char *)argc[1];
    152 
    153 	//Initialization
    154 	maxThd = maxThd << (threadNb - 1);	//Set the maximum threads number
    155 
    156 	pthread_attr_init(&thread_attr);
    157 
    158 	if (run_mode == 1) {
    159 		pthread_attr_getstacksize(&thread_attr, (size_t *) & ssz);	//For debug purpose, get default thread stack size
    160 		fprintf(stderr, "Server #%d\n", progNum);
    161 		fprintf(stderr, "Calls per thread : %d\n", callNb);
    162 		fprintf(stderr, "Instances : %d\n", threadNb);
    163 		fprintf(stderr, "Max threads to create : %d\n", maxThd);
    164 		fprintf(stderr, "Standard thread stack size in bytes %d\n",
    165 			ssz);
    166 	}
    167 
    168 	pthread_attr_setstacksize(&thread_attr, 40000);	//Set thread stack size to 40 KB
    169 
    170 	//Init results table
    171 	thread_time_result = malloc((threadNb) * sizeof(double));
    172 	memset(&thread_time_result[0], (double)0, (threadNb) * sizeof(double));
    173 
    174 	//Create all threads
    175 	//Run all threads
    176 	pThreadArray = malloc(maxThd * sizeof(pthread_t));
    177 
    178 	for (i = 0; i < threadNb; i++) {
    179 		if (run_mode)
    180 			fprintf(stderr, "Threads for pass %d : %d\n", i,
    181 				curThd);
    182 
    183 		gettimeofday(&tv1, &tz);
    184 
    185 		for (j = 0; j < curThd; j++) {
    186 			//Create thread using defined parameters (stack size = 40 KB)
    187 			if (pthread_create
    188 			    (&pThreadArray[j], &thread_attr, my_thread_process,
    189 			     (void *)j) != 0) {
    190 				fprintf(stderr,
    191 					"pthread_create error for thread %ld\n",
    192 					j);
    193 				printf("1\n");
    194 				exit(1);
    195 			}
    196 		}
    197 
    198 		//Clean threads
    199 		for (j = 0; j < curThd; j++) {
    200 			if ((pthread_t *) pThreadArray[j] != NULL) {
    201 				(void)pthread_join(pThreadArray[j], &ret);
    202 			} else {
    203 				fprintf(stderr, "pThread Join Err : %ld\n", j);
    204 			}
    205 		}
    206 
    207 		gettimeofday(&tv2, &tz);
    208 
    209 		//Calculate and store delay to table results
    210 		diff =
    211 		    (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec -
    212 							    tv1.tv_usec);
    213 		rslt = (double)diff / 1000;
    214 		thread_time_result[i] = rslt;
    215 
    216 		curThd = curThd * 2;
    217 	}
    218 
    219 	//Check if all threads results are ok
    220 	test_status = 0;
    221 	for (i = 0; i < threadNb; i++) {
    222 		if (thread_time_result[i] == 0) {
    223 			test_status = 1;
    224 			break;
    225 		}
    226 	}
    227 
    228 	//This last printf gives the result status to the tests suite
    229 	//normally should be 0: test has passed or 1: test has failed
    230 	printf("%d\n", test_status);
    231 
    232 	//Print scalability results
    233 	curThd = 1;
    234 	for (i = 0; i < threadNb; i++) {
    235 		printf("%d %lf\n", curThd, thread_time_result[i]);
    236 		curThd = curThd * 2;
    237 	}
    238 
    239 	return test_status;
    240 }
    241