1484543d1Sopenharmony_ci/*
2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License.
5484543d1Sopenharmony_ci * You may obtain a copy of the License at
6484543d1Sopenharmony_ci *
7484543d1Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8484543d1Sopenharmony_ci *
9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and
13484543d1Sopenharmony_ci * limitations under the License.
14484543d1Sopenharmony_ci */
15484543d1Sopenharmony_ci
16484543d1Sopenharmony_ci#include "eu/worker_thread.h"
17484543d1Sopenharmony_ci#include <algorithm>
18484543d1Sopenharmony_ci#include <unistd.h>
19484543d1Sopenharmony_ci#include <sys/syscall.h>
20484543d1Sopenharmony_ci#include "dfx/log/ffrt_log_api.h"
21484543d1Sopenharmony_ci#ifdef FFRT_WORKERS_DYNAMIC_SCALING
22484543d1Sopenharmony_ci#include "eu/blockaware.h"
23484543d1Sopenharmony_ci#endif
24484543d1Sopenharmony_ci#include "eu/execute_unit.h"
25484543d1Sopenharmony_ci#include "eu/osattr_manager.h"
26484543d1Sopenharmony_ci#include "eu/qos_interface.h"
27484543d1Sopenharmony_ci#include "qos.h"
28484543d1Sopenharmony_ci#include "util/ffrt_facade.h"
29484543d1Sopenharmony_ci#include "util/name_manager.h"
30484543d1Sopenharmony_ci
31484543d1Sopenharmony_cinamespace ffrt {
32484543d1Sopenharmony_ciWorkerThread::WorkerThread(const QoS& qos) : exited(false), idle(false), tid(-1), qos(qos)
33484543d1Sopenharmony_ci{
34484543d1Sopenharmony_ci#ifdef FFRT_PTHREAD_ENABLE
35484543d1Sopenharmony_ci    pthread_attr_init(&attr_);
36484543d1Sopenharmony_ci    size_t stackSize = FFRTFacade::GetEUInstance().GetGroupCtl()[qos()].workerStackSize;
37484543d1Sopenharmony_ci    if (stackSize > 0) {
38484543d1Sopenharmony_ci        pthread_attr_setstacksize(&attr_, stackSize);
39484543d1Sopenharmony_ci    }
40484543d1Sopenharmony_ci#endif
41484543d1Sopenharmony_ci#ifdef FFRT_WORKERS_DYNAMIC_SCALING
42484543d1Sopenharmony_ci    domain_id = (qos() <= BLOCKAWARE_DOMAIN_ID_MAX) ? qos() : BLOCKAWARE_DOMAIN_ID_MAX + 1;
43484543d1Sopenharmony_ci#endif
44484543d1Sopenharmony_ci}
45484543d1Sopenharmony_ci
46484543d1Sopenharmony_civoid WorkerThread::NativeConfig()
47484543d1Sopenharmony_ci{
48484543d1Sopenharmony_ci    pid_t pid = syscall(SYS_gettid);
49484543d1Sopenharmony_ci    this->tid = pid;
50484543d1Sopenharmony_ci    SetThreadAttr(this, qos);
51484543d1Sopenharmony_ci}
52484543d1Sopenharmony_ci
53484543d1Sopenharmony_civoid WorkerThread::WorkerSetup(WorkerThread* wthread)
54484543d1Sopenharmony_ci{
55484543d1Sopenharmony_ci    static int threadIndex[QoS::MaxNum()] = {0};
56484543d1Sopenharmony_ci    std::string qosStr = std::to_string(qos());
57484543d1Sopenharmony_ci    std::string threadName = std::string(WORKER_THREAD_NAME_PREFIX) + qosStr +
58484543d1Sopenharmony_ci        std::string(WORKER_THREAD_SYMBOL) + std::to_string(threadIndex[qos()]++);
59484543d1Sopenharmony_ci    if (qosStr == "") {
60484543d1Sopenharmony_ci        FFRT_LOGE("ffrt threadName qos[%d] index[%d]", qos(), threadIndex[qos()]);
61484543d1Sopenharmony_ci    }
62484543d1Sopenharmony_ci    pthread_setname_np(wthread->GetThread(), threadName.c_str());
63484543d1Sopenharmony_ci}
64484543d1Sopenharmony_ci
65484543d1Sopenharmony_ciint SetCpuAffinity(unsigned long affinity, int tid)
66484543d1Sopenharmony_ci{
67484543d1Sopenharmony_ci    cpu_set_t mask;
68484543d1Sopenharmony_ci    CPU_ZERO(&mask);
69484543d1Sopenharmony_ci    for (unsigned long i = 0; i < sizeof(affinity) * 8; i++) {
70484543d1Sopenharmony_ci        if ((affinity & (static_cast<unsigned long>(1) << i)) != 0) {
71484543d1Sopenharmony_ci            CPU_SET(i, &mask);
72484543d1Sopenharmony_ci        }
73484543d1Sopenharmony_ci    }
74484543d1Sopenharmony_ci    int ret = syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask);
75484543d1Sopenharmony_ci    if (ret < 0) {
76484543d1Sopenharmony_ci        FFRT_LOGE("set qos affinity failed for tid %d\n", tid);
77484543d1Sopenharmony_ci    }
78484543d1Sopenharmony_ci    return ret;
79484543d1Sopenharmony_ci}
80484543d1Sopenharmony_ci
81484543d1Sopenharmony_civoid SetThreadAttr(WorkerThread* thread, const QoS& qos)
82484543d1Sopenharmony_ci{
83484543d1Sopenharmony_ci    if (qos() <= qos_max) {
84484543d1Sopenharmony_ci        FFRTQosApplyForOther(qos(), thread->Id());
85484543d1Sopenharmony_ci        FFRT_LOGD("qos apply tid[%d] level[%d]\n", thread->Id(), qos());
86484543d1Sopenharmony_ci    }
87484543d1Sopenharmony_ci}
88484543d1Sopenharmony_ci}; // namespace ffrt
89