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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
9 G4 e) a6 K2 d0 r

; t+ O1 D" J. [" H$ _, n0 \! g  }! B1. Why need this mechanism?1 U' M4 R4 q5 B- I/ O
: A, W) i7 H3 Y1 J! D
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
) o, q8 ]# u+ {# y8 e
- Z# A5 n1 @" c3 d% G1 J% s) ?, R
2. How to improve it?
% ?5 H+ ^, U3 _4 t! Y- ]4 x4 q
3 C; ~/ s' x+ u  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)。搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code:
% ?2 m: }" x2 b7 r4 F6 C! }1 B4 O2 G% q
//header file( R% t: P" i. ]0 Y( ~
/////////////////////////////////////////////////
1 H" n1 ~2 h; j% F#ifndef5 h; U+ u( p8 I) W+ T, K) U# A0 i
OEM_TIMER_SERVICE__H

' s- w; k. P# [#define9 B+ I9 k* x0 k# V7 F5 \
OEM_TIMER_SERVIEC__H

2 W. e5 \% f$ q$ N& m; `3 a
' \4 t2 t+ Q. v) ^* }; z
* q/ a! _4 j/ A5 [* j  vvoid add_timer(unsigned short
- g7 M: M6 M* m; rjiffies,void (*callback)());
2 ?0 ~% j3 d3 e6 o6 @

: y( k2 T4 j, X) U4 Zvoid do_timer(void);7 P0 x0 u$ b/ R& }& b
# o7 ~8 `" ~2 L7 q" C/ }: k# H
#endif* Z3 Z- R, c# }+ u
/////////////////////////////////////////////////# W6 ~! |) Z4 k
/////////////////////////////////////////////////% e0 J, {2 p. S  F- V) p& _7 S) _0 c
//impl file
/ D, H6 h1 z& n* G) L- Z4 {4 d#include <stdio.h>  ~8 k$ ~1 J$ I' n
#include "OEMTimerService.H"
) L  A- R. v% P2 B. x7 ~4 a. z. a5 S, T, A: p# e* g5 e  G3 w
/ P( R' A1 P2 T0 g
#define( D  s6 O5 ^* I' C
TIMER_REQUESTS, {; y0 T; X! Q& K- u8 v
0x30

. l  Q/ v+ d; M* e
( C2 R) O3 `  w6 |( e0 x; g/ Z+ o  wstruct timer_list 7 [6 t: C3 z9 v0 H2 b
{
7 ^3 c& t; T% f: x! x8 [5 g; X& v$ [. t- S+ m2 ]; C' p
struct timer_list *next;

& c  h  S& @, m5 P1 y+ ?" z; U1 f( a$ h) A
unsigned short jiffies;

  i2 b5 M$ K4 A/ ~, o0 M& H2 b1 C4 m( q/ ?8 G
void (*callback)(void);
& ]5 y8 e9 |; w) w& U
};
" s/ P, c8 g- [  G- U1 q9 l7 {, y0 L4 i9 \
) F2 X; S  t( v" |. d
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};3 _% ]; U+ [& o$ w! Z6 H( v  V% v
  i0 z* c  d; W, D; O, x" ^, V3 i
struct timer_list *timer_header = NULL;" N) R, s% V+ r1 e$ m
: Z+ M0 y; n  Q3 t3 R
7 G* g4 \2 _+ k+ u
void add_timer(unsigned short
+ G! }" A& u9 O) fjiffies,void (*callback)())

3 ]7 ^/ s6 F1 f{
  X" y: R1 `8 `% p$ h1 g) S" ~) Y: i7 [  J4 p! a
struct timer_list *ptmp;

: ]* W1 g# U  |2 x- m, K$ X# B1 u' n; e! t
8 M+ M( n$ a! G5 E( D  Y
if(!callback)
; W$ P$ H  j: j% ~, }1 |; W
( A2 p2 d+ u! ~' L
return ;

& v' q( H6 k) q% R) h+ Q4 r$ b) h3 c$ Z2 |  B
5 j) y4 ^9 Z! O1 z4 x% d

5 ~9 x) z" _, n7 |EA = 0;

1 [; l& r6 O( r; |7 [% I1 x* o/ I: a5 r+ P
+ |7 j7 v6 e  {6 e
7 m( Z( e" z" \/ v: E- ~7 E7 m, Xif(jiffies <= 0)
" x* F- M2 q3 I, {

- Z! E" O% v5 _3 p(*callback)();
! |6 k6 C2 u. B7 d
! w/ y1 I; U" ?2 m
. ^! n7 i9 G4 S+ C1 W
; m( V# U$ M# ^- B; A, f
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
+ E4 O+ `' S" J$ _8 q! P
3 Y, O6 H' h9 l/ l" j4 Y6 R9 s$ D
if(ptmp->callback == NULL)

+ D6 ]" T6 }5 i" A; ^9 {0 _8 S* S4 U. `( m( {; j
break;

8 `# A* Z! h2 _2 F
' `, [5 t3 q8 A" m$ H, u( F& F, I( u# |& x" q
: }) W! y0 q! M& }* ]. T
if(ptmp >= timer_list + TIMER_REQUESTS)
0 V0 y* \- C: }8 e% X, E! R

