1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 */
4
5 #include "k_api.h"
6
pend_list_add(klist_t * head,ktask_t * task)7 RHINO_INLINE void pend_list_add(klist_t *head, ktask_t *task)
8 {
9 klist_t *tmp;
10 klist_t *list_start = head;
11 klist_t *list_end = head;
12
13 for (tmp = list_start->next; tmp != list_end; tmp = tmp->next) {
14 if (krhino_list_entry(tmp, ktask_t, task_list)->prio > task->prio) {
15 break;
16 }
17 }
18
19 klist_insert(tmp, &task->task_list);
20 }
21
pend_task_wakeup(ktask_t * task)22 void pend_task_wakeup(ktask_t *task)
23 {
24 /* wake up task depend on the different state of task */
25 switch (task->task_state) {
26 case K_PEND:
27 /* remove task on the block list because task is waken up */
28 klist_rm(&task->task_list);
29 /* add to the ready list again */
30 ready_list_add(&g_ready_queue, task);
31 task->task_state = K_RDY;
32 break;
33 case K_PEND_SUSPENDED:
34 /* remove task on the block list because task is waken up */
35 klist_rm(&task->task_list);
36 task->task_state = K_SUSPENDED;
37 break;
38 default:
39 k_err_proc(RHINO_SYS_FATAL_ERR);
40 break;
41 }
42
43 /* remove task on the tick list because task is waken up */
44 tick_list_rm(task);
45
46 task->blk_state = BLK_FINISH;
47 task->blk_obj = NULL;
48 }
49
pend_to_blk_obj(blk_obj_t * blk_obj,ktask_t * task,tick_t timeout)50 void pend_to_blk_obj(blk_obj_t *blk_obj, ktask_t *task, tick_t timeout)
51 {
52 /* task need to remember which object is blocked on */
53 task->blk_obj = blk_obj;
54
55 if (timeout != RHINO_WAIT_FOREVER) {
56 tick_list_insert(task, timeout);
57 }
58
59 task->task_state = K_PEND;
60
61 /* remove from the ready list */
62 ready_list_rm(&g_ready_queue, task);
63
64 if (blk_obj->blk_policy == BLK_POLICY_FIFO) {
65 /* add to the end of blocked objet list */
66 klist_insert(&blk_obj->blk_list, &task->task_list);
67 } else {
68 /* add to the prio sorted block list */
69 pend_list_add(&blk_obj->blk_list, task);
70 }
71 }
72
pend_task_rm(ktask_t * task)73 void pend_task_rm(ktask_t *task)
74 {
75 switch (task->task_state) {
76 case K_PEND:
77 /* remove task on the block list because task is waken up */
78 klist_rm(&task->task_list);
79 /*add to the ready list again*/
80 ready_list_add(&g_ready_queue, task);
81 task->task_state = K_RDY;
82 break;
83 case K_PEND_SUSPENDED:
84 /* remove task on the block list because task is waken up */
85 klist_rm(&task->task_list);
86 task->task_state = K_SUSPENDED;
87 break;
88 default:
89 k_err_proc(RHINO_SYS_FATAL_ERR);
90 break;
91 }
92
93 /* remove task on the tick list because task is waken up */
94 tick_list_rm(task);
95 task->blk_state = BLK_DEL;
96
97 /* task is nothing blocked on so reset it to NULL */
98 task->blk_obj = NULL;
99 }
100
pend_list_reorder(ktask_t * task)101 void pend_list_reorder(ktask_t *task)
102 {
103 if (task->blk_obj->blk_policy == BLK_POLICY_PRI) {
104 /* remove it first and add it again in prio sorted list */
105 klist_rm(&task->task_list);
106 pend_list_add(&task->blk_obj->blk_list, task);
107 }
108 }
109
pend_state_end_proc(ktask_t * task,blk_obj_t * blk_obj)110 kstat_t pend_state_end_proc(ktask_t *task, blk_obj_t *blk_obj)
111 {
112 kstat_t status;
113
114 (void)blk_obj;
115
116 switch (task->blk_state) {
117 case BLK_FINISH:
118 status = RHINO_SUCCESS;
119 break;
120 case BLK_ABORT:
121 status = RHINO_BLK_ABORT;
122 break;
123 case BLK_TIMEOUT:
124 status = RHINO_BLK_TIMEOUT;
125 break;
126 case BLK_DEL:
127 status = RHINO_BLK_DEL;
128 break;
129 default:
130 k_err_proc(RHINO_BLK_INV_STATE);
131 status = RHINO_BLK_INV_STATE;
132 break;
133 }
134
135 #if (RHINO_CONFIG_TASK_DEL > 0)
136 if (blk_obj == NULL) {
137 if (task->cancel == 1u) {
138 status = RHINO_TASK_CANCELED;
139 }
140 return status;
141 }
142
143 if ((task->cancel == 1u) && (blk_obj->cancel == 1u)) {
144 status = RHINO_TASK_CANCELED;
145 }
146 #endif
147
148 return status;
149 }
150
151