1 /*
2  * Copyright (c) 2021 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 "platform/threadpool/include/aie_thread_unix.h"
17 
18 #include <csignal>
19 #include <unistd.h>
20 
21 #include "securec.h"
22 
23 #include "protocol/retcode_inner/aie_retcode_inner.h"
24 #include "utils/log/aie_log.h"
25 
26 typedef struct {
27     pthread_t handle;
28 } PthreadHandle;
29 
InitThread(PthreadData & tr)30 int InitThread(PthreadData &tr)
31 {
32     errno_t retCode = memset_s(&tr, sizeof(PthreadData), 0, sizeof(PthreadData));
33     if (retCode != EOK) {
34         HILOGE("[AieThreadUnix]Failed to memory set, retCode[%d].", retCode);
35         return RETCODE_FAILURE;
36     }
37     return RETCODE_SUCCESS;
38 }
39 
GetThreadIdUnix(const PthreadData & tr)40 unsigned long GetThreadIdUnix(const PthreadData &tr)
41 {
42     auto *rt = reinterpret_cast<const PthreadHandle *>(&tr);
43     return static_cast<unsigned long>(rt->handle);
44 }
45 
IsThreadRunning(unsigned long tid)46 bool IsThreadRunning(unsigned long tid)
47 {
48     const int checkThreadAliveSig = 0;
49     return pthread_kill(tid, checkThreadAliveSig) != ESRCH;
50 }
51 
InitThreadAttr(PthreadAttr & attr)52 void InitThreadAttr(PthreadAttr &attr)
53 {
54     attr.stackSize = THREAD_DEFAULT_STACK_SIZE;
55     attr.scope = THREAD_SCOPE_SYSTEM;
56 }
57 
SetThreadAttrStackSize(PthreadAttr & attr,size_t size)58 void SetThreadAttrStackSize(PthreadAttr &attr, size_t size)
59 {
60     attr.stackSize = size;
61 }
62 
SetThreadAttrScope(PthreadAttr & attr,int32_t scope)63 void SetThreadAttrScope(PthreadAttr &attr, int32_t scope)
64 {
65     attr.scope = scope;
66 }
67 
CreateOneThread(PthreadData & tr,PthreadAttr * attr,PthreadRoutine func,void * param)68 int CreateOneThread(PthreadData &tr, PthreadAttr *attr, PthreadRoutine func, void *param)
69 {
70     pthread_attr_t pthreadAttr;
71 
72     int retCode = pthread_attr_init(&pthreadAttr);
73     if (retCode != 0) {
74         HILOGE("[AieThreadUnix]Failed to run pthread_attr_init, retCode[%d].", retCode);
75         return retCode;
76     }
77     if (attr != nullptr && attr->scope == THREAD_SCOPE_PROCESS) {
78         pthread_attr_setscope(&pthreadAttr, PTHREAD_SCOPE_PROCESS);
79     } else {
80         pthread_attr_setscope(&pthreadAttr, PTHREAD_SCOPE_SYSTEM);
81     }
82 
83     if (attr != nullptr && attr->stackSize > 0) {
84         pthread_attr_setstacksize(&pthreadAttr, attr->stackSize);
85     }
86 
87     pthread_attr_setdetachstate(&pthreadAttr, PTHREAD_CREATE_JOINABLE);
88     auto *pthreadHandleT = reinterpret_cast<PthreadHandle *>(reinterpret_cast<void *>(&tr));
89     retCode = pthread_create(&(pthreadHandleT->handle), &pthreadAttr, func, param);
90     pthread_attr_destroy(&pthreadAttr);
91     return retCode;
92 }
93 
WaitThread(PthreadData & tr)94 int WaitThread(PthreadData &tr)
95 {
96     auto *pthreadHandle = reinterpret_cast<PthreadHandle *>(reinterpret_cast<void *>(&tr));
97     if (pthreadHandle->handle == 0) {
98         return RETCODE_SUCCESS;
99     }
100 
101     pthread_join(pthreadHandle->handle, nullptr);
102     pthreadHandle->handle = 0;
103     return RETCODE_SUCCESS;
104 }
105