| 352 | //////////////////////////////////////////////////////// |
| 353 | |
| 354 | ThreadPool::ThreadPool(const ThreadPoolBuilder& builder) |
| 355 | : name_(builder.name_), |
| 356 | min_threads_(builder.min_threads_), |
| 357 | max_threads_(builder.max_threads_), |
| 358 | max_queue_size_(builder.max_queue_size_), |
| 359 | idle_timeout_(builder.idle_timeout_), |
| 360 | pool_status_(Status::Uninitialized("The pool was not initialized.")), |
| 361 | idle_cond_(&lock_), |
| 362 | no_threads_cond_(&lock_), |
| 363 | num_threads_(0), |
| 364 | num_threads_pending_start_(0), |
| 365 | active_threads_(0), |
| 366 | total_queued_tasks_(0), |
| 367 | tokenless_(NewToken(ExecutionMode::CONCURRENT)), |
| 368 | metrics_(builder.metrics_), |
| 369 | scheduler_(nullptr), |
| 370 | schedule_period_ms_(builder.schedule_period_ms_), |
| 371 | enable_scheduler_(builder.enable_scheduler_) { |
| 372 | string prefix = !builder.trace_metric_prefix_.empty() ? |
| 373 | builder.trace_metric_prefix_ : builder.name_; |
| 374 | |
| 375 | queue_time_trace_metric_name_ = TraceMetrics::InternName( |
| 376 | prefix + ".queue_time_us"); |
| 377 | run_wall_time_trace_metric_name_ = TraceMetrics::InternName( |
| 378 | prefix + ".run_wall_time_us"); |
| 379 | run_cpu_time_trace_metric_name_ = TraceMetrics::InternName( |
| 380 | prefix + ".run_cpu_time_us"); |
| 381 | |
| 382 | const auto& ovt = builder.queue_overload_threshold_; |
| 383 | if (ovt.Initialized() && ovt.ToNanoseconds() > 0) { |
| 384 | load_meter_.reset(new QueueLoadMeter(*this, ovt, max_threads_)); |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | ThreadPool::~ThreadPool() { |
| 389 | // There should only be one live token: the one used in tokenless submission. |