Mercurial > flash_v2
annotate packages/kernel/current/src/common/clock.cxx @ 1099:9ab0a182923a
* src/common/clock.cxx (Cyg_Counter::tick): In unsorted list case:
moved saving of next node details to before re-insertion of alarms
with intervals. The call to add_alarm() can make enough of a
difference to the list to need to force a rescan.
| author | nickg |
|---|---|
| date | Thu, 10 Jul 2003 17:41:07 +0000 |
| parents | 4c13726203c5 |
| children | cfe2937847da |
| 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 |
|
1099
9ab0a182923a
* src/common/clock.cxx (Cyg_Counter::tick): In unsorted list case:
nickg
parents:
1088
diff
changeset
|
238 // Save some details of the list state so we can |
|
9ab0a182923a
* src/common/clock.cxx (Cyg_Counter::tick): In unsorted list case:
nickg
parents:
1088
diff
changeset
|
239 // detect if it has changed. |
|
9ab0a182923a
* src/common/clock.cxx (Cyg_Counter::tick): In unsorted list case:
nickg
parents:
1088
diff
changeset
|
240 next_next = next->get_next(); |
|
9ab0a182923a
* src/common/clock.cxx (Cyg_Counter::tick): In unsorted list case:
nickg
parents:
1088
diff
changeset
|
241 next_prev = next->get_prev(); |
|
9ab0a182923a
* src/common/clock.cxx (Cyg_Counter::tick): In unsorted list case:
nickg
parents:
1088
diff
changeset
|
242 head = alarm_list_ptr->get_head(); |
|
9ab0a182923a
* src/common/clock.cxx (Cyg_Counter::tick): In unsorted list case:
nickg
parents:
1088
diff
changeset
|
243 |
| 2 | 244 if( alarm->interval != 0 ) |
| 245 { | |
| 246 // The alarm has a retrigger interval. | |
| 247 // Reset the trigger time and requeue | |
| 248 // the alarm. | |
| 249 alarm->trigger += alarm->interval; | |
| 250 add_alarm( alarm ); | |
| 251 } | |
| 252 else alarm->enabled = false; | |
| 253 | |
| 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 |
