1 /*
2  * Copyright (c) 2024 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 #include "ThrTaskContainer.h"
17 #include <sys/prctl.h>
18 #include <thread>
19 #include "hiview_logger.h"
20 
21 DEFINE_LOG_LABEL(0xD002D66, "Hiview-XPerformance");
22 
23 /* ThrTaskContainer */
StartLoop(const std::string & threadName)24 void ThrTaskContainer::StartLoop(const std::string& threadName)
25 {
26     std::thread startLoopThread(&ThrTaskContainer::Entry, this, threadName);
27     startLoopThread.detach();
28 }
29 
StopLoop()30 void ThrTaskContainer::StopLoop()
31 {
32 }
33 
PostTask(ITask * task)34 void ThrTaskContainer::PostTask(ITask* task)
35 {
36     if (task == nullptr) {
37         throw std::invalid_argument("null task");
38     }
39     std::unique_lock <std::mutex> uniqueLock(mut);
40     if (!IsTaskOverLimit()) {
41         tasks.push_back(task);
42     }
43     cv.notify_one();
44 }
45 
IsTaskOverLimit()46 bool ThrTaskContainer::IsTaskOverLimit()
47 {
48     if (tasks.size() < maxTaskSize) {
49         return false;
50     }
51     HIVIEW_LOGI("CheckTaskVectorLimit over limit");
52     for (auto& task: tasks) {
53         delete task;
54         task = nullptr;
55     }
56     tasks.clear();
57     return true;
58 }
59 
Entry(const std::string & threadName)60 void ThrTaskContainer::Entry(const std::string& threadName)
61 {
62     std::unique_lock <std::mutex> uniqueLock(mut);
63     prctl(PR_SET_NAME, threadName.c_str(), nullptr, nullptr, nullptr);
64     while (true) {
65         while (tasks.empty()) {
66             cv.wait(uniqueLock);
67             continue;
68         }
69         ITask* task = tasks.front();
70         if (task == nullptr) {
71             HIVIEW_LOGE("Entry task is null");
72             continue;
73         }
74         std::string taskInfo = task->GetTaskInfo();
75         tasks.erase(tasks.begin());
76         uniqueLock.unlock();
77         task->Run();
78         uniqueLock.lock();
79     }
80     // delete this;?
81 }