1
0
mirror of https://github.com/Zygo/bees.git synced 2025-05-17 21:35:45 +02:00

bees: add -G/--thread-min option for minimum thread count

The -g option limits the number of worker threads when the target load
average is exceeded.  On some systems the load normally runs high, and
continuous bees operation is required to avoid running out of disk space.

Add a -G/--thread-min option to force at least some threads to continue
running.

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
Zygo Blaxell 2018-08-26 00:41:37 -04:00
parent dd3c32a43d
commit 9dbe2d6fee
4 changed files with 38 additions and 6 deletions

View File

@ -545,8 +545,11 @@ Command Line Options
* --loadavg-target (-g) LOADAVG * --loadavg-target (-g) LOADAVG
* Specify load average target for dynamic worker threads. * Specify load average target for dynamic worker threads.
Threads will be started or stopped subject to the upper limit imposed Threads will be started or stopped subject to the upper limit imposed
by thread-factor and thread-count until the load average is within by thread-factor, thread-min and thread-count until the load average
+/- 0.5 of LOADAVG. is within +/- 0.5 of LOADAVG.
* --thread-min (-G) COUNT
* Specify minimum number of worker threads for scanning.
Ignored unless -g option is used to specify a target load.
* --scan-mode (-m) MODE * --scan-mode (-m) MODE
* Specify extent scanning algorithm. Default mode is 0. * Specify extent scanning algorithm. Default mode is 0.

View File

