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