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

Smart Timing Mechanism

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

' e4 e# w; z+ z9 u1 M
9 M* U: W; |" }2 j, b
1. Why need this mechanism?" E& `; A/ q' O6 Z! f

6 W% t0 J3 b% D, R! B/ o3 Z2 J
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
3 d9 a6 _1 i/ H5 q, E

, \( ~3 b6 R  ^0 f2. How to improve it?
7 x0 B# O7 j0 x' O
7 U8 M. X! d/ [, M  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)。搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code:$ H% Z6 H4 e% h0 V4 j1 ^9 }

1 q( M, y; x$ ]0 B; e* ]5 @5 j+ M; D  \//header file
1 X0 f7 Z  Q9 \" I: _5 o: L+ c/////////////////////////////////////////////////
, F& w' U2 w1 Y6 u; |#ifndef' o9 ^& f  u+ B2 k
OEM_TIMER_SERVICE__H
* \, B+ j9 v( s
#define4 Q/ l: J$ O+ J9 K
OEM_TIMER_SERVIEC__H

) F; p* ~- c9 r8 C5 n& w# }0 T5 G
5 F. s6 s3 @. ]$ `
0 d/ p) `+ }8 M. nvoid add_timer(unsigned short
$ E# k, J5 Q: ]jiffies,void (*callback)());
3 ?% G9 `2 T4 ]

( W) V" U$ J: ]. Kvoid do_timer(void);
+ m3 V, ^9 c. E! z1 x. V3 I9 q
2 h+ V1 e3 T" K8 C: g#endif7 ~" n- |8 w) e" l% [5 O6 g
/////////////////////////////////////////////////. J4 ^9 e1 h: M- h/ M$ z, t& G! p3 J
/////////////////////////////////////////////////
3 A6 T) W7 i2 q$ M//impl file
  n) M" k6 P/ f9 ]#include <stdio.h>+ S! P% |' W5 C; H" g
#include "OEMTimerService.H"/ u. Y$ @0 s- B  Z6 b

( i" Y* g8 D, @( P: t! r& P, h$ n* u2 s# A0 M
#define
! J1 N6 p* k- P. H2 C4 e4 aTIMER_REQUESTS
3 B; `9 u! Y; N: {0x30
7 ~' g5 G$ m. h8 ~: |

2 q0 s0 ]( j/ Y4 l$ p( X. Hstruct timer_list : A, m) \( p& O+ `. b* ^
{4 M( C# \' `0 W8 H

" l* F& m& \% P" G' Cstruct timer_list *next;
- f! Z: I' c* d8 T5 `, y7 ?3 w9 H
& R# n+ B3 {' D$ B' z# n
unsigned short jiffies;

- s9 [* ?3 c; W0 B; B/ l2 c" \8 Y' E7 ^# o" n! c! F3 w0 ^
void (*callback)(void);

+ j/ A$ X' ]2 L2 X};
' X5 ?+ f' i, r5 _9 f2 O4 T6 E" l4 b& J! X) x" s
4 M# M! @. O3 Z3 h9 b( S
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
2 _, I2 O% |7 I) n% v- d2 S5 r1 c1 F7 N# q' q9 b# g
struct timer_list *timer_header = NULL;  K- K- b$ [0 x1 q6 s$ c. G

0 z- c& i! d  ?
. m* G1 p) n* G  g# [  Kvoid add_timer(unsigned short
/ V" Z) k! r7 x0 z/ B* o: Njiffies,void (*callback)())
: c0 |! j+ d4 [( j2 C% o1 Z
{- r$ m9 w) r5 |# }
% V% h* ~/ p* L; f
struct timer_list *ptmp;
4 [! w/ Y& K4 s" q8 `
! I, f8 f8 r. R
" R7 w$ u2 G7 C, f: P) A' I$ `
if(!callback)

% m( l" M: y0 B% |  }! l! O" V1 z* M5 D( x5 w  h  N
return ;
" M! {3 j+ M7 h4 {
/ `7 n8 P8 U5 p4 K) E

& p- C4 F$ n% D2 a8 T& ?: N5 \0 ?# l5 a. U6 u
EA = 0;

! e7 g: a/ |: H8 S1 f6 Y) p5 a) e
. L; p4 S0 n0 v* U
if(jiffies <= 0)

8 |; R& z0 C! L8 u: ?2 x0 K9 T
/ x6 g2 B" X' B- y1 I) o$ k(*callback)();

3 ^4 N0 i7 G8 v0 K* h. J5 q& o% p" A7 K
7 y+ q$ ~' z# g& d  \0 b
3 Z! V0 H6 V* D* H
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
) h( ?- K+ g. K% r$ }8 A! M

) ?7 Z+ E1 `$ ?# z5 dif(ptmp->callback == NULL)

1 S" y: h6 |. q5 D( q# f5 b- d
2 `  s& o. f* H1 [# O2 |* T; f! sbreak;

% \2 p0 v+ |3 L% r% @5 z! l: |' |: ]4 l- d# ?7 k7 |/ [& @
# G( c0 R( f2 R  i
  T8 C4 [; b, h7 g# Y
if(ptmp >= timer_list + TIMER_REQUESTS)

: x1 I$ u* o/ z8 Z8 F
9 F4 N% T( r3 W; X/ Y, k7 w{
# P" z4 k- A  I8 Y
. \0 P% N8 R1 A5 _
goto EXIT;

5 E; M# E  \$ K; V' Z! |" s
' B& U* G+ K/ i* {}

  I7 F6 |3 u% `+ S8 T0 g( n* e# a
1 k6 m9 f5 {' ^2 Q/ b
ptmp->jiffies = jiffies;

+ A7 p+ E" a) x  B1 v# m6 b9 U3 _
! U" ]! z. {: B6 C: vptmp->callback = callback;

, @5 x" H! y( _3 N6 }& b% T
; c/ M; ]4 x+ \! z+ [

) O% s5 B2 D5 i, ]) `& V. R6 d) r/ d  h, @) ?# E7 A
ptmp->next = timer_header;

$ V) I) U, A' g3 O" q: B0 D& K( u9 y' F% p6 V) p$ n5 C
timer_header = ptmp;
) N7 j$ [& o# K# ?6 `2 k7 a
( }/ H/ Q/ ^$ k9 k! l3 G

! @) X3 w( T# m8 ?5 F" s5 H: r//add bellow code to fix linux on timer’s bugs ++

+ E" P; R; }& g# ^
1 ^) N* n& N8 B9 n# q. Sif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

0 Z6 B! I4 D3 t+ b7 m5 a
* y. r% q' d+ W" `, H1 M, o{

9 T8 r' I; R8 X( N2 w
  M1 _( q4 a, ?& gptmp->next->jiffies -= ptmp->jiffies;

) c4 w! W; I0 e. _( t
8 t" }0 `: m2 j* ?7 C8 m) P& e}//end ++
, s9 f& W/ h( r' ], o

& s. p  A4 t' _. ]8 q' Helse

  x+ }- q& |2 t$ D. {0 E: l) @7 K: Y. e8 N" Z* d- D
{

: v& {$ @7 {. D9 O1 V1 R- ~4 }
, e6 v' ~/ \$ R. a6 mwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
  d' |' w; Q* ?" N; U
; ^% v( u/ |( d4 x$ m( X
4 O5 H' a' k* j+ D4 F5 K
{
' o( }1 x$ I! m; a' ?

# @- |/ \! d. b5 jptmp->jiffies -= ptmp->next->jiffies;
1 K9 B" D& M3 w! \! ^9 n' l3 [+ e
! B7 e, H( ], Q
callback = ptmp->callback;
0 Z, N0 b0 i' B+ @
& }# ^; [6 t1 E
ptmp->callback = ptmp->next->callback;

$ P! w0 E/ G4 x/ k7 u) ]
  [8 }# w" w7 E. b8 [4 S1 m% eptmp->next->callback = callback;
9 _8 T3 Q6 r( ^: E/ P

% r: C$ r2 L! i6 q' ]) D0 b* qjiffies = ptmp->jiffies;
1 ]% r( t/ e+ N/ {" H3 J! Z
1 K8 N! ]+ a1 d8 N  q, y1 V6 h
ptmp->jiffies = ptmp->next->jiffies;
% b/ i+ D/ [/ J. R+ f

- H" f$ Q' F' \2 Jptmp->next->jiffies = jiffies;
6 o8 W# h+ _2 j4 ]/ @' [# b

7 C3 l8 y/ C$ u9 {/ u( y5 y8 u( A* aptmp = ptmp->next;

% O: y: a+ w/ s( U8 h' U- A/ Y
+ ~) i3 N4 @" O  b5 t}

, ^" B/ Y7 D5 I+ k; \1 L1 W6 k: ?/ `) _2 \" n. q4 ?% I4 D
}
. X* w& m+ C% G

+ R* z) A- e7 |, D  KEXIT:; |8 m: k" @# @' x$ C. r" Y

! `# g4 Y* [1 N8 `6 _% Q5 jEA = 1;
% P. W7 `$ W, a: e
' E: [* K0 b! f! r1 ~
return;
6 _. B% K1 A, p, }, F
}
7 f* i2 t# A5 N7 H( a& a* J" `( n' L$ r- T
void do_timer(void). J0 \8 Z* V* M' G/ d9 P& E
{
4 Q) a* Z* `; P4 [( x" g

: n; H) H: d% q" o1 i( z# L: S- e0 r8 S2 a! \3 n8 w
while((timer_header != NULL)

2 A, Q- ~& ^. a0 I+ C
; V9 ~4 a4 a+ s7 h0 q* w9 o+ T
&&(timer_header->callback != NULL)
( q8 k: l- K3 ]- \

3 q7 ?! W: y6 j9 M. V( ~4 V
! U1 O" f* ]+ ?# q&&(--timer_header->jiffies <= 0))

$ W1 n8 V" n3 s5 n' L) r5 R; G; P# m- Z# \/ r% `
{

; }7 @: b! Y' R1 w% I) _8 _8 I- q5 |$ U, G" ?
void (*callback_fptr)(void);

" v  ^* D5 N* T9 G. E1 a5 Z1 o+ I! w
3 h) s8 ]3 a# O5 J% @+ P! w
callback_fptr = timer_header->callback;
! r8 z( Z6 y+ Z0 P# q1 v& ~& Q1 p

; ~3 |$ ^; q' I4 j; ptimer_header->callback = NULL;
2 Q4 B9 b  _/ f& I7 S
: D: f+ ]% S+ M8 G" v. x5 {
timer_header = timer_header->next;
0 p( C$ u5 {; h6 x5 O
6 `3 Z/ S1 N7 c/ U; e5 J8 Q
(*callback_fptr)();
; _9 @7 H2 k: ]
2 E& h' \! B, j  `
}
4 @+ \0 a- @) M/ O/ F- R  D
  A3 ~' T; Y3 W8 R
$ i2 r. o! }5 e6 ]
}
: w8 Z+ c; ~* y% T///////////////////////////////////////////////////& P3 e& c. J* g" i) V; _

4 K# `8 `; e3 T7 c, j: t1 E
2 s+ N6 F0 q& S0 m& U
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
- m' W6 i. d( t6 o: b: H; \! J' k
3 m# i( I3 ^$ k8 D: `: q野人献曝,博君一笑
0 o" L) @2 j8 p; J  W
9 y6 [1 `5 i4 BPeter0 f5 l; f  R' f( h5 x1 v
  
% A1 M3 \3 P3 r+ k# Y7 Y# y1 ?2 u, c, t3 x$ l
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-10-20 08:33 , Processed in 0.077936 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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