@ -58,6 +58,9 @@ namespace crucible {
// Blocks until the running thread count reaches this number // Blocks until the running thread count reaches this number
static void set_thread_count(size_t threads); static void set_thread_count(size_t threads);
// Sets minimum thread count when load average tracking enabled
static void set_thread_min_count(size_t min_threads);
// Calls set_thread_count with default // Calls set_thread_count with default
static void set_thread_count(); static void set_thread_count();

View File

@ -43,6 +43,7 @@ namespace crucible {
condition_variable m_condvar; condition_variable m_condvar;
list<shared_ptr<TaskState>> m_queue; list<shared_ptr<TaskState>> m_queue;
size_t m_thread_max; size_t m_thread_max;
size_t m_thread_min = 0;
set<shared_ptr<TaskConsumer>> m_threads; set<shared_ptr<TaskConsumer>> m_threads;
shared_ptr<thread> m_load_tracking_thread; shared_ptr<thread> m_load_tracking_thread;
double m_load_target = 0; double m_load_target = 0;
@ -56,6 +57,7 @@ namespace crucible {
void start_threads_nolock(); void start_threads_nolock();
void start_stop_threads(); void start_stop_threads();
void set_thread_count(size_t thread_max); void set_thread_count(size_t thread_max);
void set_thread_min_count(size_t thread_min);
void adjust_thread_count(); void adjust_thread_count();
size_t calculate_thread_count_nolock(); size_t calculate_thread_count_nolock();
void set_loadavg_target(double target); void set_loadavg_target(double target);
@ -269,7 +271,7 @@ namespace crucible {
m_thread_target = min(max(0.0, m_thread_target), double(m_configured_thread_max)); m_thread_target = min(max(0.0, m_thread_target), double(m_configured_thread_max));
// Convert to integer but keep within range // Convert to integer but keep within range
const size_t rv = min(size_t(ceil(m_thread_target)), m_configured_thread_max); const size_t rv = max(m_thread_min, min(size_t(ceil(m_thread_target)), m_configured_thread_max));
return rv; return rv;
} }
@ -306,6 +308,22 @@ namespace crucible {
s_tms->set_thread_count(thread_max); s_tms->set_thread_count(thread_max);
} }
void
TaskMasterState::set_thread_min_count(size_t thread_min)
{
unique_lock<mutex> lock(m_mutex);
m_thread_min = thread_min;
lock.unlock();
adjust_thread_count();
start_stop_threads();
}
void
TaskMaster::set_thread_min_count(size_t thread_min)
{
s_tms->set_thread_min_count(thread_min);
}
void void
TaskMasterState::loadavg_thread_fn() TaskMasterState::loadavg_thread_fn()
{ {

View File

@ -45,6 +45,7 @@ do_cmd_help(char *argv[])
"\t-h, --help\t\tShow this help\n" "\t-h, --help\t\tShow this help\n"
"\t-c, --thread-count\tWorker thread count (default CPU count * factor)\n" "\t-c, --thread-count\tWorker thread count (default CPU count * factor)\n"
"\t-C, --thread-factor\tWorker thread factor (default " << BEES_DEFAULT_THREAD_FACTOR << ")\n" "\t-C, --thread-factor\tWorker thread factor (default " << BEES_DEFAULT_THREAD_FACTOR << ")\n"
"\t-G, --thread-min\t\tMinimum worker thread count with load average target (default 0)\n"
"\t-g, --loadavg-target\t\tTarget load average for worker threads (default is no target)\n" "\t-g, --loadavg-target\t\tTarget load average for worker threads (default is no target)\n"
"\t-m, --scan-mode\t\tScanning mode (0..2, default 0)\n" "\t-m, --scan-mode\t\tScanning mode (0..2, default 0)\n"
"\t-t, --timestamps\tShow timestamps in log output (default)\n" "\t-t, --timestamps\tShow timestamps in log output (default)\n"
@ -653,6 +654,7 @@ bees_main(int argc, char *argv[])
bool chatter_prefix_timestamp = true; bool chatter_prefix_timestamp = true;
double thread_factor = 0; double thread_factor = 0;
unsigned thread_count = 0; unsigned thread_count = 0;
unsigned thread_min = 0;
double load_target = 0; double load_target = 0;
// Parse options // Parse options
@ -661,18 +663,19 @@ bees_main(int argc, char *argv[])
int option_index = 0; int option_index = 0;
static const struct option long_options[] = { static const struct option long_options[] = {
{ "thread-factor", required_argument, NULL, 'C' }, { "thread-factor", required_argument, NULL, 'C' },
{ "thread-min", required_argument, NULL, 'G' },
{ "strip-paths", no_argument, NULL, 'P' }, { "strip-paths", no_argument, NULL, 'P' },
{ "no-timestamps", no_argument, NULL, 'T' }, { "no-timestamps", no_argument, NULL, 'T' },
{ "thread-count", required_argument, NULL, 'c' }, { "thread-count", required_argument, NULL, 'c' },
{ "help", no_argument, NULL, 'h' },
{ "loadavg-target", required_argument, NULL, 'g' }, { "loadavg-target", required_argument, NULL, 'g' },
{ "help", no_argument, NULL, 'h' },
{ "scan-mode", required_argument, NULL, 'm' }, { "scan-mode", required_argument, NULL, 'm' },
{ "absolute-paths", no_argument, NULL, 'p' }, { "absolute-paths", no_argument, NULL, 'p' },
{ "timestamps", no_argument, NULL, 't' }, { "timestamps", no_argument, NULL, 't' },
{ "verbose", required_argument, NULL, 'v' }, { "verbose", required_argument, NULL, 'v' },
}; };
c = getopt_long(argc, argv, "C:PTc:hg:m:ptv:", long_options, &option_index); c = getopt_long(argc, argv, "C:G:PTc:hg:m:ptv:", long_options, &option_index);
if (-1 == c) { if (-1 == c) {
break; break;
} }
@ -682,6 +685,9 @@ bees_main(int argc, char *argv[])
case 'C': case 'C':
thread_factor = stod(optarg); thread_factor = stod(optarg);
break; break;
case 'G':
thread_min = stoul(optarg);
break;
case 'P': case 'P':
crucible::set_relative_path(cwd); crucible::set_relative_path(cwd);
break; break;
@ -748,10 +754,12 @@ bees_main(int argc, char *argv[])
if (load_target != 0) { if (load_target != 0) {
BEESLOGNOTICE("setting load average target to " << load_target); BEESLOGNOTICE("setting load average target to " << load_target);
BEESLOGNOTICE("setting worker thread pool minimum size to " << thread_min);
TaskMaster::set_thread_min_count(thread_min);
} }
TaskMaster::set_loadavg_target(load_target); TaskMaster::set_loadavg_target(load_target);
BEESLOGNOTICE("setting worker thread pool maximum size to " << load_target); BEESLOGNOTICE("setting worker thread pool maximum size to " << thread_count);
TaskMaster::set_thread_count(thread_count); TaskMaster::set_thread_count(thread_count);
// Create a context and start crawlers // Create a context and start crawlers