Mercurial > ecos-v3_0-branch
annotate packages/kernel/current/include/clock.hxx @ 1088:4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
Cyg_Counter::rem_alarm() private functions. They no longer lock
the scheduler, so should not be called directly, only via the
Cyg_Alarm functions.
* include/clock.inl: Removed inline version of
Cyg_Alarm::disable(). It's no longer a one-liner and is thus
better as a proper function.
* src/common/clock.cxx (Cyg_Counter::tick): Rewrote the unsorted
list option. If the function of one alarm adds or removes other
alarms, then is was possible for the list to become corrupted. The
new implementation attempts to avoid this problem.
(Cyg_Alarm::initialize): Added scheduler locking to protect the
enabled flag.
(Cyg_Alarm::enable): Ditto.
(Cyg_Alarm::disable): Ditto. Moved here from clock.inl.
(Cyg_Alarm::add_alarm): Removed scheduler locking, it is now
always called from functions that have already locked it. Added an
assertion to double-check this.
(Cyg_Alarm::rem_alarm): Ditto.
* cdl/kernel.cdl:
* tests/kalarm0.c:
Added new test to test that alarms can be added and removed in
alarm functions safely.
| author | nickg |
|---|---|
| date | Tue, 01 Jul 2003 17:34:53 +0000 |
| parents | d2c90368aeef |
| children | 74dbf4c3f2e1 |
| rev | line source |
|---|---|
| 0 | 1 #ifndef CYGONCE_KERNEL_CLOCK_HXX |
| 2 #define CYGONCE_KERNEL_CLOCK_HXX | |
| 3 | |
| 4 //========================================================================== | |
| 5 // | |
| 2 | 6 // clock.hxx |
| 0 | 7 // |
| 2 | 8 // Clock and Alarm class declaration(s) |
| 0 | 9 // |
| 10 //========================================================================== | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
11 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
12 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
13 // This file is part of eCos, the Embedded Configurable Operating System. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
14 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
15 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
16 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
17 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
18 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
19 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
22 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
23 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
24 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
25 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
26 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
28 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
29 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
30 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
31 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
32 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
33 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
34 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
36 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
37 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
38 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
40 // at http://sources.redhat.com/ecos/ecos-license/ |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
41 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
148
diff
changeset
|
42 //####ECOSGPLCOPYRIGHTEND#### |
| 0 | 43 //========================================================================== |
| 44 //#####DESCRIPTIONBEGIN#### | |
| 45 // | |
| 2 | 46 // Author(s): nickg |
| 47 // Contributors: nickg | |
| 48 // Date: 1997-09-09 | |
| 49 // Purpose: Define Clock and Alarm class interfaces | |
| 50 // Description: The classes defined here collectively implement the | |
| 0 | 51 // internal API used to create, configure and manage Counters, |
| 52 // Clocks and Alarms. | |
| 53 // Usage: #include <cyg/kernel/clock.hxx> | |
| 54 // | |
| 55 //####DESCRIPTIONEND#### | |
| 56 // | |
| 57 //========================================================================== | |
| 58 | |
| 59 #include <cyg/kernel/ktypes.h> | |
| 60 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 61 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
62 #include <cyg/infra/clist.hxx> |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
63 |
| 0 | 64 // ------------------------------------------------------------------------- |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
65 // Forward definitions and typedefs. |
| 0 | 66 |
| 67 class Cyg_Alarm; | |
| 68 | |
| 69 typedef void cyg_alarm_fn(Cyg_Alarm *alarm, CYG_ADDRWORD data); | |
| 70 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
71 typedef Cyg_CList_T<Cyg_Alarm> Cyg_Alarm_List; |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
72 |
| 0 | 73 // ------------------------------------------------------------------------- |
| 74 // Counter object. | |
| 75 | |
| 76 class Cyg_Counter | |
| 77 { | |
| 78 | |
| 79 friend class Cyg_Alarm; | |
| 80 | |
| 81 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) | |
| 82 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
83 Cyg_Alarm_List alarm_list; // Linear list of Alarms |
| 0 | 84 |
| 85 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST) | |
| 86 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
87 Cyg_Alarm_List alarm_list[CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE]; |
| 0 | 88 |
| 89 #endif | |
| 90 | |
|
62
7a6ac9edc838
Merge from eCos master repository on 2000-01-24-19:43:49-GMT
jlarmour
parents:
2
diff
changeset
|
91 volatile cyg_tick_count counter; // counter value |
| 0 | 92 |
| 93 cyg_uint32 increment; // increment per tick | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
210
diff
changeset
|
94 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
210
diff
changeset
|
95 // Add an alarm to this counter |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
210
diff
changeset
|
96 void add_alarm( Cyg_Alarm *alarm ); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
210
diff
changeset
|
97 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
210
diff
changeset
|
98 // Remove an alarm from this counter |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
210
diff
changeset
|
99 void rem_alarm( Cyg_Alarm *alarm ); |
| 0 | 100 |
| 101 public: | |
| 102 | |
| 103 CYGDBG_DEFINE_CHECK_THIS | |
| 104 | |
| 105 Cyg_Counter( | |
| 106 cyg_uint32 increment = 1 | |
| 107 ); | |
| 108 | |
| 109 ~Cyg_Counter(); | |
| 110 | |
| 111 // Return current value of counter | |
| 112 cyg_tick_count current_value(); | |
| 113 | |
| 114 // Return low and high halves of the | |
| 115 // counter value. | |
| 116 cyg_uint32 current_value_lo(); | |
| 117 cyg_uint32 current_value_hi(); | |
| 118 | |
| 119 // Set the counter's current value | |
| 120 void set_value( cyg_tick_count new_value); | |
| 121 | |
| 122 // Advance counter by some number of ticks | |
| 123 void tick( cyg_uint32 ticks = 1); | |
| 124 | |
| 125 }; | |
| 126 | |
| 127 // ------------------------------------------------------------------------- | |
| 128 // Clock class. This is derived from a Counter and defines extra | |
| 129 // features to support clock-like behaviour. | |
| 130 | |
| 131 class Cyg_Clock | |
| 132 : public Cyg_Counter | |
| 133 { | |
| 134 | |
| 135 public: | |
| 136 | |
| 137 CYGDBG_DEFINE_CHECK_THIS | |
| 138 | |
| 139 // This structure allows a more accurate representation | |
| 140 // of the resolution than a single integer would allow. | |
| 141 // The resolution is defined as dividend/divisor nanoseconds | |
| 142 // per tick. | |
| 143 struct cyg_resolution { | |
| 144 cyg_uint32 dividend; | |
| 145 cyg_uint32 divisor; | |
| 146 }; | |
| 147 | |
| 148 private: | |
| 149 | |
| 150 cyg_resolution resolution; // Current clock resolution | |
| 151 | |
| 152 public: | |
| 153 | |
| 154 Cyg_Clock( // Create clock with given resolution | |
| 155 cyg_resolution resolution | |
| 156 ); | |
| 157 | |
| 158 ~Cyg_Clock(); // Destructor | |
| 159 | |
| 160 cyg_resolution get_resolution(); // Return current resolution | |
| 161 | |
| 162 void set_resolution( // Set new resolution | |
| 163 cyg_resolution resolution | |
| 164 ); | |
| 165 | |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
166 // There is a need for converting from "other" ticks to clock ticks. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
167 // We will construct 4 numbers to do the conversion as: |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
168 // clock_ticks = (((otherticks*mul1)/div1)*mul2/div2) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
169 // with the values chosen to minimize the possibility of overflow. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
170 // Do the arithmetic in cyg_uint64s throughout. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
171 struct converter { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
172 cyg_uint64 mul1, div1, mul2, div2; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
173 }; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
174 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
175 // There are two of these because the 4 numbers are different depending |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
176 // on the direction of the conversion, to prevent loss of significance. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
177 // NB these relate to the resolution of the clock object they are |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
178 // called against, not necessarily "the" system real time clock. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
179 void get_other_to_clock_converter( cyg_uint64 ns_per_other_tick, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
180 struct converter *pcc ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
181 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
182 void get_clock_to_other_converter( cyg_uint64 ns_per_other_tick, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
183 struct converter *pcc ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
184 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
185 // A utility to perform the conversion in the obvious way, with |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
186 // rounding to nearest at each stage. Static because it uses a |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
187 // previously acquired converter. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
188 static cyg_tick_count convert( cyg_tick_count value, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
189 struct converter *pcc ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
62
diff
changeset
|
190 |
| 0 | 191 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK |
| 192 | |
| 193 // There is a system supplied real time clock... | |
| 194 | |
| 195 static Cyg_Clock *real_time_clock; | |
| 196 | |
| 197 #endif | |
| 198 | |
| 199 }; | |
| 200 | |
| 201 // ------------------------------------------------------------------------- | |
| 202 // Alarm class. An alarm may be attached to a counter (or a clock) to be | |
| 203 // called when the trigger value is reached. | |
| 204 | |
| 205 class Cyg_Alarm | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
206 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) || defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST) |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
207 : public Cyg_DNode_T<Cyg_Alarm> |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
115
diff
changeset
|
208 #endif |
| 0 | 209 { |
| 210 friend class Cyg_Counter; | |
| 211 | |
| 212 protected: | |
| 213 Cyg_Counter *counter; // Attached to this counter/clock | |
| 214 | |
| 215 cyg_alarm_fn *alarm; // Call-back function | |
| 216 | |
| 217 CYG_ADDRWORD data; // Call-back data | |
| 218 | |
| 219 cyg_tick_count trigger; // Absolute trigger time | |
| 220 | |
| 221 cyg_tick_count interval; // Retrigger interval | |
| 222 | |
| 223 cyg_bool enabled; // True if enabled | |
| 224 | |
| 225 Cyg_Alarm(); | |
| 226 | |
| 227 void synchronize( void ); // deal with times in the past, | |
| 228 // make next alarm in synch. | |
| 229 | |
| 230 public: | |
| 231 | |
| 232 CYGDBG_DEFINE_CHECK_THIS | |
| 233 | |
| 234 Cyg_Alarm // Constructor | |
| 235 ( | |
| 236 Cyg_Counter *counter, // Attached to this counter | |
| 237 cyg_alarm_fn *alarm, // Call-back function | |
| 238 CYG_ADDRWORD data // Call-back data | |
| 239 ); | |
| 240 | |
| 241 ~Cyg_Alarm(); // Destructor | |
| 242 | |
| 243 void initialize( // Initialize Alarm | |
| 244 cyg_tick_count trigger, // Absolute trigger time | |
| 245 cyg_tick_count interval = 0 // Relative retrigger interval | |
| 246 ); | |
| 247 | |
| 248 void enable(); // Ensure alarm enabled | |
| 249 | |
| 250 void disable(); // Ensure alarm disabled | |
| 251 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
252 void get_times( |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
253 cyg_tick_count *trigger, // Next trigger time |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
254 cyg_tick_count *interval // Current interval |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
66
diff
changeset
|
255 ); |
| 0 | 256 }; |
| 257 | |
| 258 // ------------------------------------------------------------------------- | |
| 259 | |
| 260 #endif // ifndef CYGONCE_KERNEL_CLOCK_HXX | |
| 261 // EOF clock.hxx |
