1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_TASKPOOL_TASKPOOL_H
17#define ECMASCRIPT_TASKPOOL_TASKPOOL_H
18
19#include <memory>
20
21#include "ecmascript/common.h"
22#include "ecmascript/taskpool/runner.h"
23#include "ecmascript/platform/mutex.h"
24#include "ecmascript/daemon/daemon_thread.h"
25
26namespace panda::ecmascript {
27class PUBLIC_API Taskpool {
28public:
29    PUBLIC_API static Taskpool *GetCurrentTaskpool();
30
31    Taskpool() = default;
32    PUBLIC_API ~Taskpool()
33    {
34        LockHolder lock(mutex_);
35        runner_->TerminateThread();
36        isInitialized_ = 0;
37    }
38
39    NO_COPY_SEMANTIC(Taskpool);
40    NO_MOVE_SEMANTIC(Taskpool);
41
42    void Initialize(int threadNum = DEFAULT_TASKPOOL_THREAD_NUM,
43        std::function<void(os::thread::native_handle_type)> prologueHook = nullptr,
44        const std::function<void(os::thread::native_handle_type)> epilogueHook = nullptr);
45    void Destroy(int32_t id);
46
47    void PostTask(std::unique_ptr<Task> task) const
48    {
49        if (isInitialized_ > 0) {
50            runner_->PostTask(std::move(task));
51        }
52    }
53
54    // Terminate a task of a specified type
55    void TerminateTask(int32_t id, TaskType type = TaskType::ALL);
56
57    uint32_t GetTotalThreadNum() const
58    {
59        return runner_->GetTotalThreadNum();
60    }
61
62    bool IsInThreadPool(std::thread::id id) const
63    {
64        return runner_->IsInThreadPool(id);
65    }
66
67    bool IsDaemonThreadOrInThreadPool(std::thread::id id) const
68    {
69        DaemonThread *dThread = DaemonThread::GetInstance();
70        return IsInThreadPool(id) || (dThread != nullptr
71            && dThread->GetThreadId() == JSThread::GetCurrentThreadId());
72    }
73
74    void SetThreadPriority(PriorityMode mode)
75    {
76        runner_->SetQosPriority(mode);
77    }
78
79    void ForEachTask(const std::function<void(Task*)> &f);
80
81private:
82    virtual uint32_t TheMostSuitableThreadNum(uint32_t threadNum) const;
83
84    std::unique_ptr<Runner> runner_;
85    volatile int isInitialized_ = 0;
86    Mutex mutex_;
87};
88}  // namespace panda::ecmascript
89#endif  // ECMASCRIPT_PALTFORM_PLATFORM_H
90