1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 #include "k_api.h"
6 
tick_list_init(void)7 void tick_list_init(void)
8 {
9    klist_init(&g_tick_head);
10 }
11 
tick_list_pri_insert(klist_t * head,ktask_t * task)12 RHINO_INLINE void tick_list_pri_insert(klist_t *head, ktask_t *task)
13 {
14     tick_t   val;
15     klist_t *q;
16     klist_t *list_start;
17     klist_t *list_end;
18     ktask_t *task_iter_temp;
19 
20     list_start = head;
21     list_end   = head;
22 
23     val = task->tick_remain;
24 
25     for (q = list_start->next; q != list_end; q = q->next) {
26         task_iter_temp = krhino_list_entry(q, ktask_t, tick_list);
27         if ((task_iter_temp->tick_match - g_tick_count) > val) {
28             break;
29         }
30     }
31 
32     klist_insert(q, &task->tick_list);
33 }
34 
tick_list_insert(ktask_t * task,tick_t time)35 void tick_list_insert(ktask_t *task, tick_t time)
36 {
37     task->tick_match  = g_tick_count + time;
38     task->tick_remain = time;
39     tick_list_pri_insert(&g_tick_head, task);
40 }
41 
tick_list_rm(ktask_t * task)42 void tick_list_rm(ktask_t *task)
43 {
44     klist_rm_init(&task->tick_list);
45 }
46 
tick_list_update(tick_i_t ticks)47 void tick_list_update(tick_i_t ticks)
48 {
49     CPSR_ALLOC();
50     klist_t  *tick_head_ptr;
51     ktask_t  *p_tcb;
52     klist_t  *iter;
53     klist_t  *iter_temp;
54     tick_i_t  delta;
55 
56     RHINO_CRITICAL_ENTER();
57 
58     g_tick_count += ticks;
59 
60     tick_head_ptr = &g_tick_head;
61     iter          =  tick_head_ptr->next;
62 
63     while (iter != tick_head_ptr) {
64         /* search all the time list if possible */
65         iter_temp = iter->next;
66         p_tcb     = krhino_list_entry(iter, ktask_t, tick_list);
67         delta = (tick_i_t)p_tcb->tick_match - (tick_i_t)g_tick_count;
68         /* since time list is sorted by remain time, so just campare  the absolute time */
69         if (delta > 0) {
70             break;
71         }
72 
73         switch (p_tcb->task_state) {
74             case K_SLEEP:
75                 p_tcb->blk_state  = BLK_FINISH;
76                 p_tcb->task_state = K_RDY;
77                 tick_list_rm(p_tcb);
78                 ready_list_add(&g_ready_queue, p_tcb);
79                 break;
80             case K_PEND:
81                 tick_list_rm(p_tcb);
82                 /* remove task on the block list because task is timeout */
83                 klist_rm(&p_tcb->task_list);
84                 ready_list_add(&g_ready_queue, p_tcb);
85                 p_tcb->blk_state  = BLK_TIMEOUT;
86                 p_tcb->task_state = K_RDY;
87                 mutex_task_pri_reset(p_tcb);
88                 p_tcb->blk_obj    = NULL;
89                 break;
90             case K_PEND_SUSPENDED:
91                 tick_list_rm(p_tcb);
92                 /* remove task on the block list because task is timeout */
93                 klist_rm(&p_tcb->task_list);
94                 p_tcb->blk_state  = BLK_TIMEOUT;
95                 p_tcb->task_state = K_SUSPENDED;
96                 mutex_task_pri_reset(p_tcb);
97                 p_tcb->blk_obj    = NULL;
98                 break;
99             case K_SLEEP_SUSPENDED:
100                 p_tcb->task_state = K_SUSPENDED;
101                 p_tcb->blk_state  = BLK_FINISH;
102                 tick_list_rm(p_tcb);
103                 break;
104             default:
105                 k_err_proc(RHINO_SYS_FATAL_ERR);
106                 break;
107         }
108 
109         iter = iter_temp;
110     }
111 
112     RHINO_CRITICAL_EXIT();
113 }
114 
115