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