• 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 
18 #define MAX_THREAD_STACK_SIZE (8 * 1024 * 1024)
19 
StaticThreadFunc(void * args)20 void *StaticThreadFunc(void *args)
21 {
22     HcThread *thread = (HcThread*)args;
23     if (thread == NULL) {
24         return NULL;
25     }
26 
27     (void)pthread_setname_np(pthread_self(), StringGet(&thread->name));
28 
29     if (thread->threadFunc) {
30         thread->threadFunc(args);
31     }
32     thread->threadLock.lock(&thread->threadLock);
33     thread->running = HC_FALSE;
34     thread->threadWaitObj.notifyWithoutLock(&thread->threadWaitObj);
35     thread->threadLock.unlock(&thread->threadLock);
36     return NULL;
37 }
38 
Start(struct HcThreadT * thread)39 int Start(struct HcThreadT *thread)
40 {
41     if (thread == NULL) {
42         return -1;
43     }
44     thread->threadLock.lock(&thread->threadLock);
45     if (thread->running) {
46         thread->threadLock.unlock(&thread->threadLock);
47         return 0;
48     }
49     thread->running = HC_TRUE;
50 
51     pthread_attr_t attr;
52     pthread_attr_init(&attr);
53     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
54 
55     if (thread->stackSize > 0 && thread->stackSize <= MAX_THREAD_STACK_SIZE) {
56         pthread_attr_setstacksize(&attr, thread->stackSize);
57     }
58 
59     int result = pthread_create(&thread->thread, &attr, StaticThreadFunc, thread);
60     pthread_attr_destroy(&attr);
61     if (result != 0) {
62         thread->running = HC_FALSE;
63     }
64     thread->threadLock.unlock(&thread->threadLock);
65     return result;
66 }
67 
Join(struct HcThreadT * thread)68 void Join(struct HcThreadT *thread)
69 {
70     if (thread == NULL) {
71         return;
72     }
73 
74     if (thread->running) {
75         thread->threadWaitObj.waitWithoutLock(&thread->threadWaitObj);
76     }
77     void *status = NULL;
78     pthread_join(thread->thread, &status);
79 }
80 
BizWait(struct HcThreadT * thread)81 void BizWait(struct HcThreadT *thread)
82 {
83     if (thread == NULL) {
84         return;
85     }
86     thread->bizWaitObj.wait(&thread->bizWaitObj);
87 }
88 
BizNotify(struct HcThreadT * thread)89 void BizNotify(struct HcThreadT *thread)
90 {
91     if (thread == NULL) {
92         return;
93     }
94     thread->bizWaitObj.notify(&thread->bizWaitObj);
95 }
96 
InitThread(HcThread * thread,ThreadFunc func,size_t stackSize,const char * threadName)97 int32_t InitThread(HcThread *thread, ThreadFunc func, size_t stackSize, const char *threadName)
98 {
99     if (thread == NULL) {
100         return -1;
101     }
102 
103     thread->threadFunc = func;
104     thread->start = Start;
105     thread->wait = BizWait;
106     thread->notify = BizNotify;
107     thread->join = Join;
108     thread->stackSize = stackSize;
109     thread->running = HC_FALSE;
110     thread->name = CreateString();
111     if (StringSetPointer(&thread->name, threadName) != HC_TRUE) {
112         return -1;
113     }
114 
115     int32_t res = InitHcMutex(&thread->threadLock);
116     if (res != 0) {
117         DeleteString(&thread->name);
118         return res;
119     }
120     res = InitHcCond(&thread->threadWaitObj, &thread->threadLock);
121     if (res != 0) {
122         DeleteString(&thread->name);
123         DestroyHcMutex(&thread->threadLock);
124         return res;
125     }
126     res = InitHcCond(&thread->bizWaitObj, NULL);
127     if (res != 0) {
128         DeleteString(&thread->name);
129         DestroyHcMutex(&thread->threadLock);
130         DestroyHcCond(&thread->threadWaitObj);
131     }
132     return res;
133 }
134 
DestroyThread(HcThread * thread)135 void DestroyThread(HcThread *thread)
136 {
137     if (thread == NULL) {
138         return;
139     }
140 
141     DestroyHcCond(&thread->bizWaitObj);
142     DestroyHcCond(&thread->threadWaitObj);
143     DestroyHcMutex(&thread->threadLock);
144     DeleteString(&thread->name);
145 }
146