1 /*
2  * Copyright (c) 2023 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 "eu/worker_manager.h"
17 #include "sched/workgroup_internal.h"
18 
19 namespace ffrt {
JoinRtg(QoS & qos)20 void WorkerManager::JoinRtg(QoS& qos)
21 {
22     auto& tgwrap = groupCtl[qos];
23     std::shared_lock<std::shared_mutex> lck(tgwrap.tgMutex);
24     for (auto& thread : tgwrap.threads) {
25         pid_t tid = thread.first->Id();
26         if (!JoinWG(tid)) {
27             FFRT_LOGE("Failed to Join Thread %d", tid);
28         }
29     }
30 }
31 
JoinTG(QoS & qos)32 ThreadGroup* WorkerManager::JoinTG(QoS& qos)
33 {
34     auto& tgwrap = groupCtl[qos];
35     if (!tgwrap.tg) {
36         return nullptr;
37     }
38 
39     std::unique_lock<std::shared_mutex> lck(tgwrap.tgMutex);
40 
41     if (tgwrap.tgRefCount++ > 0) {
42         return tgwrap.tg.get();
43     }
44 
45     if (!(tgwrap.tg->Init())) {
46         FFRT_LOGE("Init Thread Group Failed");
47         return tgwrap.tg.get();
48     }
49 
50     for (auto& thread : tgwrap.threads) {
51         pid_t tid = thread.first->Id();
52         if (!(tgwrap.tg->Join(tid))) {
53             FFRT_LOGE("Failed to Join Thread %d", tid);
54         }
55     }
56     return tgwrap.tg.get();
57 }
58 
LeaveTG(QoS & qos)59 void WorkerManager::LeaveTG(QoS& qos)
60 {
61     auto& tgwrap = groupCtl[qos];
62     if (!tgwrap.tg) {
63         return;
64     }
65 
66     std::unique_lock<std::shared_mutex> lck(tgwrap.tgMutex);
67 
68     if (tgwrap.tgRefCount == 0) {
69         return;
70     }
71 
72     if (--tgwrap.tgRefCount == 0) {
73         if (qos != qos_user_interactive) {
74             for (auto& thread : groupCtl[qos].threads) {
75                 pid_t tid = thread.first->Id();
76                 if (!(tgwrap.tg->Leave(tid))) {
77                     FFRT_LOGE("Failed to Leave Thread %d", tid);
78                 }
79             }
80         }
81 
82         if (!(tgwrap.tg->Release())) {
83             FFRT_LOGE("Release Thread Group Failed");
84         }
85     }
86 }
87 }; // namespace ffrt
88