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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
5 E' Q% I" @# |7 S; L3 u

3 F+ `0 Q8 ?& O! L1. Why need this mechanism& {; t1 q. I9 d7 K- O2 E9 {

& e/ M6 c1 Q! [1 M8 C6 F
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

* {+ Z$ _4 y/ A( G
) O+ v4 q+ y7 T% n2. How to improve it?
; a1 \" k( j- X$ X5 }  O, D0 u2 T' L* P! U4 K8 t) R7 ?
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
' p, h% Y; g% b7 W% V4 D& ]* G' R! D9 f2 d- J
//header file
" h% t  m8 [# V& R/////////////////////////////////////////////////
  X. \( w/ A. `( n7 U/ _$ V#ifndef
$ ?: B" U5 b; Z8 u1 _OEM_TIMER_SERVICE__H

& l* E1 l* {, p. e' t: X#define
0 q) v' D4 L; @7 p" G' A+ g8 i) oOEM_TIMER_SERVIEC__H
3 K( u6 l4 h# F! f- f
; u+ h4 l5 }9 ^2 {: V/ D
+ Z' r" W# E& ]9 n& X8 O0 z
void add_timer(unsigned short
% a/ D5 w7 w/ @' o% C$ pjiffies,void (*callback)());
3 y3 L4 M' _% {5 K1 g' j1 o
7 }3 P  ?% E, ]) q' O
void do_timer(void);, h' u& ?- j  ]3 ^
3 X5 ]& k/ ?& l8 u; w
#endif
5 i% ~1 B% j' L8 d) A, E# ?/////////////////////////////////////////////////
2 p2 J+ M, B: E: P1 [/////////////////////////////////////////////////
  G+ {9 ?/ n: R5 b0 n- j$ i//impl file7 t7 O  M$ l8 G* w
#include <stdio.h>7 l# C+ t& O0 }3 m8 H+ }# X
#include "OEMTimerService.H"
: T/ g1 U# q2 Q$ V) E
# i  N: `3 {3 |: S$ {( y
  s8 A3 U+ x# _' F#define
  {# T9 e$ j: L( a/ u# ]  j) bTIMER_REQUESTS1 X% Y; f* V7 @4 ^/ t/ y  s2 I
0x30

% B' _$ P$ a9 w7 B% y0 ?0 y2 r3 u9 m; r4 n& _
struct timer_list 3 E' _* B- |8 A/ W, O2 D/ @, P+ |
{+ f' K7 g* h6 z& T

* _/ K& v+ v* Y$ Fstruct timer_list *next;

- y) t6 G: k' x$ J$ T0 l. s6 o
) ]6 ^7 S. J4 q' L- q% Aunsigned short jiffies;
3 Y4 t) s$ Y* I, n# m9 \, ~
" C3 x: l) ~/ j6 w
void (*callback)(void);
5 {# _& ~$ k2 o6 I8 h' E1 a' z7 J
};
* R! F' \+ X+ {& i+ d. J- X% {% e. v, E/ i

