Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 : #include "aicpusd_worker.h"
11 :
12 : #include <csignal>
13 : #include <cstring>
14 : #include <fstream>
15 :
16 : #include "aicpusd_status.h"
17 : #include "aicpusd_drv_manager.h"
18 : #include "aicpusd_monitor.h"
19 : #include "aicpusd_event_manager.h"
20 : #include "aicpu_context.h"
21 : #include "aicpusd_common.h"
22 : #include "aicpu_cust_sd_proc_mgr_sys_operator_agent.h"
23 : #include "aicpusd_hal_interface_ref.h"
24 : #include "aicpusd_util.h"
25 : #include "feature_ctrl.h"
26 : #ifndef _AOSCORE_
27 : #include "seccomp.h"
28 : #endif
29 :
30 : namespace {
31 : constexpr uint32_t EVENT_MASK = (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_RANDOM_KERNEL)) |
32 : (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_TS_HWTS_KERNEL)) |
33 : (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_AICPU_MSG)) |
34 : (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_TS_CTRL_MSG)) |
35 : (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_SPLIT_KERNEL)) |
36 : (static_cast<uint32_t>(1U) << static_cast<uint32_t>(EVENT_FFTS_PLUS_MSG));
37 : constexpr const char_t* SYSCALL_WHITE_LIST = "/var/aicpu_custom_syscall_whitelist";
38 : constexpr size_t NO_AICPU_WORKER_NUM = 2UL;
39 : constexpr uint32_t INVALID_CPU_ID = UINT32_MAX;
40 : } // namespace
41 :
42 : namespace AicpuSchedule {
43 24 : ThreadPool& ThreadPool::Instance()
44 : {
45 24 : static ThreadPool threadPool;
46 24 : return threadPool;
47 : }
48 :
49 32 : ThreadPool::ThreadPool() : semInitedNum_(0U) {}
50 :
51 32 : ThreadPool::~ThreadPool()
52 : {
53 39 : for (size_t i = 0UL; i < semInitedNum_; ++i) {
54 7 : (void)sem_destroy(&(sems_[i]));
55 : }
56 32 : }
57 :
58 21 : size_t ThreadPool::GetWorkerNum()
59 : {
60 21 : const size_t aicpuNum = static_cast<size_t>(AicpuDrvManager::GetInstance().GetAicpuNum());
61 21 : return (aicpuNum == 0UL) ? NO_AICPU_WORKER_NUM : aicpuNum;
62 : }
63 :
64 7 : int32_t ThreadPool::CreateWorker()
65 : {
66 7 : const size_t workerNum = GetWorkerNum();
67 7 : hasAicpu_ = AicpuDrvManager::GetInstance().GetAicpuNum() != 0U;
68 7 : if (!hasAicpu_) {
69 2 : aicpusd_run_info("aicpu num[0], create [%zu] aicpu workers", workerNum);
70 : }
71 : try {
72 14 : sems_ = std::move(std::vector<sem_t>(workerNum));
73 0 : } catch (std::exception& e) {
74 0 : aicpusd_err("create sems failed, %s", e.what());
75 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
76 0 : }
77 15 : for (size_t threadIndex = 0UL; threadIndex < workerNum; ++threadIndex) {
78 9 : const int32_t semInitRet = sem_init(&(sems_[threadIndex]), 0, 0U);
79 9 : if (semInitRet == -1) {
80 1 : aicpusd_err("sem[%zu] init failed, %s", threadIndex, strerror(errno));
81 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
82 : }
83 8 : semInitedNum_ = static_cast<uint32_t>(threadIndex + 1UL);
84 : }
85 : try {
86 12 : threadStatus_ = std::move(std::vector<ThreadStatus>(workerNum, ThreadStatus::THREAD_INIT));
87 0 : } catch (std::exception& e) {
88 0 : aicpusd_err("create ThreadStatus failed, %s", e.what());
89 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
90 0 : }
91 6 : int32_t ret = AICPU_SCHEDULE_OK;
92 6 : const sighandler_t oldHandler = signal(SIGCHLD, SIG_DFL);
93 6 : aicpusd_info("Set SIGCHLD to %d, old sighandler[%d]", SIG_DFL, oldHandler);
94 6 : GetExpandedSysCalls(SYSCALL_WHITE_LIST);
95 13 : for (size_t threadIndex = 0UL; threadIndex < workerNum; ++threadIndex) {
96 8 : ret = CreateOneWorker(static_cast<uint32_t>(threadIndex));
97 8 : if (ret != AICPU_SCHEDULE_OK) {
98 1 : (void)signal(SIGCHLD, oldHandler);
99 1 : return ret;
100 : }
101 : }
102 9 : for (size_t threadIndex = 0UL; threadIndex < workerNum; ++threadIndex) {
103 7 : const int32_t semWaitRet = sem_wait(&(sems_[threadIndex]));
104 7 : if (semWaitRet == -1) {
105 1 : (void)signal(SIGCHLD, oldHandler);
106 1 : aicpusd_err("sem[%zu] wait failed, %s", threadIndex, strerror(errno));
107 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
108 : }
109 6 : if (threadStatus_[threadIndex] != ThreadStatus::THREAD_RUNNING) {
110 2 : (void)signal(SIGCHLD, oldHandler);
111 2 : aicpusd_err("create thread[%zu] failed, status[%d]", threadIndex, threadStatus_[threadIndex]);
112 2 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
113 : }
114 : }
115 2 : aicpusd_info("set SIGCHLD to old sighandler[%d]", oldHandler);
116 2 : (void)signal(SIGCHLD, oldHandler);
117 : // GetInstance is not null, checked in InitAICPUScheduler
118 2 : ret = AicpuSchedule::AicpuMonitor::GetInstance().Run();
119 2 : if (ret != AICPU_SCHEDULE_OK) {
120 0 : aicpusd_err("aicpu monitor run failed, ret[%d]", ret);
121 0 : return ret;
122 : }
123 :
124 2 : return AICPU_SCHEDULE_OK;
125 : }
126 :
127 3 : int32_t ThreadPool::CreateOneWorker(const uint32_t threadIndex)
128 : {
129 3 : aicpusd_info("CreateOneWorker index[%d]", threadIndex);
130 : try {
131 3 : std::thread th(&ThreadPool::Work, threadIndex);
132 6 : workers_.emplace_back(std::move(th));
133 3 : } catch (std::exception& e) {
134 0 : aicpusd_err("create aicpu worker[%u] failed, %s", threadIndex, e.what());
135 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
136 0 : }
137 : try {
138 3 : workers_[static_cast<size_t>(threadIndex)].detach();
139 0 : } catch (std::exception& e) {
140 0 : aicpusd_err("thread[%u] detach failed, %s", threadIndex, e.what());
141 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
142 0 : }
143 :
144 3 : return AICPU_SCHEDULE_OK;
145 : }
146 :
147 8 : void ThreadPool::GetExpandedSysCalls(const char_t* const whitelist)
148 : {
149 8 : std::ifstream inFile(whitelist);
150 8 : if ((access(whitelist, R_OK) != 0) || !inFile) {
151 7 : aicpusd_info("syscall file: %s is invalid", whitelist);
152 7 : return;
153 : }
154 2 : const ScopeGuard fileGuard([&inFile]() { inFile.close(); });
155 :
156 1 : std::string syscallStr;
157 4 : while (getline(inFile, syscallStr)) {
158 3 : aicpusd_info("read syscall: %s", syscallStr.c_str());
159 3 : const int32_t syscallNo = seccomp_syscall_resolve_name(syscallStr.c_str());
160 3 : if (syscallNo < 0) {
161 1 : aicpusd_run_warn("Unknown syscall: %s, ret is %d.", syscallStr.c_str(), syscallNo);
162 1 : continue;
163 : }
164 2 : aicpusd_info("syscall: %s, syscallNo: %d", syscallStr.c_str(), syscallNo);
165 2 : (void)expandedSystemCalls_.insert(syscallNo);
166 : }
167 8 : }
168 :
169 3 : void ThreadPool::ExpandSysCallList(std::unordered_set<int32_t>& filterSystemCalls)
170 : {
171 5 : for (const auto expandedSystemCall : expandedSystemCalls_) {
172 2 : const auto insertRet = filterSystemCalls.insert(expandedSystemCall);
173 2 : if (insertRet.second) {
174 1 : aicpusd_run_info("Expand syscallNo: %d.", expandedSystemCall);
175 : }
176 : }
177 3 : }
178 :
179 5 : int32_t ThreadPool::SecureCompute(const uint32_t threadIndex)
180 : {
181 5 : if ((FeatureCtrl::IsAosCore() || (!AicpuSchedule::AicpuDrvManager::GetInstance().GetSafeVerifyFlag()))) {
182 3 : threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_RUNNING;
183 3 : aicpusd_info("Execute seccomp_load success.");
184 3 : return AICPU_SCHEDULE_OK;
185 : }
186 : std::unordered_set<int32_t> filterSystemCalls = {
187 : SCMP_SYS(open),
188 : SCMP_SYS(close),
189 : SCMP_SYS(faccessat),
190 : SCMP_SYS(fstat),
191 : SCMP_SYS(futex),
192 : SCMP_SYS(getpid),
193 : SCMP_SYS(gettid),
194 : SCMP_SYS(ioctl),
195 : SCMP_SYS(lseek),
196 : SCMP_SYS(nanosleep),
197 : SCMP_SYS(openat),
198 : SCMP_SYS(newfstatat),
199 : SCMP_SYS(pselect6),
200 : SCMP_SYS(read),
201 : SCMP_SYS(readlinkat),
202 : SCMP_SYS(rt_sigaction),
203 : SCMP_SYS(mmap),
204 : SCMP_SYS(mprotect),
205 : SCMP_SYS(exit),
206 : SCMP_SYS(exit_group),
207 : SCMP_SYS(madvise),
208 : SCMP_SYS(sched_getaffinity),
209 : SCMP_SYS(rt_sigprocmask),
210 : SCMP_SYS(set_robust_list),
211 : SCMP_SYS(munmap),
212 : SCMP_SYS(sysinfo),
213 : SCMP_SYS(clock_nanosleep),
214 : SCMP_SYS(uname),
215 : SCMP_SYS(getcpu),
216 : SCMP_SYS(write),
217 4 : SCMP_SYS(getrandom)};
218 2 : ExpandSysCallList(filterSystemCalls);
219 :
220 : // filter enable system calls
221 2 : const scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ERRNO(1U));
222 2 : int32_t ret = 0;
223 64 : for (auto filterSystemCall : filterSystemCalls) {
224 62 : ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, filterSystemCall, 0U);
225 62 : if (ret != 0) {
226 0 : threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_EXIT;
227 0 : aicpusd_err(
228 : "Add the system call failed, thread threadIndex[%u], ret[%d],"
229 : " syscall number[%d].",
230 : threadIndex, ret, filterSystemCall);
231 0 : return AICPU_SCHEDULE_ERROR_COMMON_ERROR;
232 : }
233 : }
234 :
235 2 : ret = seccomp_load(ctx);
236 2 : if (ret != 0) {
237 0 : threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_EXIT;
238 0 : aicpusd_err("Execute seccomp_load failed, thread threadIndex[%u], ret[%d].", threadIndex, ret);
239 0 : return AICPU_SCHEDULE_ERROR_COMMON_ERROR;
240 : }
241 2 : threadStatus_[static_cast<size_t>(threadIndex)] = ThreadStatus::THREAD_RUNNING;
242 2 : aicpusd_info("Execute seccomp_load success.");
243 2 : return AICPU_SCHEDULE_OK;
244 2 : }
245 :
246 7 : void ThreadPool::Work(const uint32_t threadIndex)
247 : {
248 7 : const uint32_t deviceId = AicpuSchedule::AicpuDrvManager::GetInstance().GetDeviceId();
249 : aicpu::aicpuContext_t context;
250 7 : context.tsId = 0U;
251 7 : context.deviceId = deviceId;
252 7 : context.hostPid = AicpuDrvManager::GetInstance().GetHostPid();
253 7 : context.vfId = AicpuDrvManager::GetInstance().GetVfId();
254 7 : aicpu::SetUniqueVfId(AicpuDrvManager::GetInstance().GetUniqueVfId());
255 7 : const auto aicpuRet = aicpu::aicpuSetContext(&context);
256 7 : if (aicpuRet != aicpu::AICPU_ERROR_NONE) {
257 1 : aicpusd_err("Set aicpu context failed, deviceId[%u], thread[%u].", deviceId, threadIndex);
258 1 : AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
259 3 : return;
260 : }
261 6 : aicpusd_info("Aicpu device[%u]:thread[%u] started.", deviceId, threadIndex);
262 6 : const auto ret = halEschedSubscribeEvent(deviceId, DEFAULT_GROUP_ID, threadIndex, EVENT_MASK);
263 6 : if (ret != static_cast<int32_t>(DRV_ERROR_NONE)) {
264 1 : aicpusd_err(
265 : "halEschedSubscribeEvent failed, deviceId[%u], groupId[%u], threadIndex[%u] eventBitmap[%llu].", deviceId,
266 : DEFAULT_GROUP_ID, threadIndex, EVENT_MASK);
267 1 : AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
268 1 : return;
269 : }
270 5 : aicpusd_info(
271 : "halEschedSubscribeEvent success, deviceId[%u], groupId[%u], threadIndex[%u] eventBitmap[%llu].", deviceId,
272 : DEFAULT_GROUP_ID, threadIndex, EVENT_MASK);
273 5 : if (AicpuSchedule::ThreadPool::Instance().SetAffinity(static_cast<size_t>(threadIndex), deviceId) !=
274 : AICPU_SCHEDULE_OK) {
275 0 : AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
276 0 : return;
277 : }
278 5 : if (AicpuSchedule::ThreadPool::Instance().SecureCompute(threadIndex) != AICPU_SCHEDULE_OK) {
279 1 : AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
280 1 : return;
281 : }
282 4 : AicpuSchedule::ThreadPool::Instance().PostSem(threadIndex);
283 4 : (void)aicpu::SetAicpuThreadIndex(threadIndex);
284 4 : AicpuSchedule::AicpuEventManager::GetInstance().LoopProcess(threadIndex);
285 4 : aicpusd_info("Aicpu device[%u]:thread[%u] stopped.", deviceId, threadIndex);
286 : }
287 :
288 9 : uint32_t ThreadPool::GetNoAicpuCcpuPhysIndex(const size_t threadIndex) const
289 : {
290 9 : const uint32_t ccpuNum = AicpuDrvManager::GetInstance().GetCcpuNum();
291 9 : if (ccpuNum == 0U) {
292 4 : aicpusd_err("no ctrlcpu core available for no-aicpu worker[%zu]", threadIndex);
293 4 : return INVALID_CPU_ID;
294 : }
295 5 : uint32_t ccpuLogIndex = 0U;
296 5 : if (static_cast<size_t>(ccpuNum) > threadIndex) {
297 4 : ccpuLogIndex = ccpuNum - 1U - static_cast<uint32_t>(threadIndex);
298 : }
299 5 : const uint32_t physIndex = AicpuDrvManager::GetInstance().GetCcpuPhysIndex(ccpuLogIndex);
300 5 : aicpusd_info(
301 : "no aicpu worker[%zu] bind to ctrlcpu logIndex[%u], physIndex[%u]", threadIndex, ccpuLogIndex, physIndex);
302 5 : return physIndex;
303 : }
304 :
305 4 : int32_t ThreadPool::WriteTidForAffinity(const size_t threadIndex)
306 : {
307 4 : if (threadIndex >= threadStatus_.size()) {
308 1 : aicpusd_err("threadIndex[%zu], out of rank[0, %zu]", threadIndex, threadStatus_.size());
309 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
310 : }
311 :
312 6 : std::string command = "sudo /var/add_aicpu_tid_to_tasks.sh";
313 3 : std::string pathStr = "/var/add_aicpu_tid_to_tasks.sh";
314 3 : if (access(pathStr.c_str(), F_OK) != 0) {
315 2 : aicpusd_info("Not find add_aicpu_tid_to_tasks.sh.");
316 2 : return AICPU_SCHEDULE_OK;
317 : }
318 1 : command = command + " " + std::to_string(GetTid());
319 :
320 : // system() may fail due to "No child processes".
321 : // if SIGCHLD is set to SIG_IGN, waitpid() may report ECHILD error because it cannot find the child process.
322 : // The reason is that the system() relies on a feature of the system, that is,
323 : // when the kernel initializes the process, the processing mode of SIGCHLD signal is SIG_IGN.
324 1 : const int32_t ret = AicpuSchedule::AicpuUtil::ExecuteCmd(command);
325 1 : if (ret != 0) {
326 1 : threadStatus_[threadIndex] = ThreadStatus::THREAD_EXIT;
327 1 : aicpusd_err(
328 : "write tid[%lu] to /sys/fs/cgroup/cpuset/AICPU/tasks failed, ret[%d], strerror[%s]", GetTid(), ret,
329 : strerror(errno));
330 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
331 : }
332 0 : return AICPU_SCHEDULE_OK;
333 3 : }
334 :
335 7 : int32_t ThreadPool::AddPidToTask(const size_t threadIndex)
336 : {
337 7 : if (FeatureCtrl::IsBindPidByHal()) {
338 2 : if (&halBindCgroup != nullptr) {
339 2 : aicpusd_info("Bind pid by hal index:%zu.", threadIndex);
340 2 : const drvError_t drvRet = halBindCgroup(BIND_AICPU_CGROUP);
341 2 : if (drvRet != DRV_ERROR_NONE) {
342 1 : aicpusd_err("halBindCgroup failed, ret[%d]", drvRet);
343 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
344 : }
345 1 : aicpusd_info("halBindCgroup success");
346 : } else {
347 0 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
348 : }
349 : } else {
350 5 : aicpusd_run_info("AddPidToTask by WriteTidForAffinity");
351 5 : auto ret = WriteTidForAffinity(threadIndex);
352 5 : if (ret != static_cast<int32_t>(AICPU_SCHEDULE_OK)) {
353 1 : aicpusd_err("WriteTidForAffinity failed, ret[%d]", ret);
354 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
355 : }
356 4 : aicpusd_info("WriteTidForAffinity success");
357 : }
358 5 : return AICPU_SCHEDULE_OK;
359 : }
360 :
361 7 : int32_t ThreadPool::SetAffinityByPm(const size_t threadIndex)
362 : {
363 : const uint32_t physIndex =
364 7 : hasAicpu_ ? AicpuDrvManager::GetInstance().GetAicpuPhysIndex(static_cast<uint32_t>(threadIndex)) :
365 3 : GetNoAicpuCcpuPhysIndex(threadIndex);
366 7 : if (physIndex == INVALID_CPU_ID) {
367 1 : threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
368 1 : return AICPU_SCHEDULE_OK;
369 : }
370 6 : const pid_t tid = static_cast<pid_t>(GetTid());
371 :
372 6 : std::vector<uint32_t> coreAffinity;
373 6 : coreAffinity.push_back(physIndex);
374 6 : const auto ret = ProcMgrBindThread(tid, coreAffinity);
375 6 : if (ret != 0U) {
376 1 : threadStatus_[threadIndex] = ThreadStatus::THREAD_EXIT;
377 1 : aicpusd_err(
378 : "set affinity failed ret[%d], aicpu logical threadIndex[%zu], "
379 : "aicpu physical threadIndex[%u],tid[%u], device id[%u]",
380 : ret, threadIndex, physIndex, tid, AicpuDrvManager::GetInstance().GetDeviceId());
381 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
382 : }
383 5 : threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
384 5 : aicpusd_info(
385 : "set affinity success, aicpu logical threadIndex[%zu], aicpu physical threadIndex[%u], device id[%u]",
386 : threadIndex, physIndex, AicpuDrvManager::GetInstance().GetDeviceId());
387 5 : return AICPU_SCHEDULE_OK;
388 6 : }
389 :
390 8 : int32_t ThreadPool::SetAffinityBySelf(const size_t threadIndex)
391 : {
392 8 : if (hasAicpu_ && (AddPidToTask(threadIndex) != AICPU_SCHEDULE_OK)) {
393 1 : aicpusd_err("AddPidToTask failed");
394 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
395 : }
396 :
397 : cpu_set_t mask;
398 7 : CPU_ZERO(&mask);
399 :
400 7 : uint32_t physIndex = 0;
401 7 : uint32_t devNum = 0U;
402 7 : if (hasAicpu_ && (&halGetVdevNum != nullptr)) {
403 4 : int32_t result = halGetVdevNum(&devNum);
404 4 : if (result != 0) {
405 1 : aicpusd_err("custom halGetVdevNum, failed result[%d]", result);
406 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
407 : }
408 : }
409 6 : if (!hasAicpu_) {
410 3 : physIndex = GetNoAicpuCcpuPhysIndex(threadIndex);
411 3 : } else if (devNum > 0U) {
412 2 : physIndex = AicpuDrvManager::GetInstance().GetAicpuPhysIndexInVfMode(
413 1 : static_cast<uint32_t>(threadIndex), AicpuDrvManager::GetInstance().GetDeviceId());
414 : } else {
415 2 : physIndex = AicpuDrvManager::GetInstance().GetAicpuPhysIndex(static_cast<uint32_t>(threadIndex));
416 : }
417 6 : aicpusd_info(
418 : "[custom]SetAffinityBySelf, threadIndex[%u], physIndex[%u], devNum[%u]", static_cast<uint32_t>(threadIndex),
419 : physIndex, devNum);
420 :
421 6 : if (physIndex == INVALID_CPU_ID) {
422 3 : threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
423 3 : return AICPU_SCHEDULE_OK;
424 : }
425 :
426 : // cannot overflow, aicpu num < 65535, max [64=4*16]
427 3 : CPU_SET(static_cast<int32_t>(physIndex), &mask);
428 3 : const int32_t ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask);
429 3 : if (ret != 0) {
430 1 : threadStatus_[threadIndex] = ThreadStatus::THREAD_EXIT;
431 1 : aicpusd_err(
432 : "set affinity failed ret[%d], aicpu logical threadIndex[%u], aicpu physical threadIndex[%u], "
433 : "device id[%u]",
434 : ret, threadIndex, physIndex, AicpuDrvManager::GetInstance().GetDeviceId());
435 1 : return AICPU_SCHEDULE_ERROR_INIT_FAILED;
436 : }
437 2 : threadStatus_[threadIndex] = ThreadStatus::THREAD_RUNNING;
438 2 : aicpusd_info(
439 : "set affinity success, aicpu logical threadIndex[%u], aicpu physical threadIndex[%u], device id[%u]",
440 : threadIndex, physIndex, AicpuDrvManager::GetInstance().GetDeviceId());
441 2 : return AICPU_SCHEDULE_OK;
442 : }
443 :
444 7 : int32_t ThreadPool::SetAffinity(const size_t threadIndex, const uint32_t deviceId)
445 : {
446 : (void)deviceId;
447 7 : std::string cpuSetFlag;
448 7 : const char_t* const envValue = std::getenv("PROCMGR_AICPU_CPUSET");
449 7 : if (envValue != nullptr) {
450 10 : cpuSetFlag = std::string(envValue);
451 : }
452 :
453 7 : int32_t res = AICPU_SCHEDULE_OK;
454 7 : if (cpuSetFlag == "1") {
455 3 : res = SetAffinityByPm(threadIndex);
456 3 : aicpusd_run_info(
457 : "aicpu bind tid by pm, cpuSetFlag:[%s], threadIndex[%zu], deviceId[%u], res[%d].", cpuSetFlag.c_str(),
458 : threadIndex, AicpuDrvManager::GetInstance().GetDeviceId(), res);
459 : } else {
460 4 : res = SetAffinityBySelf(threadIndex);
461 4 : aicpusd_run_info(
462 : "aicpu bind tid by self, cpuSetFlag:[%s], threadIndex[%zu], deviceId[%u], res[%d].", cpuSetFlag.c_str(),
463 : threadIndex, AicpuDrvManager::GetInstance().GetDeviceId(), res);
464 : }
465 7 : return res;
466 7 : }
467 :
468 3 : void ThreadPool::PostSem(const uint32_t threadIndex) { (void)sem_post(&(sems_[static_cast<size_t>(threadIndex)])); }
469 : } // namespace AicpuSchedule
|