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