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_thread.h"
17 #include <algorithm>
18 #include <unistd.h>
19 #include <sys/syscall.h>
20 #include "dfx/log/ffrt_log_api.h"
21 #ifdef FFRT_WORKERS_DYNAMIC_SCALING
22 #include "eu/blockaware.h"
23 #endif
24 #include "eu/execute_unit.h"
25 #include "eu/osattr_manager.h"
26 #include "eu/qos_interface.h"
27 #include "qos.h"
28 #include "util/ffrt_facade.h"
29 #include "util/name_manager.h"
30
31 namespace ffrt {
WorkerThread(const QoS & qos)32 WorkerThread::WorkerThread(const QoS& qos) : exited(false), idle(false), tid(-1), qos(qos)
33 {
34 #ifdef FFRT_PTHREAD_ENABLE
35 pthread_attr_init(&attr_);
36 size_t stackSize = FFRTFacade::GetEUInstance().GetGroupCtl()[qos()].workerStackSize;
37 if (stackSize > 0) {
38 pthread_attr_setstacksize(&attr_, stackSize);
39 }
40 #endif
41 #ifdef FFRT_WORKERS_DYNAMIC_SCALING
42 domain_id = (qos() <= BLOCKAWARE_DOMAIN_ID_MAX) ? qos() : BLOCKAWARE_DOMAIN_ID_MAX + 1;
43 #endif
44 }
45
NativeConfig()46 void WorkerThread::NativeConfig()
47 {
48 pid_t pid = syscall(SYS_gettid);
49 this->tid = pid;
50 SetThreadAttr(this, qos);
51 }
52
WorkerSetup(WorkerThread * wthread)53 void WorkerThread::WorkerSetup(WorkerThread* wthread)
54 {
55 static int threadIndex[QoS::MaxNum()] = {0};
56 std::string qosStr = std::to_string(qos());
57 std::string threadName = std::string(WORKER_THREAD_NAME_PREFIX) + qosStr +
58 std::string(WORKER_THREAD_SYMBOL) + std::to_string(threadIndex[qos()]++);
59 if (qosStr == "") {
60 FFRT_LOGE("ffrt threadName qos[%d] index[%d]", qos(), threadIndex[qos()]);
61 }
62 pthread_setname_np(wthread->GetThread(), threadName.c_str());
63 }
64
SetCpuAffinity(unsigned long affinity,int tid)65 int SetCpuAffinity(unsigned long affinity, int tid)
66 {
67 cpu_set_t mask;
68 CPU_ZERO(&mask);
69 for (unsigned long i = 0; i < sizeof(affinity) * 8; i++) {
70 if ((affinity & (static_cast<unsigned long>(1) << i)) != 0) {
71 CPU_SET(i, &mask);
72 }
73 }
74 int ret = syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask);
75 if (ret < 0) {
76 FFRT_LOGE("set qos affinity failed for tid %d\n", tid);
77 }
78 return ret;
79 }
80
SetThreadAttr(WorkerThread * thread,const QoS & qos)81 void SetThreadAttr(WorkerThread* thread, const QoS& qos)
82 {
83 if (qos() <= qos_max) {
84 FFRTQosApplyForOther(qos(), thread->Id());
85 FFRT_LOGD("qos apply tid[%d] level[%d]\n", thread->Id(), qos());
86 }
87 }
88 }; // namespace ffrt
89