• 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_task_thread.h"
17 #include "hal_error.h"
18 #include "hc_log.h"
19 
20 #define TASK_ALLOC_UINT 5
21 
IMPLEMENT_HC_VECTOR(TaskVec,HcTaskWrap,TASK_ALLOC_UINT)22 IMPLEMENT_HC_VECTOR(TaskVec, HcTaskWrap, TASK_ALLOC_UINT)
23 
24 static HcTaskBase* PopTask(HcTaskThread* thread)
25 {
26     if (thread == NULL) {
27         return NULL;
28     }
29 
30     thread->queueLock.lock(&thread->queueLock);
31     HcTaskWrap task;
32     HcBool ret = thread->tasks.popFront(&thread->tasks, &task);
33     thread->queueLock.unlock(&thread->queueLock);
34     if (ret) {
35         return task.task;
36     }
37     return NULL;
38 }
39 
PushTask(struct HcTaskThreadT * thread,HcTaskBase * task)40 static void PushTask(struct HcTaskThreadT* thread, HcTaskBase* task)
41 {
42     if (thread == NULL || task == NULL) {
43         return;
44     }
45 
46     thread->queueLock.lock(&thread->queueLock);
47     HcTaskWrap taskWarp;
48     taskWarp.task = task;
49     thread->tasks.pushBack(&thread->tasks, &taskWarp);
50     thread->thread.notify(&thread->thread);
51     thread->queueLock.unlock(&thread->queueLock);
52 }
53 
Clear(struct HcTaskThreadT * thread)54 static void Clear(struct HcTaskThreadT* thread)
55 {
56     thread->queueLock.lock(&thread->queueLock);
57     HcTaskWrap *taskWarp = NULL;
58     uint32_t index;
59     FOR_EACH_HC_VECTOR(thread->tasks, index, taskWarp) {
60         if (taskWarp->task->destroy) {
61             taskWarp->task->destroy(taskWarp->task);
62         }
63         HcFree(taskWarp->task);
64     }
65     thread->tasks.clear(&thread->tasks);
66     thread->queueLock.unlock(&thread->queueLock);
67 }
68 
StopAndClear(struct HcTaskThreadT * thread)69 static void StopAndClear(struct HcTaskThreadT* thread)
70 {
71     if (thread == NULL) {
72         return;
73     }
74     thread->clear(thread);
75     thread->quit = HC_TRUE;
76     thread->thread.notify(&thread->thread);
77     thread->thread.join(&thread->thread);
78 }
79 
StartTaskThread(struct HcTaskThreadT * thread)80 static int32_t StartTaskThread(struct HcTaskThreadT* thread)
81 {
82     if (thread == NULL) {
83         return HAL_ERR_BAD_ALLOC;
84     }
85 
86     thread->quit = HC_FALSE;
87     int32_t res = thread->thread.start(&thread->thread);
88     if (res != HAL_SUCCESS) {
89         LOGE("Start thread failed, res:%d", res);
90     }
91     return res;
92 }
93 
TaskThreadLoop(void * args)94 static int TaskThreadLoop(void* args)
95 {
96     HcTaskThread* thread = (HcTaskThread*)args;
97     if (thread == NULL) {
98         return -1;
99     }
100 
101     while (1) {
102         if (thread->quit) {
103             break;
104         }
105         HcTaskBase* task = PopTask(thread);
106         if (task != NULL) {
107             if (task->doAction) {
108                 task->doAction(task);
109             }
110             if (task->destroy) {
111                 task->destroy(task);
112             }
113             HcFree(task);
114         } else {
115             thread->thread.wait(&thread->thread);
116         }
117     }
118     return 0;
119 }
120 
InitHcTaskThread(HcTaskThread * thread,size_t stackSize,const char * threadName)121 int32_t InitHcTaskThread(HcTaskThread* thread, size_t stackSize, const char* threadName)
122 {
123     if (thread == NULL) {
124         return -1;
125     }
126 
127     thread->pushTask = PushTask;
128     thread->startThread = StartTaskThread;
129     thread->clear = Clear;
130     thread->stopAndClear = StopAndClear;
131     int32_t res = InitThread(&thread->thread, TaskThreadLoop, stackSize, threadName);
132     if (res != 0) {
133         return res;
134     }
135     res = InitHcMutex(&thread->queueLock);
136     if (res != 0) {
137         DestroyThread(&thread->thread);
138         return res;
139     }
140     thread->tasks = CREATE_HC_VECTOR(TaskVec);
141     return 0;
142 }
143 
DestroyHcTaskThread(HcTaskThread * thread)144 void DestroyHcTaskThread(HcTaskThread* thread)
145 {
146     DESTROY_HC_VECTOR(TaskVec, &thread->tasks);
147     DestroyHcMutex(&thread->queueLock);
148     DestroyThread(&thread->thread);
149 }