• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define MAX_THREAD_STACK_SIZE (8 * 1024 * 1024)
21 
StaticThreadFunc(void * args)22 void *StaticThreadFunc(void *args)
23 {
24     if (args == NULL) {
25         return NULL;
26     }
27     HcThread *thread = (HcThread*)args;
28     if (thread == NULL) {
29         return NULL;
30     }
31 
32 #if defined(SET_THREAD_NAME)
33     int res = pthread_setname_np(pthread_self(), StringGet(&thread->name));
34     if (res != 0) {
35         LOGW("[OS]: pthread_setname_np fail. [Res]: %" LOG_PUB "d", res);
36     }
37 #endif
38 
39     if (thread->threadFunc) {
40         thread->threadFunc(args);
41     }
42     (void)LockHcMutex(&thread->threadLock);
43     thread->running = HC_FALSE;
44     thread->threadWaitObj.notifyWithoutLock(&thread->threadWaitObj);
45     UnlockHcMutex(&thread->threadLock);
46     return NULL;
47 }
48 
Start(struct HcThreadT * thread)49 int Start(struct HcThreadT *thread)
50 {
51     if (thread == NULL) {
52         return HAL_ERR_NULL_PTR;
53     }
54     (void)LockHcMutex(&thread->threadLock);
55     if (thread->running) {
56         UnlockHcMutex(&thread->threadLock);
57         return 0;
58     }
59     thread->running = HC_TRUE;
60 
61     pthread_attr_t attr;
62     pthread_attr_init(&attr);
63     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
64 
65     if (thread->stackSize > 0 && thread->stackSize <= MAX_THREAD_STACK_SIZE) {
66         pthread_attr_setstacksize(&attr, thread->stackSize);
67     }
68 
69     LOGI("[OS]: pthread_create enter.");
70     int res = pthread_create(&thread->thread, &attr, StaticThreadFunc, thread);
71     LOGI("[OS]: pthread_create quit. [Res]: %" LOG_PUB "d", res);
72     pthread_attr_destroy(&attr);
73     if (res != 0) {
74         LOGE("[OS]: pthread_create fail. [Res]: %" LOG_PUB "d", res);
75         thread->running = HC_FALSE;
76     }
77     UnlockHcMutex(&thread->threadLock);
78     return res;
79 }
80 
Join(struct HcThreadT * thread)81 void Join(struct HcThreadT *thread)
82 {
83     if (thread == NULL) {
84         return;
85     }
86 
87     if (thread->running) {
88         thread->threadWaitObj.waitWithoutLock(&thread->threadWaitObj);
89     }
90     void *status = NULL;
91     LOGI("[OS]: pthread_join enter.");
92     int res = pthread_join(thread->thread, &status);
93     LOGI("[OS]: pthread_join quit. [Res]: %" LOG_PUB "d", res);
94     if (res != 0) {
95         LOGE("[OS]: pthread_join fail. [Res]: %" LOG_PUB "d", res);
96     }
97 }
98 
BizWait(struct HcThreadT * thread)99 void BizWait(struct HcThreadT *thread)
100 {
101     if (thread == NULL) {
102         return;
103     }
104     thread->bizWaitObj.wait(&thread->bizWaitObj);
105 }
106 
BizNotify(struct HcThreadT * thread)107 void BizNotify(struct HcThreadT *thread)
108 {
109     if (thread == NULL) {
110         return;
111     }
112     thread->bizWaitObj.notify(&thread->bizWaitObj);
113 }
114 
InitThread(HcThread * thread,ThreadFunc func,size_t stackSize,const char * threadName)115 int32_t InitThread(HcThread *thread, ThreadFunc func, size_t stackSize, const char *threadName)
116 {
117     if (thread == NULL) {
118         return -1;
119     }
120 
121     thread->threadFunc = func;
122     thread->start = Start;
123     thread->wait = BizWait;
124     thread->notify = BizNotify;
125     thread->join = Join;
126     thread->stackSize = stackSize;
127     thread->running = HC_FALSE;
128     thread->name = CreateString();
129     if (StringSetPointer(&thread->name, threadName) != HC_TRUE) {
130         DeleteString(&thread->name);
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