]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/scout-gfx/lib/tick.cc
update
[l4.git] / l4 / pkg / scout-gfx / lib / tick.cc
1 /*
2  * \brief   Timed event scheduler
3  * \date    2005-10-24
4  * \author  Norman Feske <norman.feske@genode-labs.com>
5  */
6 /*
7  * Copyright (C) 2005-2009
8  * Genode Labs, Feske & Helmuth Systementwicklung GbR
9  *
10  * This file is part of the Genode OS framework, which is distributed
11  * under the terms of the GNU General Public License version 2.
12  */
13
14 #include <l4/scout-gfx/tick>
15 #include <cstdio>
16
17 namespace Scout_gfx {
18
19 static Tick       *head = 0;   /* head of tick list                        */
20 static Tick::Time  now  = 0;   /* recent time (updated by handle function) */
21
22 void Tick::_enqueue()
23 {
24   /* do not enqueue twice */
25   if (++_active > 1)
26     {
27       //                printf("enqueue twice? ticks scheduled=%d\n", ticks_scheduled());
28       _active--;
29       return;
30     }
31
32   /* if ticklist is empty add first element */
33   if (!head)
34     {
35       _next = 0;
36       head = this;
37       return;
38     }
39
40   /* if deadline is smaller than any other deadline, put it on the head */
41   if ((int)_deadline - (int)now < (int)head->_deadline - (int)now)
42     {
43       _next = head;
44       head = this;
45       return;
46     }
47
48   /* find list element with a higher deadline */
49   Tick *curr = head;
50   while (curr->_next && ((int)curr->_next->_deadline - (int)now < (int)_deadline - (int)now))
51     curr = curr->_next;
52
53   /* if end of list is reached, append new element */
54   if (curr->_next == 0)
55     {
56       curr->_next = this;
57       return;
58     }
59
60   /* insert element in middle of list */
61   _next = curr->_next;
62   curr->_next = this;
63 }
64
65
66 void Tick::_dequeue()
67 {
68   if (!head)
69     return;
70
71   if (head == this)
72     {
73       head = _next;
74       return;
75     }
76
77   /* find predecessor in tick queue */
78   Tick *curr;
79   for (curr = head; curr && (curr->_next != this); curr = curr->_next)
80     ;
81
82   /* tick is not enqueued */
83   if (!curr)
84     return;
85
86   /* skip us in tick queue */
87   curr->_next = _next;
88
89   _next = 0;
90 }
91
92
93 void Tick::schedule(Time period)
94 {
95   _period    = period;
96   if (!_active)
97     {
98       _deadline  = now;       /* first deadline is overdue */
99       _enqueue();
100     }
101 }
102
103
104 int Tick::ticks_scheduled()
105 {
106         int num_ticks = 0;
107         printf("now=%d\n", (int)now);
108         for (Tick *curr = head; curr; curr = curr->_next, num_ticks++)
109                 printf("ticks_scheduled:\n %d: curr=%p, deadline=%d\n",
110                        (int)num_ticks, curr, (int)curr->_deadline);
111         return num_ticks;
112 }
113
114
115 void Tick::handle(Time curr_time)
116 {
117         Tick *curr;
118         now = curr_time;
119
120         while ((curr = head) && ((int)head->_deadline - (int)now < 0)) {
121
122                 /* remove tick from head of the list */
123                 head = curr->_next;
124
125                 curr->_next = 0;
126                 curr->_active--;
127
128                 /* do not reschedule if tick function returns 0 */
129                 if (!curr->on_tick()) continue;
130
131                 /* schedule next event */
132                 if (curr->_deadline == 0)
133                         curr->_deadline = now;
134
135                 curr->_deadline += curr->_period;
136                 curr->_enqueue();
137         }
138 }
139
140 }