aboutsummaryrefslogtreecommitdiff
path: root/src/tools/perf_replies.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/perf_replies.c')
-rw-r--r--src/tools/perf_replies.c280
1 files changed, 270 insertions, 10 deletions
diff --git a/src/tools/perf_replies.c b/src/tools/perf_replies.c
index 0f890941..2fd58c12 100644
--- a/src/tools/perf_replies.c
+++ b/src/tools/perf_replies.c
@@ -73,6 +73,7 @@ static char self_name[500] = "perf_replies";
73static uint16_t mhd_port = 0; 73static uint16_t mhd_port = 0;
74static struct MHD_Response **resps = NULL; 74static struct MHD_Response **resps = NULL;
75static unsigned int num_resps = 0; 75static unsigned int num_resps = 0;
76static char *body_dyn = NULL; /* Non-static body data */
76 77
77static void 78static void
78set_self_name (int argc, char *const *argv) 79set_self_name (int argc, char *const *argv)
@@ -340,11 +341,17 @@ show_help (void)
340 printf (" --poll use poll() function\n"); 341 printf (" --poll use poll() function\n");
341 printf (" --select use select() function\n"); 342 printf (" --select use select() function\n");
342 printf ("\n"); 343 printf ("\n");
344 printf ("Response size options (mutually exclusive):\n");
345 printf (" -E, --empty empty response, 0 bytes\n");
346 printf (" -T, --tiny tiny response, 3 bytes (default)\n");
347 printf (" -M, --medium medium response, 8 KB\n");
348 printf (" -L, --large large response, 1 MB\n");
349 printf ("\n");
343 printf ("Other options:\n"); 350 printf ("Other options:\n");
344 printf (" -c NUM, --connections=NUM reject more than NUM client \n" 351 printf (" -c NUM, --connections=NUM reject more than NUM client \n"
345 " connections\n"); 352 " connections\n");
346 printf (" -O NUM, --timeout=NUM set connection timeout to NUM seconds,\n" 353 printf (" -O NUM, --timeout=NUM set connection timeout to NUM seconds,\n"
347 " zero means no timeout"); 354 " zero means no timeout\n");
348 printf (" --date-header use the 'Date:' header in every\n" 355 printf (" --date-header use the 'Date:' header in every\n"
349 " reply\n"); 356 " reply\n");
350 printf (" --help display this help and exit\n"); 357 printf (" --help display this help and exit\n");
@@ -363,6 +370,10 @@ struct PerfRepl_parameters
363 int epoll; 370 int epoll;
364 int poll; 371 int poll;
365 int select; 372 int select;
373 int empty;
374 int tiny;
375 int medium;
376 int large;
366 unsigned int connections; 377 unsigned int connections;
367 unsigned int timeout; 378 unsigned int timeout;
368 int date_header; 379 int date_header;
@@ -381,6 +392,10 @@ static struct PerfRepl_parameters tool_params = {
381 0, 392 0,
382 0, 393 0,
383 0, 394 0,
395 0,
396 0,
397 0,
398 0,
384 0 399 0
385}; 400};
386 401
@@ -500,6 +515,114 @@ process_param__select (const char *param_name)
500} 515}
501 516
502 517
518static enum PerfRepl_param_result
519process_param__empty (const char *param_name)
520{
521 if (tool_params.tiny)
522 {
523 fprintf (stderr, "Parameter '%s' cannot be used together "
524 "with '-T' or '--tiny'.\n", param_name);
525 return PERF_RPL_PARAM_ERROR;
526 }
527 if (tool_params.medium)
528 {
529 fprintf (stderr, "Parameter '%s' cannot be used together "
530 "with '-M' or '--medium'.\n", param_name);
531 return PERF_RPL_PARAM_ERROR;
532 }
533 if (tool_params.large)
534 {
535 fprintf (stderr, "Parameter '%s' cannot be used together "
536 "with '-L' or '--large'.\n", param_name);
537 return PERF_RPL_PARAM_ERROR;
538 }
539 tool_params.empty = ! 0;
540 return '-' == param_name[1] ?
541 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
542}
543
544
545static enum PerfRepl_param_result
546process_param__tiny (const char *param_name)
547{
548 if (tool_params.empty)
549 {
550 fprintf (stderr, "Parameter '%s' cannot be used together "
551 "with '-E' or '--empty'.\n", param_name);
552 return PERF_RPL_PARAM_ERROR;
553 }
554 if (tool_params.medium)
555 {
556 fprintf (stderr, "Parameter '%s' cannot be used together "
557 "with '-M' or '--medium'.\n", param_name);
558 return PERF_RPL_PARAM_ERROR;
559 }
560 if (tool_params.large)
561 {
562 fprintf (stderr, "Parameter '%s' cannot be used together "
563 "with '-L' or '--large'.\n", param_name);
564 return PERF_RPL_PARAM_ERROR;
565 }
566 tool_params.tiny = ! 0;
567 return '-' == param_name[1] ?
568 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
569}
570
571
572static enum PerfRepl_param_result
573process_param__medium (const char *param_name)
574{
575 if (tool_params.empty)
576 {
577 fprintf (stderr, "Parameter '%s' cannot be used together "
578 "with '-E' or '--empty'.\n", param_name);
579 return PERF_RPL_PARAM_ERROR;
580 }
581 if (tool_params.tiny)
582 {
583 fprintf (stderr, "Parameter '%s' cannot be used together "
584 "with '-T' or '--tiny'.\n", param_name);
585 return PERF_RPL_PARAM_ERROR;
586 }
587 if (tool_params.large)
588 {
589 fprintf (stderr, "Parameter '%s' cannot be used together "
590 "with '-L' or '--large'.\n", param_name);
591 return PERF_RPL_PARAM_ERROR;
592 }
593 tool_params.medium = ! 0;
594 return '-' == param_name[1] ?
595 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
596}
597
598
599static enum PerfRepl_param_result
600process_param__large (const char *param_name)
601{
602 if (tool_params.empty)
603 {
604 fprintf (stderr, "Parameter '%s' cannot be used together "
605 "with '-E' or '--empty'.\n", param_name);
606 return PERF_RPL_PARAM_ERROR;
607 }
608 if (tool_params.tiny)
609 {
610 fprintf (stderr, "Parameter '%s' cannot be used together "
611 "with '-T' or '--tiny'.\n", param_name);
612 return PERF_RPL_PARAM_ERROR;
613 }
614 if (tool_params.medium)
615 {
616 fprintf (stderr, "Parameter '%s' cannot be used together "
617 "with '-M' or '--medium'.\n", param_name);
618 return PERF_RPL_PARAM_ERROR;
619 }
620 tool_params.large = ! 0;
621 return '-' == param_name[1] ?
622 PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
623}
624
625
503/** 626/**
504 * Process parameter '-c' or '--connections' 627 * Process parameter '-c' or '--connections'
505 * @param param_name the name of the parameter as specified in command line 628 * @param param_name the name of the parameter as specified in command line
@@ -605,6 +728,14 @@ process_short_param (const char *param, const char *next_param)
605 return process_param__all_cpus ("-A"); 728 return process_param__all_cpus ("-A");
606 else if ('t' == param_chr) 729 else if ('t' == param_chr)
607 return process_param__threads ("-t", param + 1, next_param); 730 return process_param__threads ("-t", param + 1, next_param);
731 else if ('E' == param_chr)
732 return process_param__empty ("-E");
733 else if ('T' == param_chr)
734 return process_param__tiny ("-T");
735 else if ('M' == param_chr)
736 return process_param__medium ("-M");
737 else if ('L' == param_chr)
738 return process_param__large ("-L");
608 else if ('c' == param_chr) 739 else if ('c' == param_chr)
609 return process_param__connections ("-c", param + 1, next_param); 740 return process_param__connections ("-c", param + 1, next_param);
610 else if ('O' == param_chr) 741 else if ('O' == param_chr)
@@ -673,6 +804,18 @@ process_long_param (const char *param, const char *next_param)
673 else if ((MHD_STATICSTR_LEN_ ("select") == param_len) && 804 else if ((MHD_STATICSTR_LEN_ ("select") == param_len) &&
674 (0 == memcmp (param, "select", MHD_STATICSTR_LEN_ ("select")))) 805 (0 == memcmp (param, "select", MHD_STATICSTR_LEN_ ("select"))))
675 return process_param__select ("--select"); 806 return process_param__select ("--select");
807 else if ((MHD_STATICSTR_LEN_ ("empty") == param_len) &&
808 (0 == memcmp (param, "empty", MHD_STATICSTR_LEN_ ("empty"))))
809 return process_param__empty ("--empty");
810 else if ((MHD_STATICSTR_LEN_ ("tiny") == param_len) &&
811 (0 == memcmp (param, "tiny", MHD_STATICSTR_LEN_ ("tiny"))))
812 return process_param__tiny ("--tiny");
813 else if ((MHD_STATICSTR_LEN_ ("medium") == param_len) &&
814 (0 == memcmp (param, "medium", MHD_STATICSTR_LEN_ ("medium"))))
815 return process_param__medium ("--medium");
816 else if ((MHD_STATICSTR_LEN_ ("large") == param_len) &&
817 (0 == memcmp (param, "large", MHD_STATICSTR_LEN_ ("large"))))
818 return process_param__large ("--large");
676 else if ((MHD_STATICSTR_LEN_ ("connections") <= param_len) && 819 else if ((MHD_STATICSTR_LEN_ ("connections") <= param_len) &&
677 (0 == memcmp (param, "connections", 820 (0 == memcmp (param, "connections",
678 MHD_STATICSTR_LEN_ ("connections")))) 821 MHD_STATICSTR_LEN_ ("connections"))))
@@ -877,6 +1020,15 @@ check_param__poll (void)
877} 1020}
878 1021
879 1022
1023static void
1024check_param__empty_tiny_medium_large (void)
1025{
1026 if (0 == (tool_params.empty | tool_params.tiny | tool_params.medium
1027 | tool_params.large))
1028 tool_params.tiny = ! 0;
1029}
1030
1031
880/* Must be called after 'check_apply_param__threads()' and 1032/* Must be called after 'check_apply_param__threads()' and
881 'check_apply_param__all_cpus()' */ 1033 'check_apply_param__all_cpus()' */
882/* non-zero - OK, zero - error */ 1034/* non-zero - OK, zero - error */
@@ -922,6 +1074,7 @@ check_apply_params (void)
922 return PERF_RPL_ERR_CODE_BAD_PARAM; 1074 return PERF_RPL_ERR_CODE_BAD_PARAM;
923 if (! check_param__poll ()) 1075 if (! check_param__poll ())
924 return PERF_RPL_ERR_CODE_BAD_PARAM; 1076 return PERF_RPL_ERR_CODE_BAD_PARAM;
1077 check_param__empty_tiny_medium_large ();
925 if (! check_param__connections ()) 1078 if (! check_param__connections ())
926 return PERF_RPL_ERR_CODE_BAD_PARAM; 1079 return PERF_RPL_ERR_CODE_BAD_PARAM;
927 return 0; 1080 return 0;
@@ -935,23 +1088,106 @@ init_data (void)
935 The system will keep it in cache. */ 1088 The system will keep it in cache. */
936 static const char tiny_body[] = "Hi!"; 1089 static const char tiny_body[] = "Hi!";
937 unsigned int i; 1090 unsigned int i;
1091 size_t body_dyn_size;
1092
1093 if (tool_params.medium)
1094 body_dyn_size = 8U * 1024U;
1095 else if (tool_params.large)
1096 body_dyn_size = 1024U * 1024U;
1097 else
1098 body_dyn_size = 0;
1099
1100 if (0 != body_dyn_size)
1101 {
1102 body_dyn = (char *) malloc (body_dyn_size);
1103 if (NULL == body_dyn)
1104 {
1105 fprintf (stderr, "Failed to allocate memory.\n");
1106 return 25;
1107 }
1108 if (tool_params.medium)
1109 {
1110 /* Fill the body with HTML-like content */
1111 size_t pos;
1112 size_t filler_pos;
1113 static const char body_header[] =
1114 "<html>\n"
1115 "<head>\n<title>Sample page title</title>\n<head>\n"
1116 "<body>\n";
1117 static const char body_filler[] =
1118 "The quick brown fox jumps over the lazy dog.<br>\n";
1119 static const char body_footer[] =
1120 "</body>\n"
1121 "</html>\n";
1122 pos = 0;
1123 memcpy (body_dyn + pos, body_header, MHD_STATICSTR_LEN_ (body_header));
1124 pos += MHD_STATICSTR_LEN_ (body_header);
1125 for (filler_pos = 0;
1126 filler_pos < (body_dyn_size - (MHD_STATICSTR_LEN_ (body_header)
1127 + MHD_STATICSTR_LEN_ (body_footer)));
1128 ++filler_pos)
1129 {
1130 body_dyn[pos + filler_pos] =
1131 body_filler[filler_pos % MHD_STATICSTR_LEN_ (body_filler)];
1132 }
1133 pos += filler_pos;
1134 memcpy (body_dyn + pos, body_footer, MHD_STATICSTR_LEN_ (body_footer));
1135 }
1136 else
1137 {
1138 /* Fill the body with binary-like content */
1139 size_t pos;
1140 for (pos = 0; pos < body_dyn_size; ++pos)
1141 {
1142 body_dyn[pos] = (char) (unsigned char) (255U - pos % 256U);
1143 }
1144 }
1145 }
1146
938 /* Use more responses to minimise waiting in threads to unlock 1147 /* Use more responses to minimise waiting in threads to unlock
939 the response used by other thread. */ 1148 the response used by other thread. */
940 num_resps = 16 * get_num_threads (); 1149 num_resps = 16 * get_num_threads ();
941 resps = (struct MHD_Response **) 1150 resps = (struct MHD_Response **)
942 malloc ((sizeof(struct MHD_Response *)) * num_resps); 1151 malloc ((sizeof(struct MHD_Response *)) * num_resps);
943 if (NULL == resps) 1152 if (NULL == resps)
1153 {
1154 if (NULL != body_dyn)
1155 {
1156 free (body_dyn);
1157 body_dyn = NULL;
1158 }
1159 fprintf (stderr, "Failed to allocate memory.\n");
944 return 25; 1160 return 25;
1161 }
945 for (i = 0; i < num_resps; ++i) 1162 for (i = 0; i < num_resps; ++i)
946 { 1163 {
947#if MHD_VERSION >= 0x00097701 1164#if MHD_VERSION >= 0x00097701
948 resps[i] = MHD_create_response_from_buffer_static (sizeof(tiny_body) - 1, 1165 if (NULL != body_dyn)
949 tiny_body); 1166 resps[i] = MHD_create_response_from_buffer_static (body_dyn_size,
950#else /* MHD_VERSION < 0x00097701 */ 1167 body_dyn);
951 resps[i] = MHD_create_response_from_buffer (sizeof(tiny_body) - 1, 1168 else if (tool_params.empty)
952 (void *) tiny_body, 1169 resps[i] = MHD_create_response_empty (MHD_RF_NONE);
953 MHD_RESPMEM_PERSISTENT); 1170 else
954#endif 1171 resps[i] =
1172 MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (tiny_body),
1173 tiny_body);
1174
1175#else /* MHD_VERSION < 0x00097701 */
1176 if (NULL != body_dyn)
1177 resps[i] = MHD_create_response_from_buffer (body_dyn_size,
1178 (void *) body_dyn,
1179 MHD_RESPMEM_PERSISTENT);
1180 else if (tool_params.empty)
1181 resps[i] = MHD_create_response_from_buffer (0,
1182 (void *) tiny_body,
1183 MHD_RESPMEM_PERSISTENT);
1184 else if (tool_params.tiny)
1185 resps[i] =
1186 MHD_create_response_from_buffer (MHD_STATICSTR_LEN_ (tiny_body),
1187 (void *) tiny_body,
1188 MHD_RESPMEM_PERSISTENT);
1189 else
1190#endif /* MHD_VERSION < 0x00097701 */
955 if (NULL == resps[i]) 1191 if (NULL == resps[i])
956 { 1192 {
957 fprintf (stderr, "Failed to create responses.\n"); 1193 fprintf (stderr, "Failed to create responses.\n");
@@ -967,6 +1203,9 @@ init_data (void)
967 free (resps); 1203 free (resps);
968 resps = NULL; 1204 resps = NULL;
969 num_resps = 0; 1205 num_resps = 0;
1206 if (NULL != body_dyn)
1207 free (body_dyn);
1208 body_dyn = NULL;
970 return 32; 1209 return 32;
971} 1210}
972 1211
@@ -981,6 +1220,9 @@ deinit_data (void)
981 free (resps); 1220 free (resps);
982 resps = NULL; 1221 resps = NULL;
983 num_resps = 0; 1222 num_resps = 0;
1223 if (NULL != body_dyn)
1224 free (body_dyn);
1225 body_dyn = NULL;
984} 1226}
985 1227
986 1228
@@ -1043,6 +1285,22 @@ get_mhd_conn_limit (struct MHD_Daemon *d)
1043} 1285}
1044 1286
1045 1287
1288static const char *
1289get_mhd_response_size (void)
1290{
1291 if (tool_params.empty)
1292 return "0 bytes (empty)";
1293 else if (tool_params.tiny)
1294 return "3 bytes (tiny)";
1295 else if (tool_params.medium)
1296 return "8 KB (medium)";
1297 else if (tool_params.large)
1298 return "1 MB (large)";
1299 abort ();
1300 return "";
1301}
1302
1303
1046static int 1304static int
1047run_mhd (void) 1305run_mhd (void)
1048{ 1306{
@@ -1066,11 +1324,11 @@ run_mhd (void)
1066 fprintf (stderr, "WARNING: The tools is compiled with size-optimisations, " 1324 fprintf (stderr, "WARNING: The tools is compiled with size-optimisations, "
1067 "the performance is suboptimal.\n"); 1325 "the performance is suboptimal.\n");
1068#endif /* __GNUC__ && ! __OPTIMIZE__ */ 1326#endif /* __GNUC__ && ! __OPTIMIZE__ */
1069#if MHD_VERSION >= 0x00097703 1327#if MHD_VERSION >= 0x00097701
1070 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_DEBUG_BUILD)) 1328 if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_DEBUG_BUILD))
1071 fprintf (stderr, "WARNING: The libmicrohttpd is compiled with " 1329 fprintf (stderr, "WARNING: The libmicrohttpd is compiled with "
1072 "debug asserts enabled, the performance is suboptimal.\n"); 1330 "debug asserts enabled, the performance is suboptimal.\n");
1073#endif /* MHD_VERSION >= 0x00097703 */ 1331#endif /* MHD_VERSION >= 0x00097701 */
1074 flags |= MHD_USE_ERROR_LOG; 1332 flags |= MHD_USE_ERROR_LOG;
1075 flags |= MHD_USE_INTERNAL_POLLING_THREAD; 1333 flags |= MHD_USE_INTERNAL_POLLING_THREAD;
1076 if (tool_params.epoll) 1334 if (tool_params.epoll)
@@ -1148,6 +1406,8 @@ run_mhd (void)
1148 0 == tool_params.timeout ? " (no timeout)" : ""); 1406 0 == tool_params.timeout ? " (no timeout)" : "");
1149 printf (" 'Date:' header: %s\n", 1407 printf (" 'Date:' header: %s\n",
1150 tool_params.date_header ? "Yes" : "No"); 1408 tool_params.date_header ? "Yes" : "No");
1409 printf (" Response size: %s\n",
1410 get_mhd_response_size ());
1151 printf ("To test with remote client use " 1411 printf ("To test with remote client use "
1152 "http://HOST_IP:%u/\n", (unsigned int) port); 1412 "http://HOST_IP:%u/\n", (unsigned int) port);
1153 printf ("To test with client on the same host use " 1413 printf ("To test with client on the same host use "