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