xref: /OK3568_Linux_fs/external/mpp/mpp/hal/hal_task.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2015 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "hal_task"
18 
19 #include <string.h>
20 
21 #include "mpp_mem.h"
22 #include "mpp_list.h"
23 #include "mpp_lock.h"
24 #include "mpp_debug.h"
25 #include "mpp_common.h"
26 
27 #include "hal_task.h"
28 
29 typedef struct HalTaskImpl_t        HalTaskImpl;
30 typedef struct HalTaskGroupImpl_t   HalTaskGroupImpl;
31 
32 struct HalTaskImpl_t {
33     struct list_head    list;
34     HalTaskGroupImpl    *group;
35     RK_S32              index;
36     RK_S32              status;
37     void                *data;
38 };
39 
40 struct HalTaskGroupImpl_t {
41     RK_S32              stage_count;
42     RK_S32              task_count;
43 
44     spinlock_t          lock;
45 
46     RK_S32              size;
47     RK_S32              aligned_size;
48 
49     struct list_head    *list;
50     RK_U32              *count;
51     HalTaskImpl         *tasks;
52 };
53 
hal_task_group_init(HalTaskGroup * group,RK_S32 stage_cnt,RK_S32 task_cnt,RK_S32 task_size)54 MPP_RET hal_task_group_init(HalTaskGroup *group, RK_S32 stage_cnt, RK_S32 task_cnt, RK_S32 task_size)
55 {
56     if (NULL == group || stage_cnt < 0 || task_cnt < 0 || task_size < 0) {
57         mpp_err_f("found invalid input group %p stage %d task %d size %d\n",
58                   group, stage_cnt, task_cnt, task_size);
59         return MPP_ERR_UNKNOW;
60     }
61 
62     HalTaskGroupImpl *p = NULL;
63     RK_S32 aligned_size = MPP_ALIGN(task_size, sizeof(void *));
64 
65     do {
66         RK_U8 *buf = NULL;
67         RK_S32 i;
68 
69         p = mpp_calloc_size(HalTaskGroupImpl, sizeof(HalTaskGroupImpl) +
70                             (sizeof(HalTaskImpl) + aligned_size) * task_cnt +
71                             (sizeof(struct list_head)) * stage_cnt +
72                             (sizeof(RK_U32)) * stage_cnt);
73         if (NULL == p) {
74             mpp_err_f("malloc group failed\n");
75             break;
76         }
77 
78         p->stage_count = stage_cnt;
79         p->task_count = task_cnt;
80         p->size = task_size;
81         p->aligned_size = aligned_size;
82         p->list = (struct list_head *)((HalTaskImpl *)(p + 1));
83         p->count = (RK_U32 *)(p->list + stage_cnt);
84         p->tasks = (HalTaskImpl *)(p->count + stage_cnt);
85 
86         mpp_spinlock_init(&p->lock);
87 
88         for (i = 0; i < stage_cnt; i++)
89             INIT_LIST_HEAD(&p->list[i]);
90 
91         buf = (RK_U8 *)(p->tasks + task_cnt);
92 
93         for (i = 0; i < task_cnt; i++) {
94             HalTaskImpl *task = &p->tasks[i];
95 
96             INIT_LIST_HEAD(&task->list);
97             task->index  = i;
98             task->group  = p;
99             task->status = TASK_IDLE;
100             task->data   = buf + i * aligned_size;
101             list_add_tail(&task->list, &p->list[TASK_IDLE]);
102             p->count[TASK_IDLE]++;
103         }
104         *group = p;
105         return MPP_OK;
106     } while (0);
107 
108     MPP_FREE(p);
109 
110     *group = NULL;
111     return MPP_NOK;
112 }
113 
hal_task_group_deinit(HalTaskGroup group)114 MPP_RET hal_task_group_deinit(HalTaskGroup group)
115 {
116     MPP_FREE(group);
117     return MPP_OK;
118 }
119 
hal_task_get_hnd(HalTaskGroup group,RK_S32 status,HalTaskHnd * hnd)120 MPP_RET hal_task_get_hnd(HalTaskGroup group, RK_S32 status, HalTaskHnd *hnd)
121 {
122     if (NULL == group || status >= TASK_BUTT || NULL == hnd) {
123         mpp_err_f("found invaid input group %p status %d hnd %p\n", group, status, hnd);
124         return MPP_ERR_UNKNOW;
125     }
126 
127     *hnd = NULL;
128     HalTaskGroupImpl *p = (HalTaskGroupImpl *)group;
129     struct list_head *list = &p->list[status];
130 
131     mpp_spinlock_lock(&p->lock);
132     if (list_empty(list)) {
133         mpp_spinlock_unlock(&p->lock);
134         return MPP_NOK;
135     }
136 
137     HalTaskImpl *task = list_entry(list->next, HalTaskImpl, list);
138     mpp_assert(task->status == status);
139     *hnd = task;
140     mpp_spinlock_unlock(&p->lock);
141     return MPP_OK;
142 }
143 
hal_task_check_empty(HalTaskGroup group,RK_S32 status)144 MPP_RET hal_task_check_empty(HalTaskGroup group, RK_S32 status)
145 {
146     if (NULL == group || status >= TASK_BUTT) {
147         mpp_err_f("found invaid input group %p status %d \n", group, status);
148         return MPP_ERR_UNKNOW;
149     }
150 
151     HalTaskGroupImpl *p = (HalTaskGroupImpl *)group;
152     struct list_head *list = &p->list[status];
153     MPP_RET ret;
154 
155     mpp_spinlock_lock(&p->lock);
156     ret = list_empty(list) ? MPP_OK : MPP_NOK;
157     mpp_spinlock_unlock(&p->lock);
158 
159     return ret;
160 }
161 
hal_task_get_count(HalTaskGroup group,RK_S32 status)162 RK_S32 hal_task_get_count(HalTaskGroup group, RK_S32 status)
163 {
164     if (NULL == group || status >= TASK_BUTT) {
165         mpp_err_f("found invaid input group %p status %d\n", group, status);
166         return -1;
167     }
168 
169     HalTaskGroupImpl *p = (HalTaskGroupImpl *)group;
170     RK_S32 count;
171 
172     mpp_spinlock_lock(&p->lock);
173     count = p->count[status];
174     mpp_spinlock_unlock(&p->lock);
175 
176     return count;
177 }
178 
hal_task_hnd_set_status(HalTaskHnd hnd,RK_S32 status)179 MPP_RET hal_task_hnd_set_status(HalTaskHnd hnd, RK_S32 status)
180 {
181     if (NULL == hnd || status >= TASK_BUTT) {
182         mpp_err_f("found invaid input hnd %p status %d\n", hnd, status);
183         return MPP_ERR_UNKNOW;
184     }
185 
186     HalTaskImpl *impl = (HalTaskImpl *)hnd;
187     HalTaskGroupImpl *group = impl->group;
188 
189     mpp_assert(group);
190     mpp_assert(impl->index < group->task_count);
191 
192     mpp_spinlock_lock(&group->lock);
193     list_del_init(&impl->list);
194     list_add_tail(&impl->list, &group->list[status]);
195     group->count[impl->status]--;
196     group->count[status]++;
197     impl->status = status;
198     mpp_spinlock_unlock(&group->lock);
199 
200     return MPP_OK;
201 }
202 
hal_task_hnd_set_info(HalTaskHnd hnd,void * info)203 MPP_RET hal_task_hnd_set_info(HalTaskHnd hnd, void *info)
204 {
205     if (NULL == hnd || NULL == info) {
206         mpp_err_f("found invaid input hnd %p info %p\n", hnd, info);
207         return MPP_ERR_UNKNOW;
208     }
209 
210     HalTaskImpl *impl = (HalTaskImpl *)hnd;
211     HalTaskGroupImpl *group = impl->group;
212 
213     mpp_assert(impl->index < group->task_count);
214 
215     mpp_spinlock_lock(&group->lock);
216     memcpy(impl->data, info, group->size);
217     mpp_spinlock_unlock(&group->lock);
218 
219     return MPP_OK;
220 }
221 
hal_task_hnd_get_info(HalTaskHnd hnd,void * info)222 MPP_RET hal_task_hnd_get_info(HalTaskHnd hnd, void *info)
223 {
224     if (NULL == hnd || NULL == info) {
225         mpp_err_f("found invaid input hnd %p info %p\n", hnd, info);
226         return MPP_ERR_UNKNOW;
227     }
228 
229     HalTaskImpl *impl = (HalTaskImpl *)hnd;
230     HalTaskGroupImpl *group = impl->group;
231 
232     mpp_assert(impl->index < group->task_count);
233 
234     mpp_spinlock_lock(&group->lock);
235     memcpy(info, impl->data, group->size);
236     mpp_spinlock_unlock(&group->lock);
237 
238     return MPP_OK;
239 }
240 
hal_task_hnd_get_data(HalTaskHnd hnd)241 void *hal_task_hnd_get_data(HalTaskHnd hnd)
242 {
243     if (NULL == hnd) {
244         mpp_err_f("found invaid input hnd %p\n", hnd);
245         return NULL;
246     }
247 
248     HalTaskImpl *impl = (HalTaskImpl *)hnd;
249     HalTaskGroupImpl *group = impl->group;
250 
251     mpp_assert(impl->index < group->task_count);
252 
253     return impl->data;
254 }
255