|
Smart Timing Mechanism
# {3 ^* ^. W9 v0 `. \ V 0 }& d$ T p- z& F
1. Why need this mechanism?' f' L- ]/ N) {% s
0 n' A6 U! z/ }3 F3 T! O5 O2 T# r 最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
" K+ a+ X) |. }: S/ n: A2 x3 p1 ^4 }# {0 b3 z0 H0 t3 A2 u
2. How to improve it?4 c& {. V0 i* y. j! r( I- Z
- f% p( ^! ~7 F8 G! M+ v1 l) k 既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)。搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code:
6 [8 @7 c0 w( U+ A/ e, s/ N+ _, ^ d/ ~' H9 \$ C0 W
//header file
9 G1 R: c( J' d% k" G/ z/////////////////////////////////////////////////9 S$ T3 Q- ~! O5 e# b! O$ {
#ifndef" X% P) f9 F3 {' n, k7 i2 [
OEM_TIMER_SERVICE__H1 @8 M6 V* i6 F$ ~
#define; g: v5 S! I' d6 S1 \6 Z, F# J
OEM_TIMER_SERVIEC__H$ [, \( R, J P+ J7 p3 D3 n7 y
" |0 o- a4 w: K, ^: X' j- {
/ T0 u+ N8 U& i9 h% Svoid add_timer(unsigned short
1 W) ~1 e" { y$ P0 D u0 ]jiffies,void (*callback)());
! z; h2 `4 C9 l/ p- ^& F5 g0 L: e) x2 `4 z
void do_timer(void);
) N9 E X. J: {& e: \- ^* h2 `; i+ y r6 [6 H0 A' @( K
#endif% A$ }9 Z9 d! l4 N: }
/////////////////////////////////////////////////) C3 P- ~" A& @3 x: O5 C* [9 C
/////////////////////////////////////////////////$ B; \; @4 z+ e7 l) _% O
//impl file
, a: j+ I5 C3 q6 z$ \! i#include <stdio.h>1 J0 b8 O9 C: S
#include "OEMTimerService.H"
0 h( L, C: n2 {8 i% U8 L0 q. r' B) J0 j1 U' A% D
$ r6 z' v6 P( ?: J2 |( E
#define6 W/ p) d( j+ E4 n' | S2 u" k
TIMER_REQUESTS; R5 U+ T* v8 P U, o7 y4 D: l
0x30
4 y& p4 i% J4 }6 ^6 G. h! n+ A! c7 ?+ v+ j
struct timer_list ' T- D# y! [: J' d
{
9 d- h- l" Q7 U" V5 `2 w8 L& J, a: c1 S3 k4 s$ u4 E$ W
struct timer_list *next; 4 p3 r: W O/ w) v
+ Q+ z% i7 F2 Z* y2 y7 k6 m, q7 O
unsigned short jiffies;; I _' R! `6 T; y
& G& t! G9 k$ ]void (*callback)(void);
! U P8 F! w! u0 H0 z3 E) V6 F) `& h};# H) @( q% O; j& L+ A/ X6 @
8 O" u5 h1 r, \# S$ j
7 x: [4 P5 i, c+ f# b" O tstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};5 s. f; z: I1 z. K1 `9 @2 W9 H A c
1 Q' O B1 x# Z( t4 }struct timer_list *timer_header = NULL;2 \2 C9 S+ L# D+ R
: r7 O& z# X, o9 ~0 G
. K3 v- c" q0 \0 x- ~9 M+ K
void add_timer(unsigned short
/ P4 P- k8 q7 I, x! q0 A- ?jiffies,void (*callback)())
3 ~, `1 z) j( p- p- W" A{
3 Z8 f' ~9 U p- o/ q' n! E: h- r* {. t7 R( B0 F
struct timer_list *ptmp;6 Q# O# K2 w; |: ?
) ^2 r D( u1 C3 z
2 s5 n/ e" A4 ]if(!callback)0 `% a+ B! Q$ H, H0 `! u4 O. r
* k9 a. B2 f5 ~5 m, h/ b3 [( q
return ;6 e: `; X5 ^; q2 p
5 s" n6 \; ~+ a5 F8 k5 @4 q1 T1 l
- K0 j, H2 E& F: B: ]; o y ^; E$ o: {) y
EA = 0;, L: o3 C2 g% m5 H# y* s+ s
B: c& w) Z5 B
" y* }* M: Q4 V* R- H1 Kif(jiffies <= 0)
. z" k; ^; {- J- k6 g% B$ A5 s! U& u9 _- Y' k8 g1 ?/ V7 Q
(*callback)();: m a% v1 A) U/ L F
/ U8 a( q6 J8 @$ e6 M/ S+ k) Q, p* u- i# W6 U( e2 H
: \( s: J. ? y' {3 f Xfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
1 o- I4 ^4 b1 T: C* i
" B1 D* X! h. }- j5 Oif(ptmp->callback == NULL)
& G: _9 ~- r! _) _* G+ H& h4 C: g: t/ X0 U8 [2 J2 V: R. @
break;
7 V) M4 y- B4 O% m, ^& s9 S
$ {8 f: v3 ]/ Q W% z/ O i: @* c$ A8 O# u
) Y$ v" L$ H0 { J/ \$ p- O H/ Eif(ptmp >= timer_list + TIMER_REQUESTS)" e5 k ^9 c; F# z
: k2 K+ S5 |5 u$ a& t- _0 W: H
{9 {4 q f% d1 j% J0 C' L
5 u% ?$ ^7 v7 ]2 y0 m6 e$ Q
goto EXIT;
' G3 y5 m/ K, v# A) Q0 {; q @ C5 ?( t% f
} ! r7 |, u% r$ Q T/ b) A) D& G
" q2 ]! Q- Q( v8 c- q
, I1 O+ {! l0 P6 vptmp->jiffies = jiffies;: a, n. V: S& N# j2 @& x
% Y' [' B" h8 c( E2 G9 U! Sptmp->callback = callback;
% ^( z% q, P3 s, ?# }, M1 u2 G0 n8 Z! c& B. O
- l2 t- s$ n4 T+ @7 ~- z; x
; G' |* s9 Z3 L( P
ptmp->next = timer_header;5 L: p; u! N3 b2 F; A p: ^; f
' j( x) ?: H/ G
timer_header = ptmp;
) W6 O0 t s' y0 E. F# g
8 Y) I# U& X$ w( ]6 K
* `! `; Z4 F$ f//add bellow code to fix linux on timer’s bugs ++
2 w3 r W! @/ x; `) {1 u9 [9 C6 u" r8 j L. k. T+ O. F1 P+ ^5 h
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
6 w4 p" |1 w5 M+ r( T
/ H6 I& _+ r& T: r{
, u5 I* Y+ j5 Q, b5 p4 G& I" S( ], l+ T0 O, ]. x3 i) n, V
ptmp->next->jiffies -= ptmp->jiffies;+ j- ~! W! Q& X/ \
' W8 g; \# z! S: L8 B, d
}//end +++ m3 P* { g4 T7 q$ V' K9 U
3 m0 _8 u' E# ]+ j' e, Uelse
7 r0 [- V, p+ n |. j
* i o7 p: _! N0 m. c{( N% I2 E. s, S7 r: Z
0 Y' p9 ?4 a- b
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies)) N* F' @" J: Y9 P
+ r4 W# P0 {- }. v! Q ?' l5 q4 t4 D: `+ K0 C
{2 }; ~# H2 I a# f. Y: T# J
1 p9 P1 b ^( W4 V
ptmp->jiffies -= ptmp->next->jiffies;: s5 M5 k9 N: B# J _ P" D0 K8 h5 J9 D
5 ]' \1 N. W! ]( R: @4 y6 P6 B
callback = ptmp->callback;
' _5 Q* @* c" j# m2 c0 O3 b* L, U4 B" P0 L+ a# f
ptmp->callback = ptmp->next->callback;! k' |7 W* |. P' ?# V) p
\2 e9 d9 o3 {7 d) }. J- S j A6 l
ptmp->next->callback = callback;
5 \3 S' ~" p- V; U& U/ ~, w9 l& ~
: Z- Q/ v. ]+ djiffies = ptmp->jiffies;
& |* T" E- N$ ^' e; I) {4 ~% D+ `# n' ^
ptmp->jiffies = ptmp->next->jiffies;
4 S. A% }, u; W. u* ~7 Y f5 A+ b$ e1 i# E
ptmp->next->jiffies = jiffies;
- I3 r* r0 [" b( q e) Q1 b: i2 w" V$ z3 ] X/ V2 b* m! G/ N3 f4 R
ptmp = ptmp->next;% p: k4 ~) a$ q" p9 h5 C
9 G0 `! W5 i1 d8 q0 c- j
}
- O) m) q" B9 k4 R d0 a
+ c) T$ ?( j8 d2 i, v}) o$ X% K7 Y3 w6 {8 q3 ]
8 u% x, j0 ]% q [* x7 K6 G z% [0 eEXIT:# a" ^/ D5 ?& c6 P. J! P2 B& K
s: e" x# f8 u8 {, a/ ~7 F
EA = 1;
1 Y" V: Y8 C9 ?: f3 q3 y5 q, Q: U. p. z- J6 o
return;
; n; B1 \; R- s" @2 ]3 e" u}! o" g: r, ], N/ ^
' D' K6 O" L4 q9 J' Y lvoid do_timer(void)
; v1 b) d. {' U* v+ j{$ e7 i9 J x6 a9 ~7 f) ]
) u6 |6 k! b6 L0 b) B3 f: n( g
* @# O: h2 t' u [5 n7 v# f
while((timer_header != NULL)9 b6 M; h6 u# P. ]5 O
9 {* N2 E9 d: X3 W8 \ }: N; s8 e9 i2 y D. n% @4 p7 M3 r, P
&&(timer_header->callback != NULL)2 C$ _9 T, b' W
^4 c) j+ Q; z/ k; K$ G; e3 ]
2 X% m- ~3 E$ n+ x# C8 V+ ?" F&&(--timer_header->jiffies <= 0))! y* E3 a2 E, a" {0 `1 }3 f
/ {# r6 A* I1 Z
{
+ G: h' @5 F% g. P
# \. o" }* M Y6 y: ?1 evoid (*callback_fptr)(void);
% C% f/ [+ P! x! w7 N- u# M; T% \7 d1 Z' i, F* U
, q/ L" N$ N: D* N1 Tcallback_fptr = timer_header->callback;
$ ~. ^8 [) |! ^, X$ J. y5 a4 x# ]/ K* q: ?' W8 y
timer_header->callback = NULL;
; u1 i$ c2 ^6 P. d; }) f& B$ N0 f9 t4 ^; O
timer_header = timer_header->next;$ A# ]4 |5 n% }
$ H+ l9 e# S, ?% ^! T
(*callback_fptr)();
8 z( _1 \; C& ^1 l8 Y4 K4 i& ]) W8 X& z+ U7 ?' j4 t4 X
}
! p3 W" L$ [8 y8 ?' \6 s% ?7 B W' Y
2 i9 t0 v6 T6 e! Y8 [
}
& r1 O! ^7 Q, s7 |$ K///////////////////////////////////////////////////
( P6 P! |; d* S+ t! F- L) [) q- U! y& J+ B. s% f8 |
) Y* V0 ~/ \ Z6 [3 x$ o; M上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!# p0 J) x: m) S
" y. J, F- n5 }
野人献曝,博君一笑
! l2 }' J/ Q# b. r0 c9 E/ n3 Z, w/ w
: e" l0 o+ n) MPeter
' r: Z/ l9 M' C0 `0 ~$ i- r1 ?
, c. B% p* v# {) r; G* k
( N% ]( f8 i% N/ d$ B: o[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ] |
|