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