perf_replies: added more features

This commit is contained in:
Evgeny Grin (Karlson2k)
2023-07-04 15:32:38 +03:00
parent a5cf04b5d0
commit 54b2a78b36
3 changed files with 210 additions and 64 deletions
-10
View File
@@ -3917,16 +3917,6 @@ AS_VAR_IF([enable_tools],["yes"],
) )
] ]
) )
MATH_LIB=''
MHD_FIND_LIB([sqrt],[#include <math.h>],
[[
double res = sqrt ((double) 4);
i][f (((double) 2) != res) return 2;
]],[m],
[AC_DEFINE([[HAVE_SQRT_FUNC]],[[1]],[Define to 1 i][f 'sqrt()' function is available.])
],[],[MATH_LIB]
)
AC_SUBST([MATH_LIB])
] ]
) )
-2
View File
@@ -37,5 +37,3 @@ endif
perf_replies_SOURCES = \ perf_replies_SOURCES = \
perf_replies.c perf_replies.c
perf_replies_LDADD = \
$(LDADD) $(MATH_LIB)
+210 -52
View File
@@ -334,11 +334,19 @@ show_help (void)
printf (" -t NUM, --threads=NUM use NUM threads\n"); printf (" -t NUM, --threads=NUM use NUM threads\n");
printf ("\n"); printf ("\n");
printf ("Force polling function (mutually exclusive):\n"); printf ("Force polling function (mutually exclusive):\n");
printf (" --epoll use 'epoll' functionality\n"); if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_EPOLL))
printf (" --poll use poll() function\n"); printf (" --epoll use 'epoll' functionality\n");
if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_POLL))
printf (" --poll use poll() function\n");
printf (" --select use select() function\n"); printf (" --select use select() function\n");
printf ("\n"); printf ("\n");
printf ("Other options:\n"); printf ("Other options:\n");
printf (" -c NUM, --connections=NUM reject more than NUM client \n"
" connections\n");
printf (" -O NUM, --timeout=NUM set connection timeout to NUM seconds,\n"
" zero means no timeout");
printf (" --date-header use the 'Date:' header in every\n"
" reply\n");
printf (" --help display this help and exit\n"); printf (" --help display this help and exit\n");
printf (" -V, --version output version information and exit\n"); printf (" -V, --version output version information and exit\n");
printf ("\n"); printf ("\n");
@@ -355,6 +363,9 @@ struct PerfRepl_parameters
int epoll; int epoll;
int poll; int poll;
int select; int select;
unsigned int connections;
unsigned int timeout;
int date_header;
int help; int help;
int version; int version;
}; };
@@ -367,6 +378,9 @@ static struct PerfRepl_parameters tool_params = {
0, 0,
0, 0,
0, 0,
0,
0,
0,
0 0
}; };
@@ -374,7 +388,7 @@ static struct PerfRepl_parameters tool_params = {
* Process parameter '-t' or '--threads' * Process parameter '-t' or '--threads'
* @param param_name the name of the parameter as specified in command line * @param param_name the name of the parameter as specified in command line
* @param param_tail the pointer to the character after parameter name in * @param param_tail the pointer to the character after parameter name in
* the parameter string or NULL for "long" parameters * the parameter string
* @param next_param the pointer to the next parameter (if any) or NULL * @param next_param the pointer to the next parameter (if any) or NULL
* @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by * @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by
* this function * this function
@@ -423,28 +437,6 @@ process_param__all_cpus (const char *param_name)
} }
static enum PerfRepl_param_result
process_param__help (const char *param_name)
{
/* Use only one of help | version */
if (! tool_params.version)
tool_params.help = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
}
static enum PerfRepl_param_result
process_param__version (const char *param_name)
{
/* Use only one of help | version */
if (! tool_params.help)
tool_params.version = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
}
static enum PerfRepl_param_result static enum PerfRepl_param_result
process_param__epoll (const char *param_name) process_param__epoll (const char *param_name)
{ {
@@ -508,6 +500,95 @@ process_param__select (const char *param_name)
} }
/**
* Process parameter '-c' or '--connections'
* @param param_name the name of the parameter as specified in command line
* @param param_tail the pointer to the character after parameter name in
* the parameter string
* @param next_param the pointer to the next parameter (if any) or NULL
* @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by
* this function
*/
static enum PerfRepl_param_result
process_param__connections (const char *param_name, const char *param_tail,
const char *next_param)
{
unsigned int param_value;
enum PerfRepl_param_result value_res;
value_res = get_param_value (param_name, param_tail, next_param,
&param_value);
if (PERF_RPL_PARAM_ERROR == value_res)
return value_res;
if (0 == param_value)
{
fprintf (stderr, "'0' is not valid value for parameter '%s'.\n",
param_name);
return PERF_RPL_PARAM_ERROR;
}
tool_params.connections = param_value;
return value_res;
}
/**
* Process parameter '-O' or '--timeout'
* @param param_name the name of the parameter as specified in command line
* @param param_tail the pointer to the character after parameter name in
* the parameter string
* @param next_param the pointer to the next parameter (if any) or NULL
* @return enum value, the PERF_PERPL_SPARAM_ONE_CHAR is not used by
* this function
*/
static enum PerfRepl_param_result
process_param__timeout (const char *param_name, const char *param_tail,
const char *next_param)
{
unsigned int param_value;
enum PerfRepl_param_result value_res;
value_res = get_param_value (param_name, param_tail, next_param,
&param_value);
if (PERF_RPL_PARAM_ERROR == value_res)
return value_res;
tool_params.timeout = param_value;
return value_res;
}
static enum PerfRepl_param_result
process_param__date_header (const char *param_name)
{
tool_params.date_header = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
}
static enum PerfRepl_param_result
process_param__help (const char *param_name)
{
/* Use only one of help | version */
if (! tool_params.version)
tool_params.help = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
}
static enum PerfRepl_param_result
process_param__version (const char *param_name)
{
/* Use only one of help | version */
if (! tool_params.help)
tool_params.version = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
}
/** /**
* Process "short" (one character) parameter. * Process "short" (one character) parameter.
* @param param the pointer to character after "-" or after another valid * @param param the pointer to character after "-" or after another valid
@@ -524,6 +605,10 @@ process_short_param (const char *param, const char *next_param)
return process_param__all_cpus ("-A"); return process_param__all_cpus ("-A");
else if ('t' == param_chr) else if ('t' == param_chr)
return process_param__threads ("-t", param + 1, next_param); return process_param__threads ("-t", param + 1, next_param);
else if ('c' == param_chr)
return process_param__connections ("-c", param + 1, next_param);
else if ('O' == param_chr)
return process_param__timeout ("-O", param + 1, next_param);
else if ('V' == param_chr) else if ('V' == param_chr)
return process_param__version ("-V"); return process_param__version ("-V");
@@ -588,6 +673,23 @@ process_long_param (const char *param, const char *next_param)
else if ((MHD_STATICSTR_LEN_ ("select") == param_len) && else if ((MHD_STATICSTR_LEN_ ("select") == param_len) &&
(0 == memcmp (param, "select", MHD_STATICSTR_LEN_ ("select")))) (0 == memcmp (param, "select", MHD_STATICSTR_LEN_ ("select"))))
return process_param__select ("--select"); return process_param__select ("--select");
else if ((MHD_STATICSTR_LEN_ ("connections") <= param_len) &&
(0 == memcmp (param, "connections",
MHD_STATICSTR_LEN_ ("connections"))))
return process_param__connections ("--connections",
param
+ MHD_STATICSTR_LEN_ ("connections"),
next_param);
else if ((MHD_STATICSTR_LEN_ ("timeout") <= param_len) &&
(0 == memcmp (param, "timeout",
MHD_STATICSTR_LEN_ ("timeout"))))
return process_param__timeout ("--timeout",
param + MHD_STATICSTR_LEN_ ("timeout"),
next_param);
else if ((MHD_STATICSTR_LEN_ ("date-header") == param_len) &&
(0 == memcmp (param, "date-header",
MHD_STATICSTR_LEN_ ("date-header"))))
return process_param__date_header ("--date-header");
else if ((MHD_STATICSTR_LEN_ ("help") == param_len) && else if ((MHD_STATICSTR_LEN_ ("help") == param_len) &&
(0 == memcmp (param, "help", MHD_STATICSTR_LEN_ ("help")))) (0 == memcmp (param, "help", MHD_STATICSTR_LEN_ ("help"))))
return process_param__help ("--help"); return process_param__help ("--help");
@@ -691,6 +793,21 @@ print_all_cores_used (void)
} }
/**
* Apply parameter '-A' or '--all-cpus'
*/
static void
check_apply_param__all_cpus (void)
{
if (! tool_params.all_cpus)
return;
num_threads = get_cpu_core_count ();
printf ("Requested use of all available CPU cores for MHD threads.\n");
print_all_cores_used ();
}
/** /**
* Apply parameter '-t' or '--threads' * Apply parameter '-t' or '--threads'
*/ */
@@ -718,21 +835,6 @@ check_apply_param__threads (void)
} }
/**
* Apply parameter '-A' or '--all-cpus'
*/
static void
check_apply_param__all_cpus (void)
{
if (! tool_params.all_cpus)
return;
num_threads = get_cpu_core_count ();
printf ("Requested use of all available CPU cores for MHD threads.\n");
print_all_cores_used ();
}
static void static void
check_param_port (void) check_param_port (void)
{ {
@@ -775,6 +877,25 @@ check_param__poll (void)
} }
/* Must be called after 'check_apply_param__threads()' and
'check_apply_param__all_cpus()' */
/* non-zero - OK, zero - error */
static int
check_param__connections (void)
{
if (0 == tool_params.connections)
return ! 0;
if (get_num_threads () > tool_params.connections)
{
fprintf (stderr, "The connections number limit (%u) is less than number "
"of threads used (%u). Use higher value for connections limit.\n",
tool_params.connections, get_num_threads ());
return 0;
}
return ! 0;
}
/** /**
* Apply decoded parameters * Apply decoded parameters
* @return 0 if success, * @return 0 if success,
@@ -794,12 +915,15 @@ check_apply_params (void)
print_version (); print_version ();
return -1; return -1;
} }
check_param_port ();
check_apply_param__all_cpus ();
check_apply_param__threads ();
if (! check_param__epoll ()) if (! check_param__epoll ())
return PERF_RPL_ERR_CODE_BAD_PARAM; return PERF_RPL_ERR_CODE_BAD_PARAM;
if (! check_param__poll ()) if (! check_param__poll ())
return PERF_RPL_ERR_CODE_BAD_PARAM; return PERF_RPL_ERR_CODE_BAD_PARAM;
check_apply_param__threads (); if (! check_param__connections ())
check_apply_param__all_cpus (); return PERF_RPL_ERR_CODE_BAD_PARAM;
return 0; return 0;
} }
@@ -897,6 +1021,28 @@ answer_shared_response (void *cls,
} }
/* Borrowed from daemon.c */
/* TODO: run-time detection */
/**
* Default connection limit.
*/
#ifdef MHD_POSIX_SOCKETS
#define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
#else
#define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
#endif
static unsigned int
get_mhd_conn_limit (struct MHD_Daemon *d)
{
/* TODO: implement run-time detection */
(void) d; /* Unused */
if (0 != tool_params.connections)
return tool_params.connections;
return (unsigned int) MHD_MAX_CONNECTIONS_DEFAULT;
}
static int static int
run_mhd (void) run_mhd (void)
{ {
@@ -935,18 +1081,25 @@ run_mhd (void)
(void) flags; /* No special additional flag */ (void) flags; /* No special additional flag */
else else
flags |= MHD_USE_AUTO; flags |= MHD_USE_AUTO;
flags |= MHD_USE_SUPPRESS_DATE_NO_CLOCK; if (! tool_params.date_header)
flags |= MHD_USE_SUPPRESS_DATE_NO_CLOCK;
if (0) if (0 != tool_params.connections)
{ {
struct MHD_OptionItem option = struct MHD_OptionItem option =
{ MHD_OPTION_CONNECTION_LIMIT, 5, NULL }; { MHD_OPTION_CONNECTION_LIMIT, (intptr_t) tool_params.connections, NULL };
opt_arr[opt_count++] = option; opt_arr[opt_count++] = option;
} }
if (1 < get_num_threads ()) if (1 < get_num_threads ())
{ {
struct MHD_OptionItem option = struct MHD_OptionItem option =
{ MHD_OPTION_THREAD_POOL_SIZE, (int) get_num_threads (), NULL }; { MHD_OPTION_THREAD_POOL_SIZE, (intptr_t) get_num_threads (), NULL };
opt_arr[opt_count++] = option;
}
if (1)
{
struct MHD_OptionItem option =
{ MHD_OPTION_CONNECTION_TIMEOUT, (intptr_t) tool_params.timeout, NULL };
opt_arr[opt_count++] = option; opt_arr[opt_count++] = option;
} }
if (1) if (1)
@@ -983,17 +1136,22 @@ run_mhd (void)
"port number explicitly.\n"); "port number explicitly.\n");
printf ("\nMHD is running.\n"); printf ("\nMHD is running.\n");
printf (" Bind port: %u\n", (unsigned int) port); printf (" Bind port: %u\n", (unsigned int) port);
printf (" Polling function: %s\n", poll_mode); printf (" Polling function: %s\n", poll_mode);
printf (" Threading: "); printf (" Threading: ");
if (1 == get_num_threads ()) if (1 == get_num_threads ())
printf ("one MHD thread\n"); printf ("one MHD thread\n");
else else
printf ("%u MHD threads in thread pool\n", get_num_threads ()); printf ("%u MHD threads in thread pool\n", get_num_threads ());
printf ("To test with remote client use http://HOST_IP:%u/\n", printf (" Connections limit: %u\n", get_mhd_conn_limit (d));
(unsigned int) port); printf (" Connection timeout: %u%s\n", tool_params.timeout,
0 == tool_params.timeout ? " (no timeout)" : "");
printf (" 'Date:' header: %s\n",
tool_params.date_header ? "Yes" : "No");
printf ("To test with remote client use "
"http://HOST_IP:%u/\n", (unsigned int) port);
printf ("To test with client on the same host use " printf ("To test with client on the same host use "
"http://127.0.0.1:%u\n", (unsigned int) port); "http://127.0.0.1:%u/\n", (unsigned int) port);
printf ("\nPress ENTER to stop.\n"); printf ("\nPress ENTER to stop.\n");
if (1) if (1)
{ {