$ n9 y* d# M  U. G- `7 astruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
- H' P- V7 o8 ]& e- |2 n
7 v% {8 H8 m- L0 u$ Dstruct timer_list *timer_header = NULL;5 z( m+ Z5 ]: v4 D5 q
# L8 {: @( {% d* }4 b+ T

, `1 Q( j# B" p( k8 nvoid add_timer(unsigned short- \5 l( K3 j( R, A7 I
jiffies,void (*callback)())

4 [, \  \& c4 B7 d9 P3 O$ l{
. [4 L0 o. e- j
( U! o1 V- J6 e. @5 z6 T: ]struct timer_list *ptmp;
+ V" D" \7 q1 U0 {0 \/ ^: ^: I

3 |) [) J$ i' I3 e) n6 L
6 E( _/ i" i0 J. ]if(!callback)
8 C# m0 {8 m: P) T0 ~# H

" N% |, @8 E8 G' x% @+ H1 Areturn ;

2 I# ?* B+ G6 e7 ~( o1 o5 v0 P. a* y# Z& G* l# x: W; I5 V7 r
  v8 ^8 V, z/ |  k" Q
4 i. A9 V) Y* a' A/ y
EA = 0;
. T+ I2 ^3 L' V& [8 i+ R
4 k5 k0 ]* G4 P

- v) p6 Q! G+ O% j% \if(jiffies <= 0)
& \& n) v( j' p% F* G) D8 g
# [6 ]6 K9 J+ |. P3 E
(*callback)();
1 c4 [- {( D6 e
6 M( w0 R0 V) N1 v
! b1 D/ }/ {) @; w7 W  D$ V

# W5 ~1 q3 Z. V, R; s* ~for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
& Y3 g6 M/ P: c, V% L5 M3 P

6 O3 r/ K( b8 f( e: Aif(ptmp->callback == NULL)

* \7 r) ?, T0 D8 D* v5 H+ T
% v  i- _- b" {' ?$ U7 \" Pbreak;

: w1 o% K) d% a& `! O% q/ F; G7 }! ]
0 Q# @, R  L: J# V. M5 I/ h

, |; d- `* x7 Iif(ptmp >= timer_list + TIMER_REQUESTS)

5 z7 _' m6 ]. ^8 q$ T" Z
, f! H$ }; s3 J! z% I{

- v6 S) Q4 b$ Q: @5 }* _( v( \; V1 }1 S0 }2 V& ]1 a
goto EXIT;

: b/ T1 T" K, V
% M! B7 Q* [: N$ s% _5 u}
: X8 \" G4 c9 N( p- N
/ E0 P0 Y9 ]3 H

, E$ x+ V! I7 Z9 B# Uptmp->jiffies = jiffies;

$ K  Q; ?8 d6 V3 }5 N: u- `4 b
/ F4 H/ J# b% W) X  T, V% \' p0 Gptmp->callback = callback;

7 V9 E- {4 g- |  u* G+ }; V. X. ^; s' ~4 V5 p) F

; c) ^+ d, t7 y2 r* U+ T
$ F+ I' a$ B9 k( q3 f% l. C+ n6 rptmp->next = timer_header;

0 M; Y8 _4 r* e1 S! N/ @' |$ A
- f8 f9 l! {/ _) G8 {timer_header = ptmp;

/ ?2 i- P$ }' Q. C# [0 S) \7 S0 ]

/ L1 `: D! m  m//add bellow code to fix linux on timer’s bugs ++

4 \8 V1 }8 ]; t$ T2 T$ D
; K/ \3 L2 v" Z# Cif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
7 v" q) S# V$ _( i
3 ^& T  h; X6 Z( O# r
{

( t  J; a% B$ F* G  v) t/ W( ]( u6 K0 W3 J: ]) q
ptmp->next->jiffies -= ptmp->jiffies;

4 b% S: J( f! a5 L6 O) J6 q  T  [! C0 j+ V9 o! @7 q1 t
}//end ++

6 {/ |% e5 K1 l; c6 O2 p8 @7 ~* ~
else

" T( F" `% k1 d" X" r+ r& g4 {
( u# v& Y5 |' P0 H' O& o$ U) d{

" C! `! l1 ^. u- d* p$ {/ V# E1 N% X. j2 I1 Z/ N- ^
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))7 _* P" v/ l8 U& s+ U
$ ?) c) }- X  I) D
1 O, f) a5 H" g- S! T( X6 M! w' D  i
{

* S; `+ ?! g( X0 H1 [* ^
0 J. I+ Z) H) _/ \" w0 x  g" d+ d, Nptmp->jiffies -= ptmp->next->jiffies;

+ l4 g2 T7 e  d4 R1 ~2 n  Y) E8 R4 k9 N. P
callback = ptmp->callback;
# K! S5 o5 [, X( p
. Q1 }* ]+ v, R/ q6 ^& i) E6 m( s
ptmp->callback = ptmp->next->callback;
7 o, U3 F. I. T( ?( L, N# H

1 ~6 g1 q/ C3 l( ^* D7 Bptmp->next->callback = callback;
: {9 S2 K9 R7 o* I

: |4 P& W' r0 V( O7 Vjiffies = ptmp->jiffies;
9 \/ j5 p, E" \0 ^
" z% X0 U5 X" ^' f3 {5 l/ S
ptmp->jiffies = ptmp->next->jiffies;
, C  }1 k8 Y% @" Y2 d7 R8 N
2 v  L  q* v; R0 _" U" A
ptmp->next->jiffies = jiffies;
+ ]* T3 d! \* m2 p
2 H5 k4 Q5 b6 R8 C  u# Z
ptmp = ptmp->next;

7 m! T  L6 s* |( S$ n' B/ Z) E7 \& ]2 [1 r3 g" Y9 i  t
}
9 }" k- z/ `0 d* w
$ @: n/ \& Y; @
}

