MXS-1360 Add 'thread_stack_size' configuration value
Using the 'thread_stack_size' configuration value, the stack size of the worker threads can be adjusted.
This commit is contained in:
parent
e9b2a560b8
commit
49ba1f8fa0
@ -150,6 +150,16 @@ Additional threads will be created to execute other internal services within
|
||||
MariaDB MaxScale. This setting is used to configure the number of threads that
|
||||
will be used to manage the user connections.
|
||||
|
||||
#### `thread_stack_size`
|
||||
|
||||
This parameter controls the stack size of the worker threads. The default value
|
||||
is 0, which means that the pthread default will be used. The size can be specified
|
||||
as explained in detail [here](#sizes).
|
||||
|
||||
```
|
||||
thread_stack_size=5Mi
|
||||
```
|
||||
|
||||
#### `auth_connect_timeout`
|
||||
|
||||
The connection timeout in seconds for the MySQL connections to the backend
|
||||
|
@ -152,6 +152,7 @@ extern const char CN_SSL_KEY[];
|
||||
extern const char CN_SSL_VERSION[];
|
||||
extern const char CN_STRIP_DB_ESC[];
|
||||
extern const char CN_THREADS[];
|
||||
extern const char CN_THREAD_STACK_SIZE[];
|
||||
extern const char CN_TYPE[];
|
||||
extern const char CN_UNIX[];
|
||||
extern const char CN_USER[];
|
||||
@ -189,6 +190,7 @@ typedef struct
|
||||
{
|
||||
bool config_check; /**< Only check config */
|
||||
int n_threads; /**< Number of polling threads */
|
||||
size_t thread_stack_size; /**< The stack size of each worker thread */
|
||||
char *version_string; /**< The version string of embedded db library */
|
||||
char release_string[RELEASE_STR_LENGTH]; /**< The release name string of the system */
|
||||
char sysname[SYSNAME_LEN]; /**< The OS name of the system */
|
||||
@ -446,6 +448,14 @@ int config_truth_value(const char *value);
|
||||
*/
|
||||
int config_threadcount(void);
|
||||
|
||||
/**
|
||||
* @brief Get thread stack size
|
||||
*
|
||||
* @return The configured worker thread stack size.
|
||||
*/
|
||||
size_t config_thread_stack_size(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get number of non-blocking polls
|
||||
*
|
||||
|
@ -132,6 +132,7 @@ const char CN_SSL_KEY[] = "ssl_key";
|
||||
const char CN_SSL_VERSION[] = "ssl_version";
|
||||
const char CN_STRIP_DB_ESC[] = "strip_db_esc";
|
||||
const char CN_THREADS[] = "threads";
|
||||
const char CN_THREAD_STACK_SIZE[] = "thread_stack_size";
|
||||
const char CN_TYPE[] = "type";
|
||||
const char CN_UNIX[] = "unix";
|
||||
const char CN_USER[] = "user";
|
||||
@ -163,6 +164,7 @@ static void remove_first_last_char(char* value);
|
||||
static bool test_regex_string_validity(const char* regex_string, const char* key);
|
||||
static pcre2_code* compile_regex_string(const char* regex_string, bool jit_enabled,
|
||||
uint32_t options, uint32_t* output_ovector_size);
|
||||
static uint64_t get_suffixed_size(const char* value);
|
||||
|
||||
int config_get_ifaddr(unsigned char *output);
|
||||
static int config_get_release_string(char* release);
|
||||
@ -1068,64 +1070,8 @@ int config_get_integer(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||
uint64_t config_get_size(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||
{
|
||||
const char *value = config_get_value_string(params, key);
|
||||
char *end;
|
||||
uint64_t size = strtoll(value, &end, 10);
|
||||
|
||||
switch (*end)
|
||||
{
|
||||
case 'T':
|
||||
case 't':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL * 1000ULL * 1000ULL * 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
case 'g':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL * 1024ULL * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL * 1000ULL * 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
case 'm':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL * 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
case 'k':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
return get_suffixed_size(value);
|
||||
}
|
||||
|
||||
const char* config_get_string(const MXS_CONFIG_PARAMETER *params, const char *key)
|
||||
@ -1334,6 +1280,11 @@ config_threadcount()
|
||||
return gateway.n_threads;
|
||||
}
|
||||
|
||||
size_t config_thread_stack_size()
|
||||
{
|
||||
return gateway.thread_stack_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of non-blocking polls to be done before a blocking poll
|
||||
* is issued.
|
||||
@ -1424,6 +1375,10 @@ handle_global_item(const char *name, const char *value)
|
||||
gateway.n_threads = MXS_MAX_THREADS;
|
||||
}
|
||||
}
|
||||
else if (strcmp(name, CN_THREAD_STACK_SIZE) == 0)
|
||||
{
|
||||
gateway.thread_stack_size = get_suffixed_size(value);
|
||||
}
|
||||
else if (strcmp(name, CN_NON_BLOCKING_POLLS) == 0)
|
||||
{
|
||||
gateway.n_nbpoll = atoi(value);
|
||||
@ -1799,6 +1754,17 @@ global_defaults()
|
||||
gateway.admin_ssl_cert[0] = '\0';
|
||||
gateway.admin_ssl_ca_cert[0] = '\0';
|
||||
|
||||
gateway.thread_stack_size = 0;
|
||||
pthread_attr_t attr;
|
||||
if (pthread_attr_init(&attr) == 0)
|
||||
{
|
||||
size_t thread_stack_size;
|
||||
if (pthread_attr_getstacksize(&attr, &thread_stack_size) == 0)
|
||||
{
|
||||
gateway.thread_stack_size = thread_stack_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (version_string != NULL)
|
||||
{
|
||||
gateway.version_string = MXS_STRDUP_A(version_string);
|
||||
@ -3890,6 +3856,7 @@ json_t* config_maxscale_to_json(const char* host)
|
||||
json_object_set_new(param, "execdir", json_string(get_execdir()));
|
||||
json_object_set_new(param, "connector_plugindir", json_string(get_connector_plugindir()));
|
||||
json_object_set_new(param, CN_THREADS, json_integer(config_threadcount()));
|
||||
json_object_set_new(param, CN_THREAD_STACK_SIZE, json_integer(config_thread_stack_size()));
|
||||
|
||||
MXS_CONFIG* cnf = config_get_global_options();
|
||||
|
||||
@ -4117,3 +4084,74 @@ static bool test_regex_string_validity(const char* regex_string, const char* key
|
||||
pcre2_code_free(code);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string into the corresponding value, interpreting
|
||||
* IEC or SI prefixes used as suffixes appropriately.
|
||||
*
|
||||
* @param value A numerical string, possibly suffixed by a IEC
|
||||
* binary prefix or SI prefix.
|
||||
*
|
||||
* @return The corresponding size.
|
||||
*/
|
||||
static uint64_t get_suffixed_size(const char* value)
|
||||
{
|
||||
char *end;
|
||||
uint64_t size = strtoll(value, &end, 10);
|
||||
|
||||
switch (*end)
|
||||
{
|
||||
case 'T':
|
||||
case 't':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL * 1000ULL * 1000ULL * 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
case 'g':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL * 1024ULL * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL * 1000ULL * 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
case 'm':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL * 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL * 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
case 'k':
|
||||
if ((*(end + 1) == 'i') || (*(end + 1) == 'I'))
|
||||
{
|
||||
size *= 1024ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
size *= 1000ULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -1293,6 +1293,7 @@ int main(int argc, char **argv)
|
||||
int ini_rval;
|
||||
intptr_t thread_id;
|
||||
int n_threads; /*< number of epoll listener threads */
|
||||
size_t thread_stack_size;
|
||||
int n_services;
|
||||
int eno = 0; /*< local variable for errno */
|
||||
int opt;
|
||||
@ -2032,12 +2033,13 @@ int main(int argc, char **argv)
|
||||
/*<
|
||||
* Start workers. We start from 1, worker 0 will be running in the main thread.
|
||||
*/
|
||||
thread_stack_size = config_thread_stack_size();
|
||||
for (i = 1; i < n_threads; i++)
|
||||
{
|
||||
worker = Worker::get(i);
|
||||
ss_dassert(worker);
|
||||
|
||||
if (!worker->start())
|
||||
if (!worker->start(thread_stack_size))
|
||||
{
|
||||
const char* logerr = "Failed to start worker thread.";
|
||||
print_log_n_stderr(true, true, logerr, logerr, 0);
|
||||
@ -2061,7 +2063,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
MXS_NOTICE("MaxScale started with %d server threads.", config_threadcount());
|
||||
|
||||
MXS_NOTICE("MaxScale started with %d worker threads, each with a stack size of %lu bytes.",
|
||||
n_threads, thread_stack_size);
|
||||
|
||||
/**
|
||||
* Successful start, notify the parent process that it can exit.
|
||||
*/
|
||||
|
@ -241,9 +241,12 @@ public:
|
||||
* This function will start a new thread, in which the `run`
|
||||
* function will be executed.
|
||||
*
|
||||
* @param stack_size The stack size of the new thread. A value of 0 means
|
||||
* that the pthread default should be used.
|
||||
*
|
||||
* @return True if the thread could be started, false otherwise.
|
||||
*/
|
||||
bool start();
|
||||
bool start(size_t stack_size = 0);
|
||||
|
||||
/**
|
||||
* Waits for the worker to finish.
|
||||
|
@ -843,11 +843,11 @@ void Worker::run()
|
||||
MXS_NOTICE("Worker %d has shut down.", m_id);
|
||||
}
|
||||
|
||||
bool Worker::start()
|
||||
bool Worker::start(size_t stack_size)
|
||||
{
|
||||
m_started = true;
|
||||
|
||||
if (!thread_start(&m_thread, &Worker::thread_main, this, 0))
|
||||
if (!thread_start(&m_thread, &Worker::thread_main, this, stack_size))
|
||||
{
|
||||
m_started = false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user