1 /*
2 * Copyright (C) 2021-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 "hc_thread.h"
17 #include "hal_error.h"
18 #include "hc_log.h"
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 #define MAX_THREAD_STACK_SIZE (8 * 1024 * 1024)
25
StaticThreadFunc(void * args)26 void *StaticThreadFunc(void *args)
27 {
28 HcThread* thread = (HcThread*)args;
29 if (thread == NULL) {
30 return NULL;
31 }
32
33 int res = pthread_setname_np(pthread_self(), StringGet(&thread->name));
34 if (res != 0) {
35 LOGW("[OS]: pthread_setname_np fail. [Res]: %d", res);
36 } else {
37 LOGI("[OS]: pthread_setname_np success. [StackSize]: %zu, [Name]: %s",
38 thread->stackSize, StringGet(&thread->name));
39 }
40
41 if (thread->threadFunc) {
42 thread->threadFunc(args);
43 }
44 thread->threadLock.lock(&thread->threadLock);
45 thread->running = HC_FALSE;
46 thread->threadWaitObj.notifyWithoutLock(&thread->threadWaitObj);
47 thread->threadLock.unlock(&thread->threadLock);
48 return NULL;
49 }
50
Start(struct HcThreadT * thread)51 int Start(struct HcThreadT *thread)
52 {
53 if (thread == NULL) {
54 return HAL_ERR_NULL_PTR;
55 }
56 thread->threadLock.lock(&thread->threadLock);
57 if (thread->running) {
58 thread->threadLock.unlock(&thread->threadLock);
59 return 0;
60 }
61 thread->running = HC_TRUE;
62
63 pthread_attr_t attr;
64 pthread_attr_init(&attr);
65 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
66
67 if (thread->stackSize > 0 && thread->stackSize <= MAX_THREAD_STACK_SIZE) {
68 pthread_attr_setstacksize(&attr, thread->stackSize);
69 }
70
71 LOGI("[OS]: pthread_create enter.");
72 int res = pthread_create(&thread->thread, &attr, StaticThreadFunc, thread);
73 LOGI("[OS]: pthread_create quit. [Res]: %d", res);
74 pthread_attr_destroy(&attr);
75 if (res != 0) {
76 LOGE("[OS]: pthread_create fail. [Res]: %d", res);
77 thread->running = HC_FALSE;
78 }
79 thread->threadLock.unlock(&thread->threadLock);
80 return res;
81 }
82
Join(struct HcThreadT * thread)83 void Join(struct HcThreadT *thread)
84 {
85 if (thread == NULL) {
86 return;
87 }
88 thread->threadLock.lock(&thread->threadLock);
89 if (thread->running) {
90 thread->threadWaitObj.waitWithoutLock(&thread->threadWaitObj);
91 }
92 thread->threadLock.unlock(&thread->threadLock);
93 }
94
BizWait(struct HcThreadT * thread)95 void BizWait(struct HcThreadT *thread)
96 {
97 if (thread == NULL) {
98 return;
99 }
100 thread->bizWaitObj.wait(&thread->bizWaitObj);
101 }
102
BizNotify(struct HcThreadT * thread)103 void BizNotify(struct HcThreadT *thread)
104 {
105 if (thread == NULL) {
106 return;
107 }
108 thread->bizWaitObj.notify(&thread->bizWaitObj);
109 }
110
InitThread(HcThread * thread,ThreadFunc func,size_t stackSize,const char * threadName)111 int32_t InitThread(HcThread *thread, ThreadFunc func, size_t stackSize, const char *threadName)
112 {
113 if (thread == NULL) {
114 return -1;
115 }
116
117 thread->threadFunc = func;
118 thread->start = Start;
119 thread->wait = BizWait;
120 thread->notify = BizNotify;
121 thread->join = Join;
122 thread->stackSize = stackSize;
123 thread->running = HC_FALSE;
124 thread->name = CreateString();
125 if (StringSetPointer(&thread->name, threadName) != HC_TRUE) {
126 return -1;
127 }
128
129 int32_t res = InitHcMutex(&thread->threadLock);
130 if (res != 0) {
131 DeleteString(&thread->name);
132 return res;
133 }
134 res = InitHcCond(&thread->threadWaitObj, &thread->threadLock);
135 if (res != 0) {
136 DeleteString(&thread->name);
137 DestroyHcMutex(&thread->threadLock);
138 return res;
139 }
140 res = InitHcCond(&thread->bizWaitObj, NULL);
141 if (res != 0) {
142 DeleteString(&thread->name);
143 DestroyHcMutex(&thread->threadLock);
144 DestroyHcCond(&thread->threadWaitObj);
145 }
146 return res;
147 }
148
DestroyThread(HcThread * thread)149 void DestroyThread(HcThread *thread)
150 {
151 if (thread == NULL) {
152 return;
153 }
154
155 DestroyHcCond(&thread->bizWaitObj);
156 DestroyHcCond(&thread->threadWaitObj);
157 DestroyHcMutex(&thread->threadLock);
158 DeleteString(&thread->name);
159 }
160
161 #ifdef __cplusplus
162 }
163 #endif