1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 */
4
5 #ifndef K_INTERNAL_H
6 #define K_INTERNAL_H
7
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11
12 /** @addtogroup aos_rhino internal
13 * OS internal funtions
14 *
15 * @{
16 */
17
18 extern kstat_t g_sys_stat;
19 extern uint8_t g_idle_task_spawned[RHINO_CONFIG_CPU_NUM];
20
21 extern runqueue_t g_ready_queue;
22
23 /* System lock */
24 extern uint8_t g_sched_lock[RHINO_CONFIG_CPU_NUM];
25 extern uint8_t g_intrpt_nested_level[RHINO_CONFIG_CPU_NUM];
26
27 /* highest pri ready task object */
28 extern ktask_t *g_preferred_ready_task[RHINO_CONFIG_CPU_NUM];
29
30 /* current active task */
31 extern ktask_t *g_active_task[RHINO_CONFIG_CPU_NUM];
32
33 /* global task ID */
34 extern uint32_t g_task_id;
35
36 /* idle attribute */
37 extern ktask_t g_idle_task[RHINO_CONFIG_CPU_NUM];
38 extern idle_count_t g_idle_count[RHINO_CONFIG_CPU_NUM];
39 extern cpu_stack_t g_idle_task_stack[RHINO_CONFIG_CPU_NUM][RHINO_CONFIG_IDLE_TASK_STACK_SIZE];
40 extern per_cpu_t g_per_cpu[RHINO_CONFIG_CPU_NUM];
41
42
43 /* tick attribute */
44 extern tick_t g_tick_count;
45 extern klist_t g_tick_head;
46
47 #if (RHINO_CONFIG_KOBJ_LIST > 0)
48 extern kobj_list_t g_kobj_list;
49 #endif
50
51 #if (RHINO_CONFIG_TIMER > 0)
52 extern klist_t g_timer_head;
53 extern tick_t g_timer_count;
54 extern ktask_t g_timer_task;
55 extern cpu_stack_t g_timer_task_stack[RHINO_CONFIG_TIMER_TASK_STACK_SIZE];
56 extern kbuf_queue_t g_timer_queue;
57 extern k_timer_queue_cb timer_queue_cb[RHINO_CONFIG_TIMER_MSG_NUM];
58 #endif
59
60 #if (RHINO_CONFIG_SYS_STATS > 0)
61 extern hr_timer_t g_sched_disable_time_start;
62 extern hr_timer_t g_sched_disable_max_time;
63 extern hr_timer_t g_cur_sched_disable_max_time;
64 extern uint16_t g_intrpt_disable_times;
65 extern hr_timer_t g_intrpt_disable_time_start;
66 extern hr_timer_t g_intrpt_disable_max_time;
67 extern hr_timer_t g_cur_intrpt_disable_max_time;
68 extern ctx_switch_t g_sys_ctx_switch_times;
69 #endif
70
71 #if (RHINO_CONFIG_HW_COUNT > 0)
72 extern hr_timer_t g_sys_measure_waste;
73 #endif
74
75 #if (RHINO_CONFIG_CPU_USAGE_STATS > 0)
76 extern ktask_t g_cpu_usage_task;
77 extern cpu_stack_t g_cpu_task_stack[RHINO_CONFIG_CPU_USAGE_TASK_STACK];
78 extern idle_count_t g_idle_count_max;
79 extern uint32_t g_cpu_usage;
80 #endif
81
82 #if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
83 extern ksem_t g_res_sem;
84 extern klist_t g_res_list;
85 extern ktask_t g_dyn_task;
86 extern cpu_stack_t g_dyn_task_stack[RHINO_CONFIG_K_DYN_TASK_STACK];
87 #endif
88
89 #if (RHINO_CONFIG_WORKQUEUE > 0)
90 extern klist_t g_workqueue_list_head;
91 extern kmutex_t g_workqueue_mutex;
92 extern kworkqueue_t g_workqueue_default;
93 extern cpu_stack_t g_workqueue_stack[RHINO_CONFIG_WORKQUEUE_STACK_SIZE];
94 #endif
95
96 #if (RHINO_CONFIG_MM_TLF > 0)
97 extern k_mm_head *g_kmm_head;
98 #endif
99
100 #if (RHINO_CONFIG_CPU_NUM > 1)
101 extern kspinlock_t g_sys_lock;
102 extern klist_t g_task_del_head;
103 #endif
104
105 #define K_OBJ_STATIC_ALLOC 1u
106 #define K_OBJ_DYN_ALLOC 2u
107
108 #define NULL_PARA_CHK(para) \
109 do { \
110 if (para == NULL) { \
111 return RHINO_NULL_PTR; \
112 } \
113 } while (0)
114
115 #define INTRPT_NESTED_LEVEL_CHK() \
116 do { \
117 if (g_intrpt_nested_level[cpu_cur_get()] > 0u) { \
118 RHINO_CRITICAL_EXIT(); \
119 return RHINO_NOT_CALLED_BY_INTRPT; \
120 } \
121 } while (0)
122
123
is_task_exec(ktask_t * task)124 RHINO_INLINE uint8_t is_task_exec(ktask_t *task)
125 {
126 #if (RHINO_CONFIG_CPU_NUM > 1)
127 if (task->cur_exc > 0u) {
128 return RHINO_TRUE;
129 }
130 else {
131 return RHINO_FALSE;
132 }
133 #else
134 if (g_active_task[0] == task) {
135 return RHINO_TRUE;
136 }
137 else {
138 return RHINO_FALSE;
139 }
140 #endif
141 }
142
143 #define RT_MAX_PRI 99u
144 #define RT_MIN_PRI 0u
145
146 #if (RHINO_CONFIG_TASK_DEL > 0)
147 #define TASK_CANCEL_CHK(obj) \
148 do { \
149 if ((g_active_task[cur_cpu_num]->cancel == 1u) && (obj->blk_obj.cancel == 1u)) {\
150 RHINO_CRITICAL_EXIT(); \
151 return RHINO_TASK_CANCELED; \
152 } \
153 } while (0)
154 #else
155 #define TASK_CANCEL_CHK(obj)
156 #endif
157
158 #define RES_FREE_NUM 4
159
160 typedef struct
161 {
162 size_t cnt;
163 void *res[RES_FREE_NUM];
164 klist_t res_list;
165 } res_free_t;
166
167 ktask_t *preferred_cpu_ready_task_get(runqueue_t *rq, uint8_t cpu_num);
168 ktask_t *cfs_preferred_task_get(void);
169
170 void core_sched(void);
171 void runqueue_init(runqueue_t *rq);
172
173 void ready_list_add(runqueue_t *rq, ktask_t *task);
174 void ready_list_add_head(runqueue_t *rq, ktask_t *task);
175 void ready_list_add_tail(runqueue_t *rq, ktask_t *task);
176 void ready_list_rm(runqueue_t *rq, ktask_t *task);
177 void ready_list_head_to_tail(runqueue_t *rq, ktask_t *task);
178
179 void time_slice_update(void);
180 void timer_task_sched(void);
181
182 void pend_list_reorder(ktask_t *task);
183 void pend_task_wakeup(ktask_t *task);
184 void pend_to_blk_obj(blk_obj_t *blk_obj, ktask_t *task, tick_t timeout);
185 void pend_task_rm(ktask_t *task);
186
187 kstat_t pend_state_end_proc(ktask_t *task, blk_obj_t *blk_obj);
188
189 void idle_task(void *p_arg);
190 void idle_count_set(idle_count_t value);
191 idle_count_t idle_count_get(void);
192
193 void tick_list_init(void);
194 void tick_task_start(void);
195 void tick_list_rm(ktask_t *task);
196 void tick_list_insert(ktask_t *task, tick_t time);
197 void tick_list_update(tick_i_t ticks);
198
199 uint8_t mutex_pri_limit(ktask_t *tcb, uint8_t pri);
200 void mutex_task_pri_reset(ktask_t *tcb);
201 uint8_t mutex_pri_look(ktask_t *tcb, kmutex_t *mutex_rel);
202
203 kstat_t task_pri_change(ktask_t *task, uint8_t new_pri);
204
205 void ktimer_init(void);
206
207 void intrpt_disable_measure_start(void);
208 void intrpt_disable_measure_stop(void);
209 __attribute__((weak)) void dyn_mem_proc_task_start(void);
210 void cpu_usage_stats_start(void);
211
212 kstat_t ringbuf_init(k_ringbuf_t *p_ringbuf, void *buf, size_t len, size_t type,size_t block_size);
213 kstat_t ringbuf_reset(k_ringbuf_t *p_ringbuf);
214 kstat_t ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len);
215 kstat_t ringbuf_head_push(k_ringbuf_t *p_ringbuf, void *data, size_t len);
216 kstat_t ringbuf_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen);
217 uint8_t ringbuf_is_full(k_ringbuf_t *p_ringbuf);
218 uint8_t ringbuf_is_empty(k_ringbuf_t *p_ringbuf);
219 void workqueue_init(void);
220 void k_mm_init(void);
221
222 #if (RHINO_CONFIG_PWRMGMT > 0)
223 void cpu_pwr_down(void);
224 void cpu_pwr_up(void);
225 #endif
226
227 /** @} */
228 #ifdef __cplusplus
229 }
230 #endif
231
232 #endif /* K_INTERNAL_H */
233
234