|
Smart Timing Mechanism
. |. s: d* L9 x $ ~/ t* ?2 s2 m: V% S* u+ a
1. Why need this mechanism?, t" y) l0 Z$ z" P! B
; V2 X, Q2 ~( X! `' `. C 最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
( X# B* @1 X4 m+ C# l' l4 C: }; L* Z7 q
2. How to improve it?& \1 y, p# s0 h( J2 A
1 i9 A+ _" I7 d$ j/ v 既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)。搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code:
2 z3 n7 a% d% T& @
8 \7 {& f: `( w% H) Q- B//header file
( D: |. x8 ~1 G% r" Q l/////////////////////////////////////////////////) b& W0 o& N3 U: U+ L
#ifndef
! |! ]( F( b9 s! B' UOEM_TIMER_SERVICE__H
$ J7 s9 ?; D: Q. i2 a" ^#define
& l% z2 X, \: @" EOEM_TIMER_SERVIEC__H- g' l! j7 ?( E$ s) K, p1 D5 f. D
8 A( S6 K. j) H9 V2 {& e9 m0 ~
: b, w! h% b2 u$ {! `9 f9 v) Evoid add_timer(unsigned short3 J% h: d$ S4 B
jiffies,void (*callback)());
% E7 X8 |6 R1 v. p7 n5 y5 @% y$ G9 t+ m/ E* y+ S
void do_timer(void);) {; T5 R* \+ z6 n4 u
/ Q% l7 A: i9 H) a; S: j6 o7 w#endif1 q& e+ P$ b; Z( b( T( w
/////////////////////////////////////////////////
+ C4 s" e1 n$ j- ?( n/////////////////////////////////////////////////( H) g# c# x' q ~6 {" k0 W
//impl file
/ I2 V7 R) F0 j/ C2 x5 ~8 ^#include <stdio.h>
7 w" H& @: _ T; S9 ^9 E9 W#include "OEMTimerService.H"+ [9 n3 a& W% q' {; G# k" d
% @: v& S# o6 I) x5 O2 H0 G
* T* m3 E P/ O4 r" x
#define
9 ?- a& S2 j! t3 |) WTIMER_REQUESTS2 u) A3 b& I& e5 F
0x30
; {- H9 J' L9 C& {! s7 Z. P& s0 s
struct timer_list
1 i0 ~% M7 @7 D9 F{6 y+ L! R: R; }+ n X* t
- q7 ]5 v" _/ r, L% D) ~6 W* U
struct timer_list *next;
7 [/ M0 F- t! C( L& l& K5 W) r& ^: R9 @1 c3 `; z
unsigned short jiffies;9 |) o5 V0 L+ ?8 q/ _; A9 L
9 w5 w/ D' `/ N3 K
void (*callback)(void);
7 M% F: d% B. Q5 W: W6 o};* H7 e# q& k4 Z# `, S5 W( D
/ E" D7 w9 B7 ]1 P) ~& u7 s& c
7 Y/ m% b0 U% v3 V
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
+ t; H% x7 r: @0 s& y# E+ Q4 d8 J* K
2 \' p2 ?2 ]$ t1 g' gstruct timer_list *timer_header = NULL;- v! G% C6 c$ d9 p1 s( ]4 Y
1 Y4 n% R" l; ]9 p! I
0 {+ J6 N- Q3 z L2 K
void add_timer(unsigned short; G G. t8 [& \
jiffies,void (*callback)())
$ D+ n7 @% D, y, u: K! W{/ j9 s3 n8 F+ T# A X" n
' a! |* j* n6 a0 m* o: M7 ostruct timer_list *ptmp;
2 m. k- V$ o0 V
' R/ u& @& d+ H. Q$ I
2 \' X5 ]4 i0 tif(!callback)
/ k+ w% N: r9 _$ r1 v0 B) L5 {2 i# Y0 {$ \; ]* R X
return ;
) B3 o, L! P# D$ r6 u* }. \" _* D6 b5 I
0 G& }0 b- F$ Y# \% j! M0 G% o W( P8 Q" {
EA = 0;
8 j6 H& X, U0 W& G e; j8 U1 B+ W; P5 J. v6 T; v
, Q, D# \" B8 q* K) o& O9 @if(jiffies <= 0)
* c. _& t/ z$ B; R+ z2 T j. [
" h+ s# R9 B3 {& P7 e: C(*callback)();! h" [5 ^' ?; v" [
0 M. T; @5 ] B
5 i8 j; @- C r* U. ~/ w; ^
+ o' H) a6 a: m2 D2 E- |+ y, a$ x' Gfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)3 D: J. C# n( _8 S' D8 b
" R% H8 @0 v* K/ h( ~3 [if(ptmp->callback == NULL)
* i4 o4 p& o6 W- ^( j: a
* R8 T: }/ g, _7 a5 H1 }break;
$ n5 o, \' i8 ?
0 ^! w. H9 ~3 o/ U3 G
9 a- j4 p' ~, Q1 {7 ?# x0 k$ i4 z
) F+ U- k5 `5 u( I2 Y' n6 Y* V( d4 Z9 `if(ptmp >= timer_list + TIMER_REQUESTS)
' ]- c4 p; y3 V( |8 F; s: P) V* y: e$ y- b0 Y0 Y3 k
{9 _% U1 k6 ^+ q& G( t3 l5 K0 n, Q5 a
) I. T- f4 r3 h6 ugoto EXIT;
/ H0 e( D! d O9 w8 k$ w9 o8 q- z6 _! D
}
8 i$ }: u1 J! {9 y2 c7 H
8 B$ Y' H7 ?- a- ~& m
2 J" f" E0 C1 i' B. ~ptmp->jiffies = jiffies;
& U+ F' C! R. V7 v
$ ^( k% [8 @* O# ?0 `! f" sptmp->callback = callback;
) u# j& y/ L8 A6 A7 F
9 U* x2 h5 @) n- q ~! Z% z3 W3 l; E" n: h2 P0 N7 p1 ]4 `
. m& S/ Y5 C% o5 O, Optmp->next = timer_header;
6 Z" O* B0 K, i: B# E U& ]
/ Q4 l9 i/ u$ R& n4 h( Ptimer_header = ptmp;$ q+ I+ q$ G% z- x. ~
- A1 N: H7 ~2 ]+ [( F8 R
$ U3 @' [0 L) P) d$ {( V//add bellow code to fix linux on timer’s bugs ++
4 D* b& _0 \2 A6 p5 R( O1 o2 \+ v
) E! a) p# `. S1 x8 Sif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)6 L1 |' k3 C$ [1 P% v0 G( I) Z' v
; `0 o6 m8 z! |- n( g, K
{
4 y+ W$ j \. E3 I
, Y6 D' K5 i& z1 M" I& G9 F3 Dptmp->next->jiffies -= ptmp->jiffies;8 n. z& {; [- w- c
7 Y8 e. f! s" W1 {3 u
}//end ++
% n- U t" u* C0 e' t1 f& O! e0 h! O; d/ Q( u$ L
else& J# a! q3 t+ e: H A' Z0 U
( J5 H# Z( X8 ^% v! ^$ s
{
% E y6 g7 ~+ Y" o0 [& T
% u7 K/ ]* [% s4 Wwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies)), e0 R; }& s& e! l: \( j; Z# c& A+ n
3 J' E* ^! n) {9 c/ ^" z5 x
# v( i, [- u/ G l6 i% r
{
9 K( m0 ?6 s- I# P2 H6 X; e8 ~) V5 t
ptmp->jiffies -= ptmp->next->jiffies;
! f/ H9 d' m; g' K
5 v& R$ t0 F. q+ `8 P! V/ g; N- Ucallback = ptmp->callback;* F8 k6 F5 U1 c, D
( |8 r9 ~/ n/ n o: E
ptmp->callback = ptmp->next->callback;
5 @) Z) q) T* Z5 e9 V, v
6 }3 A6 g- q" o5 O) }ptmp->next->callback = callback;/ S) y4 y! v, Z t" B
5 e; _* @, Z* [( q2 h
jiffies = ptmp->jiffies;0 n4 i) U* G9 i" O: d2 s; g
: j# h8 q1 f) }ptmp->jiffies = ptmp->next->jiffies;
* l( U. ]6 }# R
) S& ^/ m! t: x1 L" D9 Pptmp->next->jiffies = jiffies;9 ?! j0 `. r0 K' K, E/ m
) E% q: Z5 i/ w+ }! z, b Q! zptmp = ptmp->next;
* E3 P9 z5 Y- p
3 t) o3 k" X* x) I4 E. c}
; c5 o! t+ _: B( m
' O8 T/ y6 P2 y- \; K8 b1 ]! Y' v}$ N0 `% j8 e$ J V# E1 p: w
/ [$ |) Y" l2 BEXIT:8 D9 |& l6 u& k! r' A& N: t
) h2 c9 o! \3 }0 j1 _4 v# w0 F
EA = 1;
" k0 s5 g1 J# ?' W
" G, \) q) Y+ E9 [- g# Q4 `3 e4 @return;
! ~8 D, `. J9 B! L8 }! j0 ] Q- y e}( \- C5 @+ ]. B& Q! }
+ l0 w3 k4 r9 j# p% X" _' Evoid do_timer(void): B, I" _- A% a9 [. t
{, `# T" t7 Y" r6 A; B& u1 N
- E1 a) V: c8 h2 E& d" k
- O' j; s$ h9 i! m2 q8 ^while((timer_header != NULL)1 J; \3 w; F" [- |
/ P* p& }$ X! j9 [) ]
2 A$ k0 [$ v; e- w8 ]0 ]( F&&(timer_header->callback != NULL)# L b* X; O' V8 ~
. t4 I5 `3 \8 H8 `4 v9 ~
8 ]$ b2 x6 X: B0 ]- y( x) p2 e&&(--timer_header->jiffies <= 0))
8 A( f, K# f$ L" f$ q3 p* d) {5 x
: o Y. C5 M" b/ `# C{
/ i0 B7 ^; @+ l. J' H
1 Z0 P( s' V* Q, x# R# t3 Evoid (*callback_fptr)(void);: C# Q& b1 f) u3 ]4 G( ^8 \2 O6 {
3 w$ _1 l" Y7 a7 J# U9 A2 k/ b( C- J4 B' J3 s/ W1 n9 x- X/ z: M
callback_fptr = timer_header->callback;; t# U% H6 w9 b! @4 Y# a) `+ t
2 }; u' m @; d; P! j% G
timer_header->callback = NULL;* J4 C1 _. o8 C# ~
0 A7 H# k6 a$ w5 l+ mtimer_header = timer_header->next;7 u+ I2 {, _* D+ \0 z1 c
; q3 q" B8 r) ^4 Z+ N7 Z& L7 l
(*callback_fptr)();* u& W, s: M4 ^* _
9 Z! @/ `8 Z& f! x0 ^0 j1 M
}
0 J# ?- T: e) f5 _& O% k- _8 v$ q7 K, o% C* Y% r
2 H7 W* O# G) j. ^, ^/ T6 {}" P, X3 Y$ w4 R4 f `
///////////////////////////////////////////////////
* s" F4 x$ D) G2 s+ S9 y T/ o3 \* N
2 M+ {! |# Q1 N/ g7 E
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!" g1 |8 b# ?7 Z$ ^ m
8 V/ A: N; v* `, L, K7 W ~! C t野人献曝,博君一笑/ d/ T0 \$ u0 U4 a) R
4 J! `- n0 V6 L0 `
Peter
/ x- H# C( ~; S* `4 o' D; P 7 I4 P% U S. |' P, i
# h( q' u3 I; u, E+ h0 j[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ] |
|