13f4cbf05Sopenharmony_ci/*
23f4cbf05Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License.
53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at
63f4cbf05Sopenharmony_ci *
73f4cbf05Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f4cbf05Sopenharmony_ci *
93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and
133f4cbf05Sopenharmony_ci * limitations under the License.
143f4cbf05Sopenharmony_ci */
153f4cbf05Sopenharmony_ci#ifndef THREAD_POOL_H
163f4cbf05Sopenharmony_ci#define THREAD_POOL_H
173f4cbf05Sopenharmony_ci
183f4cbf05Sopenharmony_ci#include "nocopyable.h"
193f4cbf05Sopenharmony_ci
203f4cbf05Sopenharmony_ci#include <thread>
213f4cbf05Sopenharmony_ci#include <mutex>
223f4cbf05Sopenharmony_ci#include <functional>
233f4cbf05Sopenharmony_ci#include <string>
243f4cbf05Sopenharmony_ci#include <condition_variable>
253f4cbf05Sopenharmony_ci#include <deque>
263f4cbf05Sopenharmony_ci#include <vector>
273f4cbf05Sopenharmony_ci
283f4cbf05Sopenharmony_cinamespace OHOS {
293f4cbf05Sopenharmony_ci/**
303f4cbf05Sopenharmony_ci * @brief Provides interfaces for thread-safe thread pool operations.
313f4cbf05Sopenharmony_ci *
323f4cbf05Sopenharmony_ci * The thread-safe is for the thread pool, but not for the threads in the pool.
333f4cbf05Sopenharmony_ci * A task queue and a thread group are under control. Users add tasks to the
343f4cbf05Sopenharmony_ci * task queue, and the thread group executes the tasks in the task queue.
353f4cbf05Sopenharmony_ci */
363f4cbf05Sopenharmony_ciclass ThreadPool : public NoCopyable {
373f4cbf05Sopenharmony_cipublic:
383f4cbf05Sopenharmony_ci    typedef std::function<void()> Task;
393f4cbf05Sopenharmony_ci
403f4cbf05Sopenharmony_ci    /**
413f4cbf05Sopenharmony_ci     * @brief Creates a thread pool and names the threads in the pool.
423f4cbf05Sopenharmony_ci     *
433f4cbf05Sopenharmony_ci     * @param name Indicates the prefix of the names of the threads in pool.
443f4cbf05Sopenharmony_ci     * The names of threads in the pool are in the <b>name</b> + No format.
453f4cbf05Sopenharmony_ci     * The thread name is a meaningful C language string, whose length is
463f4cbf05Sopenharmony_ci     * restricted to 16 characters including the terminating null byte ('\0').
473f4cbf05Sopenharmony_ci     * Pay attention to the name length when setting this parameter.
483f4cbf05Sopenharmony_ci     * For example, if the number of threads in the pool is less than 10,
493f4cbf05Sopenharmony_ci     * the name length cannot exceed 14 characters.
503f4cbf05Sopenharmony_ci     */
513f4cbf05Sopenharmony_ci    explicit ThreadPool(const std::string &name = std::string());
523f4cbf05Sopenharmony_ci    ~ThreadPool() override;
533f4cbf05Sopenharmony_ci
543f4cbf05Sopenharmony_ci    /**
553f4cbf05Sopenharmony_ci     * @brief Starts a given number of threads, which will execute
563f4cbf05Sopenharmony_ci     * the tasks in a task queue.
573f4cbf05Sopenharmony_ci     *
583f4cbf05Sopenharmony_ci     * @param threadsNum Indicates the number of threads to start.
593f4cbf05Sopenharmony_ci     */
603f4cbf05Sopenharmony_ci    uint32_t Start(int threadsNum);
613f4cbf05Sopenharmony_ci    /**
623f4cbf05Sopenharmony_ci     * @brief Stops the thread pool.
633f4cbf05Sopenharmony_ci     */
643f4cbf05Sopenharmony_ci    void Stop();
653f4cbf05Sopenharmony_ci    /**
663f4cbf05Sopenharmony_ci     * @brief Adds a task to the task queue.
673f4cbf05Sopenharmony_ci     *
683f4cbf05Sopenharmony_ci     * If <b>Start()</b> has never been called, the task will be executed
693f4cbf05Sopenharmony_ci     * immediately.
703f4cbf05Sopenharmony_ci     *
713f4cbf05Sopenharmony_ci     * @param f Indicates the task to add.
723f4cbf05Sopenharmony_ci     */
733f4cbf05Sopenharmony_ci    void AddTask(const Task& f);
743f4cbf05Sopenharmony_ci    /**
753f4cbf05Sopenharmony_ci     * @brief Sets the maximum number of tasks in the task queue.
763f4cbf05Sopenharmony_ci     *
773f4cbf05Sopenharmony_ci     * @param maxSize Indicates the maximum number of tasks to set.
783f4cbf05Sopenharmony_ci     */
793f4cbf05Sopenharmony_ci    void SetMaxTaskNum(size_t maxSize) { maxTaskNum_ = maxSize; }
803f4cbf05Sopenharmony_ci
813f4cbf05Sopenharmony_ci    // for testability
823f4cbf05Sopenharmony_ci    /**
833f4cbf05Sopenharmony_ci     * @brief Obtains the maximum number of tasks in the task queue.
843f4cbf05Sopenharmony_ci     */
853f4cbf05Sopenharmony_ci    size_t GetMaxTaskNum() const { return maxTaskNum_; }
863f4cbf05Sopenharmony_ci    /**
873f4cbf05Sopenharmony_ci     * @brief Obtains the number of tasks in the task queue.
883f4cbf05Sopenharmony_ci     */
893f4cbf05Sopenharmony_ci    size_t GetCurTaskNum();
903f4cbf05Sopenharmony_ci    /**
913f4cbf05Sopenharmony_ci     * @brief Obtains the number of threads in the pool.
923f4cbf05Sopenharmony_ci     */
933f4cbf05Sopenharmony_ci    size_t GetThreadsNum() const { return threads_.size(); }
943f4cbf05Sopenharmony_ci    /**
953f4cbf05Sopenharmony_ci     * @brief Obtains the name of the thread pool.
963f4cbf05Sopenharmony_ci     */
973f4cbf05Sopenharmony_ci    std::string GetName() const { return myName_; }
983f4cbf05Sopenharmony_ci
993f4cbf05Sopenharmony_ciprivate:
1003f4cbf05Sopenharmony_ci    // If the number of tasks in the queue reaches the maximum set by maxQueueSize, the thread pool is full load.
1013f4cbf05Sopenharmony_ci    bool Overloaded() const;
1023f4cbf05Sopenharmony_ci    void WorkInThread(); // main function in each thread.
1033f4cbf05Sopenharmony_ci    Task ScheduleTask(); // fetch a task from the queue and execute it
1043f4cbf05Sopenharmony_ci
1053f4cbf05Sopenharmony_ciprivate:
1063f4cbf05Sopenharmony_ci    std::string myName_;
1073f4cbf05Sopenharmony_ci    std::mutex mutex_;
1083f4cbf05Sopenharmony_ci    std::condition_variable hasTaskToDo_;
1093f4cbf05Sopenharmony_ci    std::condition_variable acceptNewTask_;
1103f4cbf05Sopenharmony_ci    std::vector<std::thread> threads_;
1113f4cbf05Sopenharmony_ci    std::deque<Task> tasks_;
1123f4cbf05Sopenharmony_ci    size_t maxTaskNum_;
1133f4cbf05Sopenharmony_ci    bool running_;
1143f4cbf05Sopenharmony_ci};
1153f4cbf05Sopenharmony_ci
1163f4cbf05Sopenharmony_ci} // namespace OHOS
1173f4cbf05Sopenharmony_ci
1183f4cbf05Sopenharmony_ci#endif
1193f4cbf05Sopenharmony_ci
120