! ?/ t1 O6 N6 F( d4 G{

" C  }9 Q& F$ h$ b- ~* s* p4 G9 v! b# v" D  g' y
goto EXIT;

( y' Y2 b* _, x! C8 t; X
: r) z% v! ^5 p}

) P7 q8 s% \; X6 n, b
) l0 O* J3 |7 G% h9 ~% a1 i( s- B9 T$ v4 ], Z/ l( r
ptmp->jiffies = jiffies;

% [7 H( l% s! D" f/ c4 T' n( t# I) N
ptmp->callback = callback;
* K6 D2 s: N) p; |
# t: q/ r" n9 U# _- _: [( y0 Q: o- d
4 r/ j8 e+ d# D8 y

7 A& {/ q6 x2 Z/ ?ptmp->next = timer_header;

4 v1 y! s' }/ U/ L+ m# H
7 i9 Z/ C) V) q, ctimer_header = ptmp;

4 d- J( Y1 B" e% D* @# E
( \+ P7 A* S* d" x/ U# A
, W+ ?; b4 P7 D/ D9 f8 b//add bellow code to fix linux on timer’s bugs ++
  `' k. r* V# D6 s
7 [% f* Y3 a3 j4 d' U' ~1 m
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

2 S4 [/ |5 c6 y- B
' n8 j! g7 M% U: X. ~7 N% C{
8 f% L# J3 k, s' U, R8 ]) F3 k, m5 K
. k: }' d4 s8 O6 `: T- {) o
ptmp->next->jiffies -= ptmp->jiffies;
+ i6 y3 F# Q8 s5 E" V8 N3 ^
; l+ M% |4 O( R9 J6 u: F
}//end ++
# X3 V  D8 F* j+ n; j. h
8 j/ }0 _# I7 t9 q
else
" @% e2 Q( `/ p/ Z6 g
- j- z; B5 d9 s+ p; e  `0 F
{
( R9 {; J! R: O

# f) E1 I! |' V$ }3 B  Swhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))5 i. n' g! w# h/ H

, B  G$ P9 y; j. ]4 J; X$ S3 p2 H: z! H3 d2 J# k
{
; r/ P' h' x5 r! H( f9 R  _

1 Z3 _; B' J1 K1 c  p/ @ptmp->jiffies -= ptmp->next->jiffies;

/ H* o' K* Y- b- ?5 J, ^& A7 p; D
* h) e# Q2 y1 A; Vcallback = ptmp->callback;

# ]* c: d& ~6 H
7 h) E. i% @: x0 w3 y+ W7 b: sptmp->callback = ptmp->next->callback;
1 h7 m! @" `) J+ U6 K# Y

  Q" K+ ?. n: D) Y! Cptmp->next->callback = callback;

( m# M" L& @, l# N9 K- u7 X
+ Y( Z' k6 X1 }9 R9 {jiffies = ptmp->jiffies;
! F, Y: ?1 r) s+ j0 F3 D% R! Z
6 a( C' b; e+ }4 b/ @, O. @% Z) Z! z
ptmp->jiffies = ptmp->next->jiffies;

: u# B) \' O4 O$ l* q' E
$ c4 K2 q; }- g" U8 aptmp->next->jiffies = jiffies;
7 @& a5 B  D9 g# v% ~

- x1 @4 |2 w! \& E3 Sptmp = ptmp->next;

3 X$ N5 o' @  g  R5 i' K; K+ C" P2 V& g
}
' m4 g% _$ j" ^% P+ [$ \3 k0 }

! x4 x: A& O& p2 |% J  t" J* ~}
* x# j* L7 M1 ]6 R/ S8 ?
! ?, ~: u" G0 u  ~
EXIT:
; d/ O: y; G# Z
8 t# i, s% a. f! e& U, x9 g, lEA = 1;
& n& s( w3 v& m1 k! N- t% q
, V3 o% b/ q$ a9 d
return;

3 f% k) G+ b- G7 `}
: S, X+ |& {4 o
1 k+ K. s3 P( Q$ s; a$ |4 k% C" [void do_timer(void)
' ^( ]0 W: o8 r" ^{: R2 b! q& C  ]! L* X+ G9 m$ j7 ?

3 S# c, D/ z3 _( Y. i9 }! D  q1 u) C3 O2 N
while((timer_header != NULL)
; _6 R' C! T' m  U( b
% `5 O% g0 L5 O& ^

/ s5 p, l8 N5 Q9 p&&(timer_header->callback != NULL)
( U3 h+ L; c7 o& ~# n
! h0 z' ^; H( j& d$ x3 ]
0 Y2 p' ^1 h1 q  d
&&(--timer_header->jiffies <= 0))
" L5 Y2 L! X0 r* i+ r1 z7 A

5 ^! `8 `% p2 Y% f% r{

  N2 X% p$ [* ~3 V3 V2 |0 k* m' w; T9 \+ B: ?
void (*callback_fptr)(void);

4 Q$ M* x$ S% M1 p5 Z- O/ }, u  h- p3 Y' e) v; ^7 d* P

2 ?0 o: ^' _% t! l2 u. ?5 o" s  v: ^callback_fptr = timer_header->callback;

( d: }" U6 s1 t" B- X  d1 E1 M& K& ^% M
timer_header->callback = NULL;

, a0 Z& j$ n' X1 g& o; U( Y7 R3 |
- M2 t5 w, |& H, ltimer_header = timer_header->next;

0 j; _2 x: [6 [; X  j
9 x+ c; O6 {, m8 ~* ~7 X$ c) g(*callback_fptr)();
+ {) S' L. {6 }- P$ F3 @# u; ]
& u5 G! S$ Q, G. b
}

' x4 W+ y2 u' ?  W. j# s+ c
) f8 ~. V# N0 m3 w# t* ]- k

2 ]9 H3 j+ }  k1 Q/ p5 @' l; h& d) h( r}
. B9 L. ^3 r  p  U2 X///////////////////////////////////////////////////' S* r3 f0 [- @' l6 q5 Q/ s6 v

& c( r* {1 J+ J$ {
* X/ d/ ?2 L' B; y& B' g
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
0 s2 q9 R6 ^% Q& c& U  j, d' @. _: w' T
( a6 L* l! J7 r2 e/ }% h野人献曝,博君一笑* H  T' Y# C7 z; |
- _) A1 ]8 {, J0 C0 U9 f
Peter
9 B& @) h6 L7 @7 U. c9 y# v+ R; u  * s( `2 T! c. M+ |9 _2 e

" R0 I' E/ m6 u6 `$ M( ^[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-10-12 07:28 , Processed in 1.319808 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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