' c' l5 P4 r: q" o, x2 ~& {2 N5 Z" `# d- `) P. m9 G* ]3 O6 a" B( L, ?
EXIT:
! X1 V) {1 Z* R" m& [, B
2 u% ?4 c3 z. _; F' h2 k, iEA = 1;

' g4 G* h# W+ O" _4 Z/ s+ z/ Q
% o% d" J3 f  |0 Z7 W5 T4 w% `( hreturn;
& T" N3 K' d' y" y- z* C( C
}6 M2 |$ P: ^1 ~4 ^" b
& j7 r. B+ q( ?  _. g: s( G
void do_timer(void)# }( D3 q: ?3 o+ R2 B
{
1 k+ \0 x+ |! n; v  {# @
  I! a/ B; Z( }0 ?* F& s

, H4 m. M4 G$ t) _& ~1 T; t: B. \' d. Jwhile((timer_header != NULL)

$ p& E7 h) I0 D# ~- ^2 F$ Y
) i7 ?, G% V) w! J0 I4 D% e! l1 Y' J, A, V' c! O+ p' P! f
&&(timer_header->callback != NULL)
9 u' A' L3 w  I: F) _; |
# Y$ W8 Y; a2 P: G4 V
. d: d% S3 j& g5 ?8 O/ M
&&(--timer_header->jiffies <= 0))

# G& }4 p5 H/ j/ C
5 _) P# q( V5 k& T{

4 I9 _1 L/ q: a- D$ X# B" A
' z: `1 ?8 y2 B$ {! svoid (*callback_fptr)(void);

0 u$ E# k& i; F0 b. q6 p
3 O% t( u- x1 A) m! k7 X- ?& @& E" ?! A: P8 W
callback_fptr = timer_header->callback;

- i2 P& J$ C1 G7 _* z+ b" z
: w+ h1 ?; \* m9 w! D; btimer_header->callback = NULL;
9 w; M; _' T, p: x- h0 Q

, S8 E- m0 Q8 W( a* A- ktimer_header = timer_header->next;
. t& s! K1 w7 Z4 K* `
3 r6 u( j9 @3 w- X3 n2 {
(*callback_fptr)();
. ]1 ^5 Y! T7 R* x& L, b  k9 T0 E

. H0 @! H. a' p3 g3 T9 G- X/ a}
7 f) m$ W- H7 j* \2 Z, N
7 ^2 C* e+ B2 U5 n4 x2 \, t
1 N  A3 J# J, B0 S' f3 q  i
}* q1 g& ]9 L9 F, @: \% `6 m
///////////////////////////////////////////////////& Q' T2 U2 d8 |
+ a$ C( t" g+ w. `  u. a# \
% X* l: ?" W6 T( ^2 s
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
9 N1 V2 {& s9 i" ^: w" F' H  p* s- D5 t7 F. ~9 O, z5 D, B: L
野人献曝,博君一笑# i' R  ^( h+ a
6 ]: Z4 @: m/ x
Peter& p/ D4 K) D9 @# v& l  Y
  ( E( F/ O' R0 `# l* l5 V0 K, ?6 k1 h1 U
6 W4 L/ O  }# T! ?. P, j5 _7 z4 y3 v
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-5-16 07:34 , Processed in 0.042492 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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