• 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 #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