1 /*
2  * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3  */
4 
5 #include <stdio.h>
6 #include <time.h>
7 
8 #include <k_api.h>
9 #include <aos/errno.h>
10 #include <aos/kernel.h>
11 
12 #include "rhino_p.h"
13 
14 #if (RHINO_CONFIG_KOBJ_DYN_ALLOC == 0)
15 #warning "RHINO_CONFIG_KOBJ_DYN_ALLOC is disabled!"
16 #endif
17 
18 static unsigned int used_bitmap;
19 
20 #if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
21 
aos_task_new(const char * name,void (* fn)(void *),void * arg,size_t stack_size)22 aos_status_t aos_task_new(const char *name, void (*fn)(void *), void *arg, size_t stack_size)
23 {
24     int ret;
25 
26     ktask_t *task_handle = NULL;
27 
28 #if (RHINO_CONFIG_SCHED_CFS > 0)
29     ret = (int)krhino_cfs_task_dyn_create(&task_handle, name, arg, AOS_DEFAULT_APP_PRI,
30                                           stack_size / sizeof(cpu_stack_t), fn, 1u);
31 #else
32     ret = (int)krhino_task_dyn_create(&task_handle, name, arg, AOS_DEFAULT_APP_PRI,
33                                       0, stack_size / sizeof(cpu_stack_t), fn, 1u);
34 #endif
35 
36     return rhino2stderrno(ret);
37 }
38 
aos_task_new_ext(aos_task_t * task,const char * name,void (* fn)(void *),void * arg,size_t stack_size,int32_t prio)39 aos_status_t aos_task_new_ext(aos_task_t *task, const char *name, void (*fn)(void *),
40                      void *arg, size_t stack_size, int32_t prio)
41 {
42     int ret;
43     if  (task == NULL) {
44         return -EINVAL;
45     }
46 #if (RHINO_CONFIG_SCHED_CFS > 0)
47     ret = (int)krhino_cfs_task_dyn_create((ktask_t **)task, name, arg, AOS_DEFAULT_APP_PRI,
48                                           stack_size / sizeof(cpu_stack_t), fn, 1u);
49 #else
50     ret = (int)krhino_task_dyn_create((ktask_t **)task, name, arg, prio,
51                                       0, stack_size / sizeof(cpu_stack_t), fn, 1u);
52 #endif
53     return rhino2stderrno(ret);
54 }
55 
aos_task_create(aos_task_t * task,const char * name,void (* fn)(void *),void * arg,void * stack,size_t stack_size,int32_t prio,uint32_t options)56 aos_status_t aos_task_create(aos_task_t *task, const char *name, void (*fn)(void *),
57                      void *arg, void *stack, size_t stack_size, int32_t prio, uint32_t options)
58 {
59     int       ret;
60     cpu_stack_t  *task_stack = NULL;
61     ktask_t      *task_obj;
62 
63     if (task == NULL) {
64         return -EINVAL;
65     }
66 
67     if (stack == NULL) {
68         task_stack = aos_malloc(stack_size * sizeof(cpu_stack_t));
69         if (task_stack == NULL) {
70             return -ENOMEM;
71         }
72         stack = task_stack;
73     }
74 
75     task_obj = aos_malloc(sizeof(ktask_t));
76     if (task_obj == NULL) {
77         aos_free(task_stack);
78         return -ENOMEM;
79     }
80 
81     *task = task_obj;
82 #if (RHINO_CONFIG_SCHED_CFS > 0)
83     ret = (int)krhino_cfs_task_create(task_obj, name, arg, prio, (cpu_stack_t *)stack,
84                                       stack_size / sizeof(cpu_stack_t), fn, options & AOS_TASK_AUTORUN);
85 #else
86     ret = (int)krhino_task_create(task_obj, name, arg, prio, 0, (cpu_stack_t *)stack,
87                                   stack_size / sizeof(cpu_stack_t), fn, options & AOS_TASK_AUTORUN);
88 #endif
89     if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) {
90         aos_free(task_stack);
91         aos_free(task_obj);
92         *task = NULL;
93     }
94 
95     return rhino2stderrno(ret);
96 }
97 
aos_task_exit(int32_t code)98 void aos_task_exit(int32_t code)
99 {
100     (void)code;
101 
102     krhino_task_dyn_del(NULL);
103 }
104 
aos_task_delete(aos_task_t * task)105 aos_status_t aos_task_delete(aos_task_t *task)
106 {
107     int ret;
108     ktask_t *ktask;
109 
110     CHECK_HANDLE(task);
111 
112     ktask = (ktask_t *)(*task);
113 
114     ret = (int)krhino_task_dyn_del(ktask);
115 
116     return rhino2stderrno(ret);
117 }
118 #endif /* RHINO_CONFIG_KOBJ_DYN_ALLOC */
119 
aos_task_resume(aos_task_t * task)120 aos_status_t aos_task_resume(aos_task_t *task)
121 {
122     int ret;
123     ktask_t *ktask;
124 
125     CHECK_HANDLE(task);
126 
127     ktask = (ktask_t *)(*task);
128     ret = krhino_task_resume(ktask);
129 
130     return rhino2stderrno(ret);
131 }
132 
aos_task_suspend(aos_task_t * task)133 aos_status_t aos_task_suspend(aos_task_t *task)
134 {
135     int ret;
136     ktask_t *ktask;
137 
138     CHECK_HANDLE(task);
139     ktask = (ktask_t *)(*task);
140     ret = krhino_task_suspend(ktask);
141 
142     return rhino2stderrno(ret);
143 }
144 
aos_task_yield()145 aos_status_t aos_task_yield()
146 {
147     int ret;
148     ret = krhino_task_yield();
149     return rhino2stderrno(ret);
150 }
151 
aos_task_self()152 aos_task_t aos_task_self()
153 {
154     return (aos_task_t)krhino_cur_task_get();
155 
156 }
157 
aos_task_name_get(aos_task_t * task,char * buf,size_t buf_size)158 aos_status_t aos_task_name_get(aos_task_t *task, char *buf, size_t buf_size)
159 {
160     const char *name;
161     int str_len, copy_len;
162 
163     CHECK_HANDLE(task);
164 
165     if (buf == NULL || buf_size == 0) {
166         return -EINVAL;
167     }
168 
169     name = ((ktask_t *)*task)->task_name;
170 
171     str_len = strlen(name);
172 
173     copy_len = (str_len > (buf_size - 1)) ? buf_size - 1 : str_len;
174     memcpy(buf, name, copy_len);
175     return 0;
176 
177 }
178 
aos_task_key_create(aos_task_key_t * key)179 aos_status_t aos_task_key_create(aos_task_key_t *key)
180 {
181     int i;
182     if (key == NULL) {
183         return -EINVAL;
184     }
185     for (i = RHINO_CONFIG_TASK_INFO_NUM - 1; i >= 0; i--) {
186         if (!((1 << i) & used_bitmap)) {
187             used_bitmap |= 1 << i;
188             *key = i;
189 
190             return 0;
191         }
192     }
193 
194     return -EINVAL;
195 }
196 
aos_task_key_delete(aos_task_key_t key)197 void aos_task_key_delete(aos_task_key_t key)
198 {
199     if (key >= RHINO_CONFIG_TASK_INFO_NUM) {
200         return;
201     }
202 
203     used_bitmap &= ~(1 << key);
204 }
205 
206 #if (RHINO_CONFIG_TASK_INFO > 0)
aos_task_setspecific(aos_task_key_t key,void * vp)207 aos_status_t aos_task_setspecific(aos_task_key_t key, void *vp)
208 {
209     int ret;
210     ret = krhino_task_info_set(krhino_cur_task_get(), key, vp);
211     return rhino2stderrno(ret);
212 }
213 
aos_task_getspecific(aos_task_key_t key)214 void *aos_task_getspecific(aos_task_key_t key)
215 {
216     void *vp = NULL;
217 
218     krhino_task_info_get(krhino_cur_task_get(), key, &vp);
219 
220     return vp;
221 }
222 
aos_msleep(uint32_t ms)223 void aos_msleep(uint32_t ms)
224 {
225     krhino_task_sleep(MS2TICK(ms));
226 }
227 
aos_sched_get_priority_max(uint32_t policy)228 uint32_t aos_sched_get_priority_max(uint32_t policy)
229 {
230     return RHINO_CONFIG_PRI_MAX;
231 }
232 
aos_task_ptcb_get(aos_task_t * task,void ** ptcb)233 aos_status_t aos_task_ptcb_get(aos_task_t *task, void **ptcb)
234 {
235     CPSR_ALLOC();
236     CHECK_HANDLE(task);
237     if (ptcb == NULL) {
238         return -EINVAL;
239     }
240 
241     RHINO_CRITICAL_ENTER();
242     *(ptcb) = ((ktask_t *)*task)->ptcb;
243     RHINO_CRITICAL_EXIT();
244 
245     return 0;
246 }
247 
aos_task_ptcb_set(aos_task_t * task,void * ptcb)248 aos_status_t aos_task_ptcb_set(aos_task_t *task, void *ptcb)
249 {
250     CPSR_ALLOC();
251     CHECK_HANDLE(task);
252 
253     RHINO_CRITICAL_ENTER();
254     ((ktask_t *)*task)->ptcb = ptcb;
255     RHINO_CRITICAL_EXIT();
256 
257     return 0;
258 }
259 
aos_task_pri_change(aos_task_t * task,uint8_t pri,uint8_t * old_pri)260 aos_status_t aos_task_pri_change(aos_task_t *task, uint8_t pri, uint8_t *old_pri)
261 {
262     kstat_t ret;
263 
264     CHECK_HANDLE(task);
265 
266     ret = krhino_task_pri_change((ktask_t *)*task, pri, old_pri);
267 
268     return rhino2stderrno(ret);
269 }
270 
aos_task_pri_get(aos_task_t * task,uint8_t * priority)271 aos_status_t aos_task_pri_get(aos_task_t *task, uint8_t *priority)
272 {
273     CPSR_ALLOC();
274     CHECK_HANDLE(task);
275     if (priority == NULL) {
276         return -EINVAL;
277     }
278 
279     RHINO_CRITICAL_ENTER();
280     *priority = ((ktask_t *)*task)->b_prio;
281     RHINO_CRITICAL_EXIT();
282 
283     return 0;
284 }
285 
aos_task_sched_policy_set(aos_task_t * task,uint8_t policy,uint8_t pri)286 aos_status_t aos_task_sched_policy_set(aos_task_t *task, uint8_t policy, uint8_t pri)
287 {
288     kstat_t ret;
289 
290     CHECK_HANDLE(task);
291 
292     if (policy != KSCHED_FIFO && policy != KSCHED_RR && policy != KSCHED_CFS) {
293         return -EINVAL;
294     }
295 
296     ret = krhino_sched_param_set((ktask_t *)*task, policy, pri);
297     return rhino2stderrno(ret);
298 }
299 
aos_task_sched_policy_get(aos_task_t * task,uint8_t * policy)300 aos_status_t aos_task_sched_policy_get(aos_task_t *task, uint8_t *policy)
301 {
302     kstat_t ret = 0;
303 
304     CHECK_HANDLE(task);
305     if (policy == NULL) {
306         return -EINVAL;
307     }
308 
309     ret = krhino_sched_policy_get((ktask_t *)*task, policy);
310     return rhino2stderrno(ret);
311 }
312 
aos_task_sched_policy_get_default()313 uint32_t aos_task_sched_policy_get_default()
314 {
315 #if (RHINO_CONFIG_SCHED_CFS > 0)
316     return KSCHED_CFS;
317 #else
318     return KSCHED_RR;
319 #endif
320 }
321 
aos_task_time_slice_set(aos_task_t * task,uint32_t slice)322 aos_status_t aos_task_time_slice_set(aos_task_t *task, uint32_t slice)
323 {
324     kstat_t ret;
325     CHECK_HANDLE(task);
326 
327     ret = krhino_task_time_slice_set((ktask_t *)*task, MS2TICK(slice));
328     return rhino2stderrno(ret);
329 }
330 
aos_task_time_slice_get(aos_task_t * task,uint32_t * slice)331 aos_status_t aos_task_time_slice_get(aos_task_t *task, uint32_t *slice)
332 {
333     uint32_t time_slice;
334     CPSR_ALLOC();
335     CHECK_HANDLE(task);
336     if (slice == NULL) {
337         return -EINVAL;
338     }
339 
340     RHINO_CRITICAL_ENTER();
341     time_slice = ((ktask_t *)*task)->time_slice;
342     RHINO_CRITICAL_EXIT();
343     *slice = (uint32_t)krhino_ticks_to_ms(time_slice);
344 
345     return 0;
346 }
347 
348 #endif
349 
350