]> git.buserror.net Git - polintos/scott/priv.git/blob - lib/kernel/time/timer.cc
minor doc updates
[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 // This software is provided 'as-is', without any express or implied warranty.
6 // In no event will the authors or contributors be held liable for any damages
7 // arising from the use of this software.
8 // 
9 // Permission is hereby granted to everyone, free of charge, to use, copy,
10 // modify, prepare derivative works of, publish, distribute, perform,
11 // sublicense, and/or sell copies of the Software, provided that the above
12 // copyright notice and disclaimer of warranty be included in all copies or
13 // substantial portions of this software.
14
15 #include <kernel/time.h>
16 #include <lowlevel/clock.h>
17
18 namespace Time {
19         void TimerMux::arm(TimerEntry *entry, Time expiry)
20         {
21                 AutoSpinLockRecIRQ autolock(lock);
22                 
23                 bool was_empty = heap.empty();
24                 Time oldexpiry;
25
26                 if (!was_empty) {
27                         oldexpiry = heap.get_top()->expiry;
28                 } else {
29                         // Shut up the compiler
30                         oldexpiry.seconds = 0;
31                         oldexpiry.nanos = 0;
32                 }
33
34                 entry->expiry = expiry;
35                 
36                 if (entry->is_armed())
37                         heap.requeue(entry);
38                 else
39                         heap.add(entry);
40
41                 Time newexpiry = heap.get_top()->expiry;
42                 if (was_empty || oldexpiry != newexpiry)
43                         parent.arm(newexpiry);
44         }
45
46         void TimerMux::disarm(TimerEntry *entry)
47         {
48                 AutoSpinLockRecIRQ autolock(lock);
49                 
50                 if (entry->is_armed()) {
51                         bool was_top = entry == heap.get_top();
52
53                         heap.del(entry);
54
55                         if (was_top)
56                                 parent.arm(heap.get_top()->expiry);
57                 }
58         }
59         
60         void TimerMux::run()
61         {
62                 DroppableAutoSpinLockRecIRQ autolock(lock);
63                 
64                 while (true) {
65                         TimerEntry *top = heap.get_top();
66                         Time now;
67                         clock.get_time(&now);
68
69                         if (now < top->expiry)
70                                 break;
71
72                         heap.del(top);
73
74                         autolock.unlock();
75                         top->action();
76                         autolock.lock();
77                 }
78                 
79                 if (!heap.empty())
80                         parent.arm(heap.get_top()->expiry);
81         }
82         
83         void TimerEntry::set_action(System::Events::Event *event)
84         {
85                 // FIXME
86         }
87
88         void TimerEntry::action()
89         {
90                 // FIXME
91         }
92 }
93
94 #include _KERNEL_SERVER(time/timer/footer.cc)