3434#include <rthw.h>
3535
3636/* hard timer list */
37- static rt_list_t rt_timer_list = RT_LIST_OBJECT_INIT ( rt_timer_list ) ;
37+ static rt_list_t rt_timer_list [ RT_TIMER_SKIP_LIST_LEVEL ] ;
3838
3939#ifdef RT_USING_TIMER_SOFT
4040#ifndef RT_TIMER_THREAD_STACK_SIZE
@@ -46,7 +46,7 @@ static rt_list_t rt_timer_list = RT_LIST_OBJECT_INIT(rt_timer_list);
4646#endif
4747
4848/* soft timer list */
49- static rt_list_t rt_soft_timer_list ;
49+ static rt_list_t rt_soft_timer_list [ RT_TIMER_SKIP_LIST_LEVEL ] ;
5050static struct rt_thread timer_thread ;
5151ALIGN (RT_ALIGN_SIZE )
5252static rt_uint8_t timer_thread_stack [RT_TIMER_THREAD_STACK_SIZE ];
@@ -83,6 +83,8 @@ static void _rt_timer_init(rt_timer_t timer,
8383 rt_tick_t time ,
8484 rt_uint8_t flag )
8585{
86+ int i ;
87+
8688 /* set flag */
8789 timer -> parent .flag = flag ;
8890
@@ -96,21 +98,64 @@ static void _rt_timer_init(rt_timer_t timer,
9698 timer -> init_tick = time ;
9799
98100 /* initialize timer list */
99- rt_list_init (& (timer -> list ));
101+ for (i = 0 ; i < RT_TIMER_SKIP_LIST_LEVEL ; i ++ )
102+ {
103+ rt_list_init (& (timer -> row [i ]));
104+ }
100105}
101106
102- static rt_tick_t rt_timer_list_next_timeout (rt_list_t * timer_list )
107+ /* the fist timer always in the last row */
108+ static rt_tick_t rt_timer_list_next_timeout (rt_list_t timer_list [])
103109{
104110 struct rt_timer * timer ;
105111
106- if (rt_list_isempty (timer_list ))
112+ if (rt_list_isempty (& timer_list [ RT_TIMER_SKIP_LIST_LEVEL - 1 ] ))
107113 return RT_TICK_MAX ;
108114
109- timer = rt_list_entry (timer_list -> next , struct rt_timer , list );
115+ timer = rt_list_entry (timer_list [RT_TIMER_SKIP_LIST_LEVEL - 1 ].next ,
116+ struct rt_timer , row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]);
110117
111118 return timer -> timeout_tick ;
112119}
113120
121+ rt_inline void _rt_timer_remove (rt_timer_t timer )
122+ {
123+ int i ;
124+
125+ for (i = 0 ; i < RT_TIMER_SKIP_LIST_LEVEL ; i ++ )
126+ {
127+ rt_list_remove (& timer -> row [i ]);
128+ }
129+ }
130+
131+ static int rt_timer_count_height (struct rt_timer * timer )
132+ {
133+ int i , cnt = 0 ;
134+
135+ for (i = 0 ; i < RT_TIMER_SKIP_LIST_LEVEL ; i ++ )
136+ {
137+ if (!rt_list_isempty (& timer -> row [i ]))
138+ cnt ++ ;
139+ }
140+ return cnt ;
141+ }
142+
143+ static void rt_timer_dump (rt_list_t timer_heads [])
144+ {
145+ rt_list_t * list ;
146+
147+ for (list = timer_heads [RT_TIMER_SKIP_LIST_LEVEL - 1 ].next ;
148+ list != & timer_heads [RT_TIMER_SKIP_LIST_LEVEL - 1 ];
149+ list = list -> next )
150+ {
151+ struct rt_timer * timer = rt_list_entry (list ,
152+ struct rt_timer ,
153+ row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]);
154+ rt_kprintf ("%d" , rt_timer_count_height (timer ));
155+ }
156+ rt_kprintf ("\n" );
157+ }
158+
114159/**
115160 * @addtogroup Clock
116161 */
@@ -162,8 +207,7 @@ rt_err_t rt_timer_detach(rt_timer_t timer)
162207 /* disable interrupt */
163208 level = rt_hw_interrupt_disable ();
164209
165- /* remove it from timer list */
166- rt_list_remove (& (timer -> list ));
210+ _rt_timer_remove (timer );
167211
168212 /* enable interrupt */
169213 rt_hw_interrupt_enable (level );
@@ -224,8 +268,7 @@ rt_err_t rt_timer_delete(rt_timer_t timer)
224268 /* disable interrupt */
225269 level = rt_hw_interrupt_disable ();
226270
227- /* remove it from timer list */
228- rt_list_remove (& (timer -> list ));
271+ _rt_timer_remove (timer );
229272
230273 /* enable interrupt */
231274 rt_hw_interrupt_enable (level );
@@ -246,9 +289,14 @@ RTM_EXPORT(rt_timer_delete);
246289 */
247290rt_err_t rt_timer_start (rt_timer_t timer )
248291{
292+ int row_lvl ;
249293 struct rt_timer * t ;
294+ rt_list_t * timer_list ;
250295 register rt_base_t level ;
251- rt_list_t * n , * timer_list ;
296+ rt_list_t * row_head [RT_TIMER_SKIP_LIST_LEVEL ];
297+ rt_list_t * row_head_li ;
298+ static unsigned int random_nr ;
299+ unsigned int tst_nr ;
252300
253301 /* timer check */
254302 RT_ASSERT (timer != RT_NULL );
@@ -271,39 +319,62 @@ rt_err_t rt_timer_start(rt_timer_t timer)
271319 if (timer -> parent .flag & RT_TIMER_FLAG_SOFT_TIMER )
272320 {
273321 /* insert timer to soft timer list */
274- timer_list = & rt_soft_timer_list ;
322+ timer_list = rt_soft_timer_list ;
275323 }
276324 else
277325#endif
278326 {
279327 /* insert timer to system timer list */
280- timer_list = & rt_timer_list ;
328+ timer_list = rt_timer_list ;
281329 }
282330
283- for (n = timer_list -> next ; n != timer_list ; n = n -> next )
331+ row_head_li = timer_list ;
332+ for (row_lvl = 0 ; row_lvl < RT_TIMER_SKIP_LIST_LEVEL ; row_lvl ++ )
284333 {
285- t = rt_list_entry (n , struct rt_timer , list );
286-
287- /*
288- * It supposes that the new tick shall less than the half duration of
289- * tick max. And if we have two timers that timeout at the same time,
290- * it's prefered that the timer inserted early get called early.
291- */
292- if ((t -> timeout_tick - timer -> timeout_tick ) == 0 )
293- {
294- rt_list_insert_after (n , & (timer -> list ));
295- break ;
296- }
297- else if ((t -> timeout_tick - timer -> timeout_tick ) < RT_TICK_MAX / 2 )
334+ for (row_head [row_lvl ] = row_head_li [row_lvl ].next ;
335+ row_head [row_lvl ] != timer_list [row_lvl ].prev ;
336+ row_head [row_lvl ] = row_head [row_lvl ]-> next )
298337 {
299- rt_list_insert_before (n , & (timer -> list ));
300- break ;
338+ rt_list_t * p = row_head [row_lvl ]-> next ;
339+ /* fix up the entry pointer */
340+ t = rt_list_entry (p , struct rt_timer , row [row_lvl ]);
341+
342+ /* If we have two timers that timeout at the same time, it's
343+ * preferred that the timer inserted early get called early.
344+ * So insert the new timer to the end the the some-timeout timer
345+ * list.
346+ */
347+ if ((t -> timeout_tick - timer -> timeout_tick ) == 0 )
348+ {
349+ continue ;
350+ }
351+ else if ((t -> timeout_tick - timer -> timeout_tick ) < RT_TICK_MAX / 2 )
352+ {
353+ row_head_li = row_head [row_lvl ]- row_lvl ;
354+ break ;
355+ }
301356 }
302357 }
303- /* no found suitable position in timer list */
304- if (n == timer_list )
358+
359+ /* Interestingly, this super simple timer insert counter works very very
360+ * well on distributing the list height uniformly. By means of "very very
361+ * well", I mean it beats the randomness of timer->timeout_tick very easily
362+ * (actually, the timeout_tick is not random and easy to be attacked). */
363+ random_nr ++ ;
364+ tst_nr = random_nr ;
365+
366+ rt_list_insert_after (row_head [RT_TIMER_SKIP_LIST_LEVEL - 1 ],
367+ & (timer -> row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]));
368+ for (row_lvl = 2 ; row_lvl <= RT_TIMER_SKIP_LIST_LEVEL ; row_lvl ++ )
305369 {
306- rt_list_insert_before (n , & (timer -> list ));
370+ if (!(tst_nr & RT_TIMER_SKIP_LIST_MASK ))
371+ rt_list_insert_after (row_head [RT_TIMER_SKIP_LIST_LEVEL - row_lvl ],
372+ & (timer -> row [RT_TIMER_SKIP_LIST_LEVEL - row_lvl ]));
373+ else
374+ break ;
375+ /* Shift over the bits we have tested. Works well with 1 bit and 2
376+ * bits. */
377+ tst_nr >>= (RT_TIMER_SKIP_LIST_MASK + 1 )>>1 ;
307378 }
308379
309380 timer -> parent .flag |= RT_TIMER_FLAG_ACTIVATED ;
@@ -349,8 +420,7 @@ rt_err_t rt_timer_stop(rt_timer_t timer)
349420 /* disable interrupt */
350421 level = rt_hw_interrupt_disable ();
351422
352- /* remove it from timer list */
353- rt_list_remove (& (timer -> list ));
423+ _rt_timer_remove (timer );
354424
355425 /* enable interrupt */
356426 rt_hw_interrupt_enable (level );
@@ -410,6 +480,7 @@ void rt_timer_check(void)
410480 struct rt_timer * t ;
411481 rt_tick_t current_tick ;
412482 register rt_base_t level ;
483+ /*int dumped = 0;*/
413484
414485 RT_DEBUG_LOG (RT_DEBUG_TIMER , ("timer check enter\n" ));
415486
@@ -418,20 +489,30 @@ void rt_timer_check(void)
418489 /* disable interrupt */
419490 level = rt_hw_interrupt_disable ();
420491
421- while (!rt_list_isempty (& rt_timer_list ))
492+ while (!rt_list_isempty (& rt_timer_list [ RT_TIMER_SKIP_LIST_LEVEL - 1 ] ))
422493 {
423- t = rt_list_entry (rt_timer_list .next , struct rt_timer , list );
494+ t = rt_list_entry (rt_timer_list [RT_TIMER_SKIP_LIST_LEVEL - 1 ].next ,
495+ struct rt_timer , row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]);
424496
425497 /*
426498 * It supposes that the new tick shall less than the half duration of
427499 * tick max.
428500 */
429501 if ((current_tick - t -> timeout_tick ) < RT_TICK_MAX /2 )
430502 {
503+ /*
504+ *if (!dumped)
505+ *{
506+ * dumped = 1;
507+ * [>rt_kprintf("%s:\n", __FUNCTION__);<]
508+ * rt_timer_dump(rt_timer_list);
509+ *}
510+ */
511+
431512 RT_OBJECT_HOOK_CALL (rt_timer_timeout_hook , (t ));
432513
433514 /* remove timer from timer list firstly */
434- rt_list_remove ( & ( t -> list ) );
515+ _rt_timer_remove ( t );
435516
436517 /* call timeout function */
437518 t -> timeout_func (t -> parameter );
@@ -471,7 +552,7 @@ void rt_timer_check(void)
471552 */
472553rt_tick_t rt_timer_next_timeout_tick (void )
473554{
474- return rt_timer_list_next_timeout (& rt_timer_list );
555+ return rt_timer_list_next_timeout (rt_timer_list );
475556}
476557
477558#ifdef RT_USING_TIMER_SOFT
@@ -489,9 +570,10 @@ void rt_soft_timer_check(void)
489570
490571 current_tick = rt_tick_get ();
491572
492- for (n = rt_soft_timer_list .next ; n != & (rt_soft_timer_list );)
573+ for (n = rt_soft_timer_list [RT_TIMER_SKIP_LIST_LEVEL - 1 ].next ;
574+ n != & (rt_soft_timer_list [RT_TIMER_SKIP_LIST_LEVEL - 1 ]);)
493575 {
494- t = rt_list_entry (n , struct rt_timer , list );
576+ t = rt_list_entry (n , struct rt_timer , row [ RT_TIMER_SKIP_LIST_LEVEL - 1 ] );
495577
496578 /*
497579 * It supposes that the new tick shall less than the half duration of
@@ -505,7 +587,7 @@ void rt_soft_timer_check(void)
505587 n = n -> next ;
506588
507589 /* remove timer from timer list firstly */
508- rt_list_remove ( & ( t -> list ) );
590+ _rt_timer_remove ( timer );
509591
510592 /* call timeout function */
511593 t -> timeout_func (t -> parameter );
@@ -542,7 +624,7 @@ static void rt_thread_timer_entry(void *parameter)
542624 while (1 )
543625 {
544626 /* get the next timeout tick */
545- next_timeout = rt_timer_list_next_timeout (& rt_soft_timer_list );
627+ next_timeout = rt_timer_list_next_timeout (rt_soft_timer_list );
546628 if (next_timeout == RT_TICK_MAX )
547629 {
548630 /* no software timer exist, suspend self. */
@@ -584,6 +666,12 @@ static void rt_thread_timer_entry(void *parameter)
584666 */
585667void rt_system_timer_init (void )
586668{
669+ int i ;
670+
671+ for (i = 0 ; i < sizeof (rt_timer_list )/sizeof (rt_timer_list [0 ]); i ++ )
672+ {
673+ rt_list_init (rt_timer_list + i );
674+ }
587675}
588676
589677/**
@@ -594,7 +682,14 @@ void rt_system_timer_init(void)
594682void rt_system_timer_thread_init (void )
595683{
596684#ifdef RT_USING_TIMER_SOFT
597- rt_list_init (& rt_soft_timer_list );
685+ int i ;
686+
687+ for (i = 0 ;
688+ i < sizeof (rt_soft_timer_list )/sizeof (rt_soft_timer_list [0 ]);
689+ i ++ )
690+ {
691+ rt_list_init (rt_soft_timer_list + i );
692+ }
598693
599694 /* start software timer thread */
600695 rt_thread_init (& timer_thread ,
0 commit comments