Mercurial > flash_v2
annotate packages/kernel/current/src/common/clock.cxx @ 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 | e4850e482c80 |
| children | 9ab0a182923a |
| rev | line source |
|---|---|
| 0 | 1 //========================================================================== |
| 2 // | |
| 2 | 3 // common/clock.cxx |
| 0 | 4 // |
| 2 | 5 // Clock class implementations |
| 0 | 6 // |
| 7 //========================================================================== | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
9 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
10 // 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:
174
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
356
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
12 // Copyright (C) 2002 Jonathan Larmour |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
13 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
14 // 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:
174
diff
changeset
|
15 // 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:
174
diff
changeset
|
16 // 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:
174
diff
changeset
|
17 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
18 // 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:
174
diff
changeset
|
19 // 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:
174
diff
changeset
|
20 // 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:
174
diff
changeset
|
21 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
22 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
23 // 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:
174
diff
changeset
|
24 // 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:
174
diff
changeset
|
25 // 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:
174
diff
changeset
|
26 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
27 // 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:
174
diff
changeset
|
28 // 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:
174
diff
changeset
|
29 // 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:
174
diff
changeset
|
30 // 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:
174
diff
changeset
|
31 // 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:
174
diff
changeset
|
32 // 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:
174
diff
changeset
|
33 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
34 // 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:
174
diff
changeset
|
35 // 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:
174
diff
changeset
|
36 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
37 // 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
|
38 // 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:
174
diff
changeset
|
39 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
174
diff
changeset
|
40 //####ECOSGPLCOPYRIGHTEND#### |
| 0 | 41 //========================================================================== |
| 42 //#####DESCRIPTIONBEGIN#### | |
| 43 // | |
| 2 | 44 // Author(s): nickg |
| 45 // Contributors: nickg | |
| 46 // Date: 1997-09-15 | |
| 47 // Purpose: Clock class implementation | |
| 0 | 48 // Description: This file contains the definitions of the counter, |
| 49 // clock and alarm class member functions that are common | |
| 50 // to all clock implementations. | |
| 51 // | |
| 52 //####DESCRIPTIONEND#### | |
| 53 // | |
| 54 //========================================================================== | |
| 55 | |
| 56 #include <pkgconf/kernel.h> | |
| 57 | |
| 58 #include <cyg/kernel/ktypes.h> // base kernel types | |
| 59 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 60 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 61 | |
| 62 #include <cyg/kernel/clock.hxx> // our header | |
| 63 | |
| 64 #include <cyg/kernel/sched.hxx> // scheduler definitions | |
| 65 #include <cyg/kernel/thread.hxx> // thread definitions | |
| 66 #include <cyg/kernel/intr.hxx> // interrupt definitions | |
| 67 | |
| 68 #include <cyg/kernel/sched.inl> // scheduler inlines | |
| 69 #include <cyg/kernel/clock.inl> // Clock inlines | |
| 70 | |
| 71 // ------------------------------------------------------------------------- | |
| 72 // Static variables | |
| 73 | |
| 74 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK | |
| 75 | |
| 76 Cyg_Clock *Cyg_Clock::real_time_clock = NULL; // System real time clock | |
| 77 | |
| 78 #endif | |
| 79 | |
| 80 //========================================================================== | |
| 81 // Constructor for counter object | |
| 82 | |
| 83 Cyg_Counter::Cyg_Counter( | |
| 84 cyg_uint32 incr | |
| 85 ) | |
| 86 { | |
| 87 CYG_REPORT_FUNCTION(); | |
| 88 | |
| 89 counter = 0; | |
| 90 increment = incr; | |
| 91 | |
| 92 } | |
| 93 | |
| 94 // ------------------------------------------------------------------------- | |
| 95 // Destructor for Counter object | |
| 96 | |
| 97 Cyg_Counter::~Cyg_Counter() | |
| 98 { | |
| 99 CYG_REPORT_FUNCTION(); | |
| 100 | |
| 101 | |
| 102 } | |
| 103 | |
| 104 // ------------------------------------------------------------------------- | |
| 105 // | |
| 106 | |
| 107 #ifdef CYGDBG_USE_ASSERTS | |
| 108 | |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
66
diff
changeset
|
109 cyg_bool Cyg_Counter::check_this( cyg_assert_class_zeal zeal) const |
| 0 | 110 { |
| 111 // check that we have a non-NULL pointer first | |
| 112 if( this == NULL ) return false; | |
| 113 | |
| 114 switch( zeal ) | |
| 115 { | |
| 116 case cyg_system_test: | |
| 117 case cyg_extreme: | |
| 118 case cyg_thorough: | |
| 119 case cyg_quick: | |
| 120 case cyg_trivial: | |
| 121 case cyg_none: | |
| 122 default: | |
| 123 break; | |
| 124 }; | |
| 125 | |
| 126 return true; | |
| 127 } | |
| 128 | |
| 129 #endif | |
| 130 | |
| 131 // ------------------------------------------------------------------------- | |
| 132 // Counter tick function | |
| 133 | |
| 134 void Cyg_Counter::tick( cyg_uint32 ticks ) | |
| 135 { | |
| 136 // CYG_REPORT_FUNCTION(); | |
| 137 | |
| 138 CYG_ASSERTCLASS( this, "Bad counter object" ); | |
| 139 | |
| 140 // Increment the counter in a loop so we process | |
| 141 // each tick separately. This is easier than trying | |
| 142 // to cope with a range of increments. | |
| 143 | |
| 144 while( ticks-- ) | |
| 145 { | |
| 146 Cyg_Scheduler::lock(); | |
| 147 | |
| 148 // increment the counter, note that it is | |
| 149 // allowed to wrap. | |
| 150 counter += increment; | |
| 151 | |
| 152 // now check for any expired alarms | |
| 153 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
154 Cyg_Alarm_List *alarm_list_ptr; // pointer to list |
| 0 | 155 |
| 156 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) | |
| 157 | |
| 158 alarm_list_ptr = &alarm_list; | |
| 159 | |
| 160 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST) | |
| 161 | |
| 162 // With multiple lists, each one contains only the alarms | |
| 163 // that will expire at a given tick modulo the list number. | |
| 164 // So we only have a fraction of the alarms to check here. | |
| 165 | |
| 166 alarm_list_ptr = &(alarm_list[ | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
167 (counter/increment) % CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE ] ); |
| 0 | 168 |
| 169 #else | |
| 170 #error "No CYGIMP_KERNEL_COUNTERS_x_LIST config" | |
| 171 #endif | |
| 172 | |
| 173 // Now that we have the list pointer, we can use common code for | |
|
1077
e4850e482c80
* src/common/clock.cxx (Cyg_Counter::rem_alarm): Bugfix: call
jlarmour
parents:
356
diff
changeset
|
174 // both list organizations. |
| 0 | 175 |
| 2 | 176 #ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST |
| 177 | |
| 178 // With a sorted alarm list, we can simply pick alarms off the | |
| 179 // front of the list until we find one that is in the future. | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
180 |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
181 while( !alarm_list_ptr->empty() ) |
| 0 | 182 { |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
183 Cyg_Alarm *alarm = alarm_list_ptr->get_head(); |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
184 |
| 0 | 185 CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" ); |
| 186 | |
| 187 if( alarm->trigger <= counter ) | |
| 188 { | |
| 189 // remove alarm from list | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
190 alarm_list_ptr->rem_head(); |
| 0 | 191 |
| 192 if( alarm->interval != 0 ) | |
| 193 { | |
| 194 // The alarm has a retrigger interval. | |
| 195 // Reset the trigger time and requeue | |
| 196 // the alarm. | |
| 197 alarm->trigger += alarm->interval; | |
| 198 add_alarm( alarm ); | |
| 199 } | |
| 200 else alarm->enabled = false; | |
| 201 | |
| 202 CYG_INSTRUMENT_ALARM( CALL, this, alarm ); | |
| 203 | |
| 204 // call alarm function | |
| 205 alarm->alarm(alarm, alarm->data); | |
| 206 | |
| 207 // all done, loop | |
| 208 } | |
| 209 else break; | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
210 |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
211 } |
| 2 | 212 #else |
| 0 | 213 |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
214 // With unsorted lists we must scan the whole list for |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
215 // candidates. However, we must be careful here since it is |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
216 // possible for the function of one alarm to add or remove |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
217 // other alarms to/from this list. Having the list shift under |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
218 // our feet in this way could be disasterous. We solve this by |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
219 // detecting when the list has changed and restarting the scan |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
220 // from the beginning. |
| 2 | 221 |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
222 Cyg_DNode_T<Cyg_Alarm> *node = alarm_list_ptr->get_head(); |
| 2 | 223 |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
224 while( node != NULL ) |
| 2 | 225 { |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
226 Cyg_Alarm *alarm = CYG_CLASSFROMBASE( Cyg_Alarm, Cyg_DNode, node ); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
227 Cyg_DNode_T<Cyg_Alarm> *next = alarm->get_next(); |
| 2 | 228 |
| 229 CYG_ASSERTCLASS(alarm, "Bad alarm in counter list" ); | |
| 230 | |
| 231 if( alarm->trigger <= counter ) | |
| 232 { | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
233 Cyg_DNode *next_next, *next_prev; |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
234 Cyg_Alarm *head; |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
235 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
236 alarm_list_ptr->remove(alarm); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
237 |
| 2 | 238 if( alarm->interval != 0 ) |
| 239 { | |
| 240 // The alarm has a retrigger interval. | |
| 241 // Reset the trigger time and requeue | |
| 242 // the alarm. | |
| 243 alarm->trigger += alarm->interval; | |
| 244 add_alarm( alarm ); | |
| 245 } | |
| 246 else alarm->enabled = false; | |
| 247 | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
248 // Save some details of the list state so we can |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
249 // detect if it has changed. |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
250 next_next = next->get_next(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
251 next_prev = next->get_prev(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
252 head = alarm_list_ptr->get_head(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
253 |
| 2 | 254 CYG_INSTRUMENT_ALARM( CALL, this, alarm ); |
| 255 | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
256 // Call alarm function |
| 2 | 257 alarm->alarm(alarm, alarm->data); |
| 258 | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
259 // If that alarm function has added or removed an |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
260 // alarm on this list that might affect this scan, |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
261 // then start again from beginning. The main test here |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
262 // is whether the link fields of the next node have |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
263 // changed, implying that it may have been moved. The |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
264 // test against the list head detects the case where |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
265 // the next node was the only node in the list, when |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
266 // moving is would have left the links unchanged. |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
267 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
268 if( next_next != next->get_next() || |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
269 next_prev != next->get_prev() || |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
270 head != alarm_list_ptr->get_head() ) |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
271 { |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
272 node = alarm_list_ptr->get_head(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
273 continue; |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
274 } |
| 2 | 275 } |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
276 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
277 // If the next node is the head of the list, then we have |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
278 // looped all the way around. The node == next test |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
279 // catches the case where we only had one element to start |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
280 // with. |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
281 if( next == alarm_list_ptr->get_head() || node == next ) |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
282 node = NULL; |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
283 else |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
284 node = next; |
| 2 | 285 } |
| 286 | |
| 287 #endif | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
288 Cyg_Scheduler::unlock(); |
| 0 | 289 |
| 290 } | |
| 291 | |
| 292 } | |
| 293 | |
| 294 // ------------------------------------------------------------------------- | |
| 295 // Add an alarm to this counter | |
| 296 | |
| 297 void Cyg_Counter::add_alarm( Cyg_Alarm *alarm ) | |
| 298 { | |
| 299 CYG_REPORT_FUNCTION(); | |
| 300 | |
| 301 CYG_ASSERTCLASS( this, "Bad counter object" ); | |
| 302 CYG_ASSERTCLASS( alarm, "Bad alarm passed" ); | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
303 CYG_ASSERT( Cyg_Scheduler::get_sched_lock() > 0, "Scheduler not locked"); |
| 0 | 304 |
| 305 // set this now to allow an immediate handler call to manipulate | |
| 306 // this alarm sensibly. | |
| 307 alarm->enabled = true; | |
| 308 | |
| 309 // Check here for an alarm that triggers now or in the past and | |
| 310 // call its alarm function immediately. | |
| 311 if( alarm->trigger <= counter ) | |
| 312 { | |
| 313 CYG_INSTRUMENT_ALARM( CALL, this, alarm ); | |
| 314 | |
| 315 // call alarm function. Note that this is being | |
| 316 // called here before the add_alarm has returned. | |
| 317 // Note that this function may disable the alarm. | |
| 318 | |
| 319 alarm->alarm(alarm, alarm->data); | |
| 320 | |
| 321 // Note that this extra check on alarm->enabled is in case the | |
| 322 // handler function disables this alarm! | |
| 323 if( alarm->interval != 0 && alarm->enabled ) | |
| 324 { | |
| 325 // The alarm has a retrigger interval. | |
| 326 // Reset the trigger interval and drop | |
| 327 // through to queue it. | |
| 328 alarm->trigger += alarm->interval; | |
| 329 // ensure the next alarm time is in our future, and in phase | |
| 330 // with the original time requested. | |
| 331 alarm->synchronize(); | |
| 332 } | |
| 333 else | |
| 334 { | |
| 335 // The alarm is all done with, disable it | |
| 336 // unlock and return. | |
| 337 alarm->enabled = false; | |
| 338 return; | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 CYG_INSTRUMENT_ALARM( ADD, this, alarm ); | |
| 343 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
344 // Find the pointer to the relevant list _after_ a retrigger |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
345 // alarm has been given its new trigger time. |
| 0 | 346 |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
347 Cyg_Alarm_List *alarm_list_ptr; // pointer to list |
| 0 | 348 |
| 349 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) | |
| 350 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
351 alarm_list_ptr = &alarm_list; |
| 0 | 352 |
| 353 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST) | |
| 354 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
355 // Each alarm must go into the list that covers the tick that is |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
356 // going to happen _after_ the trigger time (or at it if trigger |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
357 // happens to fall on a tick. |
| 0 | 358 |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
359 alarm_list_ptr = &(alarm_list[ |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
360 ((alarm->trigger+increment-1)/increment) % |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
361 CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE ] ); |
| 0 | 362 |
| 363 #else | |
| 364 #error "No CYGIMP_KERNEL_COUNTERS_x_LIST config" | |
| 365 #endif | |
| 366 | |
| 2 | 367 #ifdef CYGIMP_KERNEL_COUNTERS_SORT_LIST |
| 368 | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
369 // Now that we have the list pointer, we can use common code for |
|
356
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
370 // both list organizations. |
| 0 | 371 |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
372 Cyg_Alarm *list_alarm = alarm_list_ptr->get_head(); |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
373 |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
374 if( list_alarm != NULL ) |
|
356
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
375 { |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
376 do |
| 0 | 377 { |
| 378 CYG_ASSERTCLASS(list_alarm, "Bad alarm in counter list" ); | |
| 379 | |
|
356
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
380 // The alarms are in ascending trigger order. If we |
|
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
381 // find an alarm that triggers later than us, we go |
|
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
382 // in front of it. |
| 0 | 383 |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
384 if( list_alarm->trigger > alarm->trigger ) |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
385 { |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
386 alarm_list_ptr->insert( list_alarm, alarm ); |
|
356
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
387 goto add_alarm_unlock_return; |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
388 } |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
389 |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
390 list_alarm = list_alarm->get_next(); |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
391 |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
392 } while( list_alarm != alarm_list_ptr->get_head() ); |
|
356
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
393 // a lower or equal alarm time was not found, so drop through |
|
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
394 // so it is added to the list tail |
|
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
395 } |
|
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
396 alarm_list_ptr->add_tail( alarm ); |
| 0 | 397 |
|
356
b77e86276ec3
* src/common/clock.cxx (add_alarm): Tweak last change to allow
jlarmour
parents:
210
diff
changeset
|
398 add_alarm_unlock_return: |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
399 #else |
| 0 | 400 |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
401 alarm_list_ptr->add_tail( alarm ); |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
402 |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
403 #endif |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
404 |
| 0 | 405 } |
| 406 | |
| 407 // ------------------------------------------------------------------------- | |
| 408 // Remove an alarm from this counter | |
| 409 | |
| 410 void Cyg_Counter::rem_alarm( Cyg_Alarm *alarm ) | |
| 411 { | |
| 412 CYG_REPORT_FUNCTION(); | |
| 413 | |
| 414 CYG_ASSERTCLASS( this, "Bad counter object" ); | |
| 415 CYG_ASSERTCLASS( alarm, "Bad alarm passed" ); | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
416 CYG_ASSERT( Cyg_Scheduler::get_sched_lock() > 0, "Scheduler not locked"); |
| 0 | 417 |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
418 Cyg_Alarm_List *alarm_list_ptr; // pointer to list |
| 0 | 419 |
| 420 #if defined(CYGIMP_KERNEL_COUNTERS_SINGLE_LIST) | |
| 421 | |
| 422 alarm_list_ptr = &alarm_list; | |
| 423 | |
| 424 #elif defined(CYGIMP_KERNEL_COUNTERS_MULTI_LIST) | |
| 425 | |
| 426 alarm_list_ptr = &(alarm_list[ | |
| 427 ((alarm->trigger+increment-1)/increment) % | |
| 428 CYGNUM_KERNEL_COUNTERS_MULTI_LIST_SIZE ] ); | |
| 429 | |
| 430 #else | |
| 431 #error "No CYGIMP_KERNEL_COUNTERS_x_LIST config" | |
| 432 #endif | |
| 433 | |
| 434 // Now that we have the list pointer, we can use common code for | |
| 435 // both list organizations. | |
| 436 | |
| 437 CYG_INSTRUMENT_ALARM( REM, this, alarm ); | |
|
148
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
438 |
|
8f2f7615e727
Merge from eCos master repository on 2001-01-12-06:43:03-GMT
jlarmour
parents:
132
diff
changeset
|
439 alarm_list_ptr->remove( alarm ); |
| 0 | 440 |
|
151
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
148
diff
changeset
|
441 alarm->enabled = false; |
|
25e238959bae
Merge from eCos master repository on 2001-02-12-23:44:24-GMT
jlarmour
parents:
148
diff
changeset
|
442 |
| 0 | 443 } |
| 444 | |
| 445 //========================================================================== | |
| 446 // Constructor for clock object | |
| 447 | |
| 448 Cyg_Clock::Cyg_Clock( | |
| 449 cyg_resolution res | |
| 450 ) | |
| 451 { | |
| 452 CYG_REPORT_FUNCTION(); | |
| 453 | |
| 454 resolution = res; | |
| 455 } | |
| 456 | |
| 457 // ------------------------------------------------------------------------- | |
| 458 // Destructor for Clock objects | |
| 459 | |
| 460 Cyg_Clock::~Cyg_Clock() | |
| 461 { | |
| 462 CYG_REPORT_FUNCTION(); | |
| 463 | |
| 464 } | |
| 465 | |
| 466 // ------------------------------------------------------------------------- | |
| 467 // | |
| 468 | |
| 469 #ifdef CYGDBG_USE_ASSERTS | |
| 470 | |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
66
diff
changeset
|
471 cyg_bool Cyg_Clock::check_this( cyg_assert_class_zeal zeal) const |
| 0 | 472 { |
| 473 // check that we have a non-NULL pointer first | |
| 474 if( this == NULL ) return false; | |
| 475 | |
| 476 switch( zeal ) | |
| 477 { | |
| 478 case cyg_system_test: | |
| 479 case cyg_extreme: | |
| 480 case cyg_thorough: | |
| 481 case cyg_quick: | |
| 482 case cyg_trivial: | |
| 483 case cyg_none: | |
| 484 default: | |
| 485 break; | |
| 486 }; | |
| 487 | |
| 488 return true; | |
| 489 } | |
| 490 | |
| 491 #endif | |
| 492 | |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
493 // ------------------------------------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
494 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
495 // Clock Converters: split a rational into 4 factors to try to prevent |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
496 // overflow whilst retaining reasonable accuracy. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
497 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
498 // typically we get numbers like 1,000,000 for ns_per and |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
499 // 100 and 1,000,000,000 for the dividend and divisor. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
500 // So we want answers like 1/10 and 10/1 out of these routines. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
501 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
502 static void construct_converter( Cyg_Clock::converter *pcc, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
503 cyg_uint64 m1, cyg_uint64 d1, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
504 cyg_uint64 m2, cyg_uint64 d2 ) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
505 { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
506 cyg_uint64 upper, lower; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
507 unsigned int i; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
508 static cyg_uint16 primes[] = { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
509 3,5,7,11,13,17,19,23,29,31,37,41,43,47, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
510 53,59,61,67,71,73,79,83,89,97, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
511 101,103,107,109,113,127,131,137,139,149, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
512 151,157,163,167,173,179,181,191,193,197,199, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
513 239, // for 1,111,111 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
514 541, // for 10,101,011 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
515 1667, // for 8,333,333 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
516 }; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
517 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
518 int rounding = 0; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
519 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
520 // Here we assume that our workings will fit in a 64; the point is to |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
521 // allow calculations with a number of ticks that may be large. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
522 upper = m1 * m2; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
523 lower = d1 * d2; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
524 #ifdef CYGDBG_USE_ASSERTS |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
525 cyg_uint64 save_upper = upper; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
526 cyg_uint64 save_lower = lower; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
527 #endif |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
528 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
529 retry_rounding: |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
530 // First strip out common powers of 2 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
531 while ( (0 == (1 & upper)) && ( 0 == (1 & lower)) ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
532 upper >>= 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
533 lower >>= 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
534 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
535 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
536 // then common factors - use lazy table above |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
537 for ( i = 0 ; i < (sizeof( primes )/sizeof( primes[0] )); i++ ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
538 cyg_uint64 j, k, p = (cyg_uint64)(primes[i]); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
539 j = upper / p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
540 while ( j * p == upper ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
541 k = lower / p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
542 if ( k * p != lower ) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
543 break; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
544 upper = j; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
545 lower = k; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
546 j = upper / p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
547 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
548 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
549 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
550 m1 = upper; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
551 d1 = lower; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
552 m2 = 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
553 d2 = 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
554 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
555 if ( m1 > 0x10000 ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
556 // only bother if there are more than 16 bits consumed here |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
557 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
558 // now move powers of 2 from d1 to d2 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
559 // keeping them the same order of magnitude |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
560 while ( (0 == (1 & d1)) && (d2 < d1) ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
561 d1 >>= 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
562 d2 <<= 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
563 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
564 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
565 // and factors from the table - go too far, if anything |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
566 int cont = (d2 < d1); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
567 for ( i = 0 ; cont && (i < (sizeof( primes )/sizeof( primes[0] ))); i++ ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
568 cyg_uint64 k, p = (cyg_uint64)(primes[i]); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
569 k = d1 / p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
570 while ( cont && ((k * p) == d1) ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
571 // we can extract a prime |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
572 d1 = k; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
573 d2 *= p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
574 k = d1 / p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
575 cont = (d2 < d1); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
576 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
577 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
578 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
579 // move powers of 2 from m1 to m2 so long as we do not go less than d1 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
580 while ( (0 == (1 & m1)) && (m2 < m1) && (m1 > (d1 << 5)) ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
581 m1 >>= 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
582 m2 <<= 1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
583 if ( m1 < 0x10000 ) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
584 break; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
585 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
586 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
587 // and factors from the table - ensure m1 stays well larger than d1 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
588 cont = ((m2 < m1) && (m1 > (d1 << 4)) && (m1 > 0x10000)); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
589 for ( i = 0 ; cont && (i < (sizeof( primes )/sizeof( primes[0] ))); i++ ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
590 cyg_uint64 k, p = (cyg_uint64)(primes[i]); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
591 k = m1 / p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
592 cont = cont && (k > (d1 << 4) && (k > 0x10000)); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
593 while ( cont && ((k * p) == m1) ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
594 // we can extract a prime |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
595 m1 = k; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
596 m2 *= p; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
597 k = m1 / p; // examine k for getting too small |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
598 cont = ((m2 < m1) && (k > (d1 << 4)) && (k > 0x10000)); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
599 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
600 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
601 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
602 // if, after all that, m1 odd and unchanged, and too large, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
603 // decrement it just the once and try again: then try it |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
604 // incremented once. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
605 if ( (m1 & 1) && (m1 == upper) && (m1 > 0x10000) && (rounding < 2) ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
606 CYG_ASSERT( 1 == m2, "m2 should be 1 to try rounding" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
607 m1--; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
608 upper = m1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
609 rounding++; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
610 goto retry_rounding; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
611 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
612 // likewise for d1 - each of the pair can be odd only once each |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
613 if ( (d1 & 1) && (d1 == lower) && (d1 > 0x10000) && (rounding < 2) ) { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
614 CYG_ASSERT( 1 == d2, "d2 should be 1 to try rounding" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
615 d1--; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
616 lower = d1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
617 rounding++; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
618 goto retry_rounding; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
619 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
620 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
621 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
622 CYG_ASSERT( 0 != m1, "m1 zero" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
623 CYG_ASSERT( 0 != m2, "m2 zero" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
624 CYG_ASSERT( 0 != d1, "d1 zero" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
625 CYG_ASSERT( 0 != d2, "d2 zero" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
626 CYG_ASSERT( rounding || save_upper/save_lower == (m1 * m2)/(d1 * d2), |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
627 "Unequal in forwards direction" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
628 CYG_ASSERT( rounding || save_lower/save_upper == (d1 * d2)/(m1 * m2), |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
629 "Unequal in reverse direction" ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
630 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
631 pcc->mul1 = m1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
632 pcc->div1 = d1; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
633 pcc->mul2 = m2; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
634 pcc->div2 = d2; |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
635 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
636 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
637 // other to clocks is (other * ns_per * dividend / divisor) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
638 void Cyg_Clock::get_other_to_clock_converter( |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
639 cyg_uint64 ns_per_other_tick, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
640 struct converter *pcc ) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
641 { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
642 construct_converter( pcc, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
643 ns_per_other_tick, 1, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
644 resolution.divisor, resolution.dividend ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
645 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
646 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
647 // clocks to other is (ticks * divisor / dividend / ns_per) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
648 void Cyg_Clock::get_clock_to_other_converter( |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
649 cyg_uint64 ns_per_other_tick, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
650 struct converter *pcc ) |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
651 { |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
652 construct_converter( pcc, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
653 1, ns_per_other_tick, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
654 resolution.dividend, resolution.divisor ); |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
655 } |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
656 |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
34
diff
changeset
|
657 |
| 0 | 658 //========================================================================== |
| 659 // Constructor for alarm object | |
| 660 | |
| 661 Cyg_Alarm::Cyg_Alarm( | |
| 662 Cyg_Counter *c, // Attached to this counter | |
| 663 cyg_alarm_fn *a, // Call-back function | |
| 664 CYG_ADDRWORD d // Call-back data | |
| 665 ) | |
| 666 { | |
| 667 CYG_REPORT_FUNCTION(); | |
| 668 | |
| 669 counter = c; | |
| 670 alarm = a; | |
| 671 data = d; | |
| 672 trigger = 0; | |
| 673 interval = 0; | |
| 674 enabled = false; | |
| 675 | |
| 676 } | |
| 677 | |
| 678 Cyg_Alarm::Cyg_Alarm(){} | |
| 679 | |
| 680 // ------------------------------------------------------------------------- | |
| 681 // Destructor | |
| 682 | |
| 683 Cyg_Alarm::~Cyg_Alarm() | |
| 684 { | |
| 685 CYG_REPORT_FUNCTION(); | |
| 686 | |
| 687 disable(); | |
| 688 } | |
| 689 | |
| 690 // ------------------------------------------------------------------------- | |
| 691 // | |
| 692 | |
| 693 #ifdef CYGDBG_USE_ASSERTS | |
| 694 | |
|
78
59d97b6ba612
Merge from eCos master repository on 2000-03-28-19:50:47-BST
jlarmour
parents:
66
diff
changeset
|
695 cyg_bool Cyg_Alarm::check_this( cyg_assert_class_zeal zeal) const |
| 0 | 696 { |
| 697 // check that we have a non-NULL pointer first | |
| 698 if( this == NULL ) return false; | |
| 699 | |
| 700 switch( zeal ) | |
| 701 { | |
| 702 case cyg_system_test: | |
| 703 case cyg_extreme: | |
| 704 case cyg_thorough: | |
| 705 if( trigger != 0 && !enabled ) return false; | |
| 706 case cyg_quick: | |
| 707 case cyg_trivial: | |
| 708 case cyg_none: | |
| 709 default: | |
| 710 break; | |
| 711 }; | |
| 712 | |
| 713 return true; | |
| 714 } | |
| 715 | |
| 716 #endif | |
| 717 | |
| 718 // ------------------------------------------------------------------------- | |
| 719 // Initialize Alarm and enable | |
| 720 | |
| 721 void Cyg_Alarm::initialize( | |
| 722 cyg_tick_count t, // Absolute trigger time | |
| 723 cyg_tick_count i // Relative retrigger interval | |
| 724 ) | |
| 725 { | |
| 726 CYG_REPORT_FUNCTION(); | |
| 727 | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
728 Cyg_Scheduler::lock(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
729 |
| 0 | 730 // If already enabled, remove from counter |
| 731 | |
| 732 if( enabled ) counter->rem_alarm(this); | |
| 733 | |
| 734 CYG_INSTRUMENT_ALARM( INIT, this, 0 ); | |
| 735 CYG_INSTRUMENT_ALARM( TRIGGER, | |
| 736 ((cyg_uint32 *)&t)[0], | |
| 737 ((cyg_uint32 *)&t)[1] ); | |
| 738 CYG_INSTRUMENT_ALARM( INTERVAL, | |
| 739 ((cyg_uint32 *)&i)[0], | |
| 740 ((cyg_uint32 *)&i)[1] ); | |
| 741 | |
| 742 trigger = t; | |
| 743 interval = i; | |
| 744 | |
| 745 counter->add_alarm(this); | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
746 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
747 Cyg_Scheduler::unlock(); |
| 0 | 748 } |
| 749 | |
| 750 // ------------------------------------------------------------------------- | |
| 751 // Synchronize with a past alarm stream that had been disabled, | |
| 752 // bring past times into synch, and the like. | |
| 753 | |
| 754 void | |
| 755 Cyg_Alarm::synchronize( void ) | |
| 756 { | |
| 757 if( interval != 0 ) { | |
| 758 // This expression sets the trigger to the next whole interval | |
| 759 // at or after the current time. This means that alarms will | |
| 760 // continue at the same intervals as if they had never been | |
| 761 // disabled. The alternative would be to just set trigger to | |
| 762 // (counter->counter + interval), but this is less satisfying | |
| 763 // than preserving the original intervals. That behaviour can | |
| 764 // always be obtained by using initialize() rather than | |
| 765 // enable(), while the current behaviour would be more | |
| 766 // difficult to achieve that way. | |
| 767 cyg_tick_count d; | |
| 768 d = counter->current_value() + interval - trigger; | |
| 769 if ( d > interval ) { | |
| 770 // then trigger was in the past, so resynchronize | |
| 771 trigger += interval * ((d - 1) / interval ); | |
| 772 } | |
| 773 // otherwise, we were just set up, so no worries. | |
| 774 } | |
| 775 } | |
| 776 | |
| 777 // ------------------------------------------------------------------------- | |
| 778 // Ensure alarm enabled | |
| 779 | |
| 780 void Cyg_Alarm::enable() | |
| 781 { | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
782 Cyg_Scheduler::lock(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
783 |
| 0 | 784 if( !enabled ) |
| 785 { | |
| 786 // ensure the alarm time is in our future: | |
| 787 synchronize(); | |
| 788 enabled = true; | |
| 789 counter->add_alarm(this); | |
| 790 } | |
|
1088
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
791 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
792 Cyg_Scheduler::unlock(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
793 } |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
794 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
795 // ------------------------------------------------------------------------- |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
796 // Ensure alarm disabled |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
797 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
798 void Cyg_Alarm::disable() |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
799 { |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
800 Cyg_Scheduler::lock(); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
801 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
802 if( enabled ) counter->rem_alarm(this); |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
803 |
|
4c13726203c5
* include/clock.hxx: Made Cyg_Counter::add_alarm() and
nickg
parents:
1077
diff
changeset
|
804 Cyg_Scheduler::unlock(); |
| 0 | 805 } |
| 806 | |
|
115
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
807 // ------------------------------------------------------------------------- |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
808 // Get the current time values from the alarm |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
809 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
810 void Cyg_Alarm::get_times( |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
811 cyg_tick_count *t, // Next trigger time |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
812 cyg_tick_count *i // Current interval |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
813 ) |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
814 { |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
815 // Lock the scheduler while we do this to avoid |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
816 // race conditions. |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
817 Cyg_Scheduler::lock(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
818 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
819 if( t != NULL ) *t = trigger; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
820 if( i != NULL ) *i = interval; |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
821 |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
822 Cyg_Scheduler::unlock(); |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
823 } |
|
6ed91473a1cd
Merge from eCos master repository on 2000-08-21-22:40:54-BST
jlarmour
parents:
78
diff
changeset
|
824 |
| 0 | 825 //========================================================================== |
| 826 // System clock object | |
| 827 | |
| 828 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK | |
| 829 | |
| 830 class Cyg_RealTimeClock | |
| 831 : public Cyg_Clock | |
| 832 { | |
| 833 Cyg_Interrupt interrupt; | |
| 834 | |
| 835 static cyg_uint32 isr(cyg_vector vector, CYG_ADDRWORD data); | |
| 836 | |
| 837 static void dsr(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data); | |
| 838 | |
| 839 Cyg_RealTimeClock(); | |
| 840 | |
| 841 static Cyg_RealTimeClock rtc; | |
| 842 }; | |
| 843 | |
| 844 Cyg_Clock::cyg_resolution rtc_resolution = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION; | |
| 845 | |
| 846 //Cyg_RealTimeClock Cyg_RealTimeClock::rtc __attribute__((init_priority (1))); | |
| 847 | |
| 848 Cyg_RealTimeClock Cyg_RealTimeClock::rtc CYG_INIT_PRIORITY( CLOCK ); | |
| 849 | |
| 850 // ------------------------------------------------------------------------- | |
| 851 | |
| 852 Cyg_RealTimeClock::Cyg_RealTimeClock() | |
| 853 : Cyg_Clock(rtc_resolution), | |
| 2 | 854 interrupt(CYGNUM_HAL_INTERRUPT_RTC, 1, (CYG_ADDRWORD)this, isr, dsr) |
| 0 | 855 { |
| 856 CYG_REPORT_FUNCTION(); | |
| 857 | |
| 858 HAL_CLOCK_INITIALIZE( CYGNUM_KERNEL_COUNTERS_RTC_PERIOD ); | |
| 859 | |
| 860 interrupt.attach(); | |
| 861 | |
| 2 | 862 interrupt.unmask_interrupt(CYGNUM_HAL_INTERRUPT_RTC); |
| 0 | 863 |
| 864 Cyg_Clock::real_time_clock = this; | |
| 865 } | |
| 866 | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
867 #if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY) |
| 2 | 868 cyg_tick_count total_clock_latency, total_clock_interrupts; |
| 869 cyg_int32 min_clock_latency = 0x7FFFFFFF; | |
| 870 cyg_int32 max_clock_latency = 0; | |
| 871 bool measure_clock_latency = false; | |
| 872 #endif | |
| 873 | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
874 #if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
875 cyg_tick_count total_clock_dsr_latency, total_clock_dsr_calls; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
876 cyg_int32 min_clock_dsr_latency = 0x7FFFFFFF; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
877 cyg_int32 max_clock_dsr_latency = 0; |
|
66
bf00f99aec69
Merge from eCos master repository on 2000-02-02-19:16:44-GMT
jlarmour
parents:
64
diff
changeset
|
878 cyg_uint32 clock_dsr_start = 0; |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
879 #endif |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
880 |
| 0 | 881 // ------------------------------------------------------------------------- |
| 882 | |
| 883 cyg_uint32 Cyg_RealTimeClock::isr(cyg_vector vector, CYG_ADDRWORD data) | |
| 884 { | |
| 885 // CYG_REPORT_FUNCTION(); | |
| 886 | |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
887 #if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && defined(HAL_CLOCK_LATENCY) |
| 2 | 888 if (measure_clock_latency) { |
| 889 cyg_int32 delta; | |
| 890 HAL_CLOCK_LATENCY(&delta); | |
| 891 // Note: Ignore a latency of 0 when finding min_clock_latency. | |
| 892 if (delta > 0) { | |
| 893 // Valid delta measured | |
| 894 total_clock_latency += delta; | |
| 895 total_clock_interrupts++; | |
| 896 if (min_clock_latency > delta) min_clock_latency = delta; | |
| 897 if (max_clock_latency < delta) max_clock_latency = delta; | |
| 898 } | |
| 899 } | |
| 900 #endif | |
| 901 | |
| 0 | 902 CYG_INSTRUMENT_CLOCK( ISR, 0, 0); |
| 903 | |
| 2 | 904 HAL_CLOCK_RESET( CYGNUM_HAL_INTERRUPT_RTC, CYGNUM_KERNEL_COUNTERS_RTC_PERIOD ); |
| 0 | 905 |
| 2 | 906 Cyg_Interrupt::acknowledge_interrupt(CYGNUM_HAL_INTERRUPT_RTC); |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
907 |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
908 #if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
909 HAL_CLOCK_READ(&clock_dsr_start); |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
910 #endif |
|
18
7253dcc42a09
Merge from eCos master repository on 1999-06-25-15:31:50-BST
jlarmour
parents:
2
diff
changeset
|
911 return Cyg_Interrupt::CALL_DSR|Cyg_Interrupt::HANDLED; |
| 0 | 912 } |
| 913 | |
| 914 // ------------------------------------------------------------------------- | |
| 915 | |
| 916 void Cyg_RealTimeClock::dsr(cyg_vector vector, cyg_ucount32 count, CYG_ADDRWORD data) | |
| 917 { | |
| 918 // CYG_REPORT_FUNCTION(); | |
| 919 | |
|
210
d2c90368aeef
Merge from eCos master repository on 2002-05-23-21:39:14-BST
jlarmour
parents:
208
diff
changeset
|
920 #if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_DSR_LATENCY) && defined(HAL_CLOCK_LATENCY) |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
921 if (measure_clock_latency) { |
|
174
38892b97b685
Merge from eCos master repository on 2001-07-28-00:17:32-BST
jlarmour
parents:
151
diff
changeset
|
922 cyg_int32 delta; |
|
38892b97b685
Merge from eCos master repository on 2001-07-28-00:17:32-BST
jlarmour
parents:
151
diff
changeset
|
923 HAL_CLOCK_READ((cyg_uint32 *)&delta); |
|
34
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
924 delta -= clock_dsr_start; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
925 // Note: Ignore a latency of <= 0 when finding min_clock_latency. |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
926 if (delta > 0 ) { |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
927 // Valid delta measured |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
928 total_clock_dsr_latency += delta; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
929 total_clock_dsr_calls++; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
930 if (min_clock_dsr_latency > delta) min_clock_dsr_latency = delta; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
931 if (max_clock_dsr_latency < delta) max_clock_dsr_latency = delta; |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
932 } |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
933 } |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
934 #endif |
|
29bc183297e1
Merge from eCos master repository on 1999-09-02-16:26:10-BST
jlarmour
parents:
18
diff
changeset
|
935 |
| 0 | 936 Cyg_RealTimeClock *rtc = (Cyg_RealTimeClock *)data; |
| 937 | |
| 938 CYG_INSTRUMENT_CLOCK( TICK_START, | |
| 939 rtc->current_value_lo(), | |
| 940 rtc->current_value_hi()); | |
| 941 | |
| 942 rtc->tick( count ); | |
| 943 | |
| 944 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE | |
|
132
0ae0bc38e387
Merge from eCos master repository on 2000-10-31-00:30:36-GMT
jlarmour
parents:
115
diff
changeset
|
945 #if 0 == CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES |
| 0 | 946 |
| 947 // If timeslicing is enabled, call the scheduler to | |
| 948 // handle it. But not if we have unique priorities. | |
| 949 | |
| 950 Cyg_Scheduler::scheduler.timeslice(); | |
| 951 | |
| 952 #endif | |
| 953 #endif | |
| 954 | |
| 955 CYG_INSTRUMENT_CLOCK( TICK_END, | |
| 956 rtc->current_value_lo(), | |
| 957 rtc->current_value_hi()); | |
| 958 | |
| 959 } | |
| 960 | |
| 961 #endif | |
| 962 | |
| 963 // ------------------------------------------------------------------------- | |
| 964 // EOF common/clock.cxx |
