]> git.buserror.net Git - polintos/scott/priv.git/blob - lib/kernel/time/timer.cc
Switch to a simple X11-style license.
[polintos/scott/priv.git] / lib / kernel / time / timer.cc
1 // lib/kernel/time/timer.cc -- Generic timer multiplexing
2 //
3 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
4 // 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal with
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 // of the Software, and to permit persons to whom the Software is furnished to do
10 // so, subject to the following condition:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
21 // SOFTWARE.
22
23 #include <kernel/time.h>
24 #include <lowlevel/clock.h>
25
26 namespace Time {
27         void TimerMux::arm(TimerEntry *entry, Time expiry)
28         {
29                 AutoSpinLockRecIRQ autolock(lock);
30                 
31                 bool was_empty = heap.empty();
32                 Time oldexpiry;
33
34                 if (!was_empty) {
35                         oldexpiry = heap.get_top()->expiry;
36                 } else {
37                         // Shut up the compiler
38                         oldexpiry.seconds = 0;
39                         oldexpiry.nanos = 0;
40                 }
41
42                 entry->expiry = expiry;
43                 
44                 if (entry->is_armed())
45                         heap.requeue(entry);
46                 else
47                         heap.add(entry);
48
49                 Time newexpiry = heap.get_top()->expiry;
50                 if (was_empty || oldexpiry != newexpiry)
51                         parent.arm(newexpiry);
52         }
53
54         void TimerMux::disarm(TimerEntry *entry)
55         {
56                 AutoSpinLockRecIRQ autolock(lock);
57                 
58                 if (entry->is_armed()) {
59                         bool was_top = entry == heap.get_top();
60
61                         heap.del(entry);
62
63                         if (was_top)
64                                 parent.arm(heap.get_top()->expiry);
65                 }
66         }
67         
68         void TimerMux::run()
69         {
70                 DroppableAutoSpinLockRecIRQ autolock(lock);
71                 
72                 while (true) {
73                         TimerEntry *top = heap.get_top();
74                         Time now;
75                         clock.get_time(&now);
76
77                         if (now < top->expiry)
78                                 break;
79
80                         heap.del(top);
81
82                         autolock.unlock();
83                         top->action();
84                         autolock.lock();
85                 }
86                 
87                 if (!heap.empty())
88                         parent.arm(heap.get_top()->expiry);
89         }
90         
91         void TimerEntry::set_action(System::Events::Event *event)
92         {
93                 // FIXME
94         }
95
96         void TimerEntry::action()
97         {
98                 // FIXME
99         }
100 }
101
102 #include _KERNEL_SERVER(time/timer/footer.cc)