找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 6018|回复: 0

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism

. F! n3 a" v5 D: |
7 t! _2 S/ O9 v; U. G' n
1. Why need this mechanism
, Q7 W, I* P/ c' T# W' v: @: M9 P* O' z0 \* I
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
% L# v$ H9 ?. V0 W

- G) {  K1 y5 {1 x0 `2. How to improve it?
& N2 C' g) M; `" u' f% o$ r: r8 P9 o' r
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
) B3 N1 q4 K* S) c1 N+ g# H! h7 R( S/ i, ^
//header file* k1 z% D7 j$ W* h. u
/////////////////////////////////////////////////& {9 P0 w; c, W/ ]8 `
#ifndef; V8 z4 L$ o1 `) d, t' B# P: d% O
OEM_TIMER_SERVICE__H
. _4 }1 w) w* E8 r
#define3 V2 _+ O- [; G
OEM_TIMER_SERVIEC__H

: b$ c5 r! }: g5 M9 y# A1 J! z0 k  |

& H* X$ E9 F5 dvoid add_timer(unsigned short$ N8 N; ~7 R6 s1 g/ h) t7 s$ E( A# Q( j
jiffies,void (*callback)());
% N1 y2 z) S( X# ?

0 f! a! U( b8 e1 f* j. rvoid do_timer(void);
$ f/ R) G7 _3 B( D5 `( e; U' c( O6 u. q
#endif
3 ^- F3 d' R( a2 d  A) J" y  Z. @1 \/////////////////////////////////////////////////
  J& Q' E# g0 O0 A7 C& ], L/////////////////////////////////////////////////% Q/ h! t' ~$ ~# N0 D
//impl file
7 z* e+ W, }& L! K#include <stdio.h>
3 z$ l7 G$ H1 B( ?" h: s( D6 M: E#include "OEMTimerService.H"  N/ x4 J$ i2 P
# V2 w, o2 G) Q, j& j: z
' p6 a4 Z, s1 [1 w
#define- ^1 B! `' c$ E/ `4 V9 R. @3 w
TIMER_REQUESTS
, C1 U1 H; d* i' U2 e0x30
5 F& K$ [: f6 E

( C: e+ s$ ~1 m0 P( s% I2 dstruct timer_list
6 I8 ^/ g, }1 c{4 H: @& c4 C3 M

! h) z3 }( L' G$ [" _9 Lstruct timer_list *next;
0 }: X+ r* m9 D( H/ [0 a. C+ G
7 x+ h, t% ?- [. Z& m6 {" k# v
unsigned short jiffies;
" m0 p! I* o: E+ a& L

+ f. s2 S7 {" ]1 a+ U9 Jvoid (*callback)(void);
0 {' P# o  n1 T+ g
};9 A4 a3 T: l8 c* f2 S, x( Q0 u1 y7 y
, z6 ]3 B3 p& `/ x
! z: ]0 R0 }7 E0 {2 H& `! `9 T
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
! Q) `: P+ {! y3 ~. E: i9 b$ o. f
- |/ Z6 P$ G( M& t0 gstruct timer_list *timer_header = NULL;( n4 @% ^- v4 T  s# T8 F. g

  N" _5 G+ ~% ^" b- [: y; ~6 V9 l: L& d. \
void add_timer(unsigned short: D: C* }/ r0 j- K
jiffies,void (*callback)())
( R* a' U( Z( U& \0 N# i
{4 p& J4 r* N) @4 ~- V& s
) J/ d% ~# P3 D1 Z
struct timer_list *ptmp;
# N6 x: A5 |& F- P

- v0 r- l/ z9 k5 d: c1 ]) X/ L8 D$ D# j. L1 z4 V9 ?# z$ Q* C
if(!callback)
$ n: A  ]1 ~$ D! |, O

' o: i- b) q7 d" F% m! dreturn ;

1 z9 Z" q. t# w7 `7 Q  a
3 ]5 \( N4 }0 ^/ m4 g
8 p* C6 k% ?+ v& h

' z- f# _  o; TEA = 0;
8 M: ^8 ]# m: M8 R/ H7 u0 P
/ m( S$ l4 I9 n( f3 D6 x
9 N: ^0 s& F. c3 `+ q# s2 I5 q7 m
if(jiffies <= 0)

; u' E; F% r8 g5 l5 @+ [. b+ W
(*callback)();
: s4 s5 @" [* T( }/ `
/ E7 A8 S* f8 e' t* ?6 g

# _( c; l$ b" a8 m3 f. H/ }) I
7 \& l7 o6 v* X6 }for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

: t, E) |/ i5 ^6 i2 H; ^" K& [. G# T3 ^, l) Q1 c* F6 @, N, s$ m1 S
if(ptmp->callback == NULL)

6 ]. e3 ^4 v: K9 c, N- w* j+ T3 F' b9 m+ \9 N
break;
7 D3 _+ W, _2 u9 E: Z# i" F1 r* T
! [' K0 l5 [" f- M- Q

. O2 y1 v* X  \' h, C9 n  Z* j
1 H! ^. Q0 p" J+ y) ^if(ptmp >= timer_list + TIMER_REQUESTS)
3 s' O: `5 {( `& E
* H: O- H9 F  N+ ^. a9 b
{

# u5 q, G" C% T7 c
" j0 q! B7 N7 J. _goto EXIT;

) a# S1 o1 V; f$ r4 U' d3 T% b% d( |, t! n5 g8 N
}

6 X7 G; f% I( K3 K7 H) w( z. A7 O' E5 s% ]/ ?; J1 n
+ @5 j8 p: M4 P  X
ptmp->jiffies = jiffies;
( Z3 B7 \  |# m* A- Y2 V8 K
* i( v# i) D; m7 C
ptmp->callback = callback;
% d# q+ W# R% `# {  i: {

% N! n0 N* Z- @

, r/ z9 x& b2 u! W( C- W/ ]+ I
/ p6 n8 G  ~0 g: T( iptmp->next = timer_header;

, ?0 f7 Y' M( d/ I  s1 L! V: P5 @; s3 x, _" y9 }6 [0 l, F8 \
timer_header = ptmp;
- z6 {4 ~5 A3 z0 O1 m3 _

& [/ j3 j! K/ z1 v, @- J% k3 d# Z& W9 U' X% ]
//add bellow code to fix linux on timer’s bugs ++
, }( V9 t. Y6 g" ]1 k: E2 M! r$ n! F

, X# X' p3 o4 p# w0 ~; Q7 vif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
$ E7 z' H9 T- P& Q4 X

7 b6 c6 t4 T& a{

7 g( P6 B6 Y. }! [
* X6 U6 P" Q0 j2 c! hptmp->next->jiffies -= ptmp->jiffies;

3 N! L7 F- q- i0 a
  [7 i( R7 B4 ]0 h0 y: @, ?8 a2 ^}//end ++

1 G, \3 l8 n% W( h( k' F$ B, L* ~' l4 \9 E
else

6 a3 q: D7 J4 F+ J0 Q: b
( i  L+ c0 k& t% i% B2 z2 F; h* d* u4 r{
0 j+ K( p& D) ~
+ R  D5 `3 w2 l- H6 V3 k
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
0 @1 {$ y7 x) V, ]3 T3 [' O, ~, k  X

# [& g& ]7 g3 u* |. v2 y5 h+ w3 w) M, Y" z9 b
{

3 ]% F1 V. J& \  u' w: S; r% X* @
; F2 Z0 m: R. Jptmp->jiffies -= ptmp->next->jiffies;
* H* S- v7 |! z) M- l) e1 C' g6 ~
" a# |/ k, i8 g. O% X
callback = ptmp->callback;

4 H( F* H0 ]/ E' s7 w9 O
/ E& B3 h. {2 f2 k2 U, [ptmp->callback = ptmp->next->callback;

! @4 q+ O9 T" L3 Y  _$ ?3 U7 n# \
4 V7 O1 }  l1 |. Mptmp->next->callback = callback;

; p0 R# c7 F+ p; H. a0 }9 l- s
, l/ ]) R, @- Q8 R9 n0 h6 W+ |jiffies = ptmp->jiffies;
9 M2 C$ C+ E& y1 q! c! [

! G: S2 t! Y$ @7 V* M1 ^; L. ]ptmp->jiffies = ptmp->next->jiffies;

4 N( I- f& |- p7 I3 o- _* Y. p1 v+ y% S! l4 {* P! L
ptmp->next->jiffies = jiffies;

4 z; f1 ?  K% i1 [( Q& R+ P0 E, `* c, w, m% O5 C
ptmp = ptmp->next;

8 H( }# {3 G: ^, ^, o8 ^# N% i+ D- S& K4 K( [5 U
}

/ G$ j8 n4 _4 j' K1 n/ F4 {6 ]% L- f6 z
}
) I$ q, e1 L- f$ N8 k

6 e4 H& E% R; s5 MEXIT:
4 p; x2 P5 |; c* G% a& i6 u% m9 \( l& `
EA = 1;

% t4 z; P9 q6 L4 m. z% q
5 r% o) l9 n: j# q4 J6 {' \0 [return;
3 Y& b/ F" q2 H  W
}5 `2 M) c5 e6 J$ Z3 f% H
6 _* J# D; a1 O+ R
void do_timer(void). }+ E  B% ^7 J$ L) r$ ?
{
+ P% f7 w3 e, [2 O. p
5 B8 T  i  b* g2 X) Y1 L5 t( q& L

4 Z9 `; W* |7 Q2 j, q! w0 q* ~1 _while((timer_header != NULL)

/ [2 T* t2 B' W; \1 x  \5 q* S1 i) A" s$ ]/ s: t
+ T# t- C, l# ~' a
&&(timer_header->callback != NULL)

% U) t. K3 O" j. ^& L
/ Q( s# p2 G/ }8 }7 Q+ s
- w0 ^  q: ^/ t+ v6 a* `&&(--timer_header->jiffies <= 0))

. m7 C5 G0 M9 [) a) w" M+ I8 [
3 x6 C5 [$ T- Z6 D9 i: N. m{
1 Z; @" E4 Z" S# U$ f1 P
8 E' b2 a' e" p" t
void (*callback_fptr)(void);
, o+ r: z( Q- P1 b
% l( e% U* p, w; {
: T% [" X, Y* d) s
callback_fptr = timer_header->callback;
2 g( y# v! g( M& C% B! _
8 W2 k9 B7 {7 N1 H# B
timer_header->callback = NULL;

, Q4 b6 P, o$ h7 ?# @1 h( y, T6 z& i( t6 X0 D& E
timer_header = timer_header->next;

. W2 C% Z5 n& W+ t* x! w" {4 E* \# h0 `: H
(*callback_fptr)();

: D3 T) L7 l% k" s) I
3 J' B* k0 v. s: O7 O1 ~1 t2 X}

) |+ o9 U5 |1 a, E% O/ D1 O; C6 a6 O2 N* d  {+ }- w

1 Y) i% V- r4 P" b) I6 Z}
5 F% X( v1 J+ W% L. ]4 |///////////////////////////////////////////////////
6 f" d2 y$ d2 a. K+ N' ~& A2 G2 k3 W# S% h/ _) \4 R& j* f
; K( _# z3 s- D
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!9 ^+ A  z- _9 F; P6 x

( T( S. ~* Q% \* `. E* w+ G- E7 c野人献曝,博君一笑
+ y6 [6 C$ g% G- n4 n4 F, }! L
0 p4 p- _$ [/ P0 W. QPeter; O% o6 v8 M8 w3 |
  
" N4 A) V! G/ [" D* G3 ~/ x! c8 c* C# K! h* L
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2026-5-25 14:33 , Processed in 0.055431 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表