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

Smart Timing Mechanism

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

8 _+ R; U0 `# h% Z' r& Z+ P/ B

: m0 Z# b: p6 B+ {" ^8 l1 Q: n1. Why need this mechanism6 `% z* `( C. K- ~
) }) I  s' L9 q- A
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
6 \8 I4 p1 e) @5 k" r' h( L; K
$ M* Q! }. Q/ b  D
2. How to improve it?! N4 g/ l2 Y. [0 b6 D
$ }. r9 _+ i$ p/ U
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
9 S( w/ I9 \  k- a7 s; p% i
- D; P/ m$ r2 ~! ^5 |) C* Q+ Z//header file
1 ?( P2 W& Z) \& Y/////////////////////////////////////////////////7 j! j! \7 u8 L. c. Y1 Z7 i% h
#ifndef3 D, e0 q: G2 j$ ^
OEM_TIMER_SERVICE__H
' K) r8 B" v: b2 F8 _. J, T& O* M2 }
#define( x3 `7 G" T( R8 }7 X6 H9 ]/ n
OEM_TIMER_SERVIEC__H
2 V  e( M/ ]* e9 S

2 n7 j7 `7 N( h! [1 v/ n" `( r' _) {3 ~. c+ E1 P
void add_timer(unsigned short# m+ r) P  d9 Q' e* L# |& V
jiffies,void (*callback)());
8 H9 m$ D2 c7 i- [2 @' J; w/ w. H6 B
8 L( A- U: y3 z+ M) ?8 B. p% z: @
void do_timer(void);& y0 ^0 l2 m% B* }) L
+ W7 G% j, C& z. v  N" @& }
#endif; B" p. w, `4 @7 _
/////////////////////////////////////////////////
. x- I( a4 c- n/ V( {1 D0 y- O/////////////////////////////////////////////////; g$ }( l! v9 t+ N
//impl file+ G8 u' p, O2 z& S
#include <stdio.h>6 d0 `4 ?4 K/ H" S% \$ F8 d  z
#include "OEMTimerService.H"2 G6 a6 P! u0 D+ w- g2 Y- f

& }+ P3 Q6 B1 b
$ b, e- ]  x: r9 e& H, q$ I#define
. T8 x4 y) f- q& GTIMER_REQUESTS
0 L2 B0 L  E, t7 O, S& W6 W* i0x30

; |6 E7 z& v5 a1 N; D1 t, f6 q, t0 N  p) ^+ ]  X
struct timer_list * A/ f. P/ q' `
{
5 X3 s$ m1 i* F* f2 H( B
$ i, a4 a5 i" [+ qstruct timer_list *next;

) }0 h6 Z) T  G/ p9 C  u4 ]$ O9 N2 l1 l2 K( P1 ~  {( Z. B7 m
unsigned short jiffies;
( g+ r5 ]( T( i. x0 H; v

7 E$ C0 G. }4 B, \! a) F$ ~* Y; fvoid (*callback)(void);
+ @5 q9 |. T# a) }( I  g" u+ q, G
};* z, H* K0 N0 y3 [1 \
7 Z' t! `" W( u6 M+ R' G& ~
9 O4 @' s. T/ K$ k9 k- v
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
# P) r" h, d( @* T; J% n; ?$ w* S. ~, d0 F# K$ ~3 ~0 R
struct timer_list *timer_header = NULL;& V1 Y) l, k: J) U* `1 I  o
! Q, R3 E% V+ C

4 k- ~: I; J1 A& Gvoid add_timer(unsigned short
0 {( Z" S; ^4 U/ K: Y$ Njiffies,void (*callback)())
+ F& E5 G& s1 p. z
{! U! m; _  o; O8 ?/ _

! s  ?- H! b) d+ ^struct timer_list *ptmp;
. H  `6 h( r3 @$ }9 k& r$ r  U+ @

1 P5 O4 ~9 ~  j9 h; o9 L, r2 e
; V0 {6 V& }$ R' S. Wif(!callback)
' X0 {8 _- W  {7 s

) j+ |  h" T+ Ureturn ;
5 |5 g* u6 ^4 I8 a7 }* ~
1 w, W4 K  V) u- C2 Y6 R9 f, N+ Z) H% [

0 X, ?" O7 F9 ]& [0 K) ]- X& Q: T2 _& q: q5 G! w
EA = 0;

, y. k7 @5 f; k* H& e
4 y5 K% q5 D/ {  @7 {/ z+ u6 D6 D: ~/ q4 a1 Z
if(jiffies <= 0)

8 ]: Q+ l) y& v; j3 m) l
' N! S. H) A. h0 x. C(*callback)();

4 ], D, d; L7 E& V$ ~% J; D2 D; N9 s" l# v# _7 v" R

* u2 b" v) i* c2 G$ ?6 U$ ?: J
$ m( b+ _5 N+ @2 ^; hfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

, |3 T* {' k0 t0 S+ O* r7 p4 a' `  x
if(ptmp->callback == NULL)
5 e" P9 g5 E  d) i! Z9 T

; R$ I6 E/ k. J5 Ebreak;

3 {! f# Z/ |+ f6 g1 ^. G$ E& L5 k
) x( o$ P. Y/ h4 ~9 ?
. v, z( n' G7 Z6 u5 i0 h
- V& G8 T' Z6 k! G, hif(ptmp >= timer_list + TIMER_REQUESTS)
  w* w+ q% w7 J) r  h4 Z( v8 j

, k. X& J1 E* M, e9 s; H{
( Q% ]7 _" a" u2 a# Q& I2 Y8 M4 V2 k
  O/ z1 @1 r1 F! }2 O! i+ ~4 O
goto EXIT;
% [# Q5 I1 x* S2 q1 |
1 v$ v/ s5 B+ \; `
}
- [; u* `8 @' H/ e  y  x

$ w( i9 z& \: g
, p" T# b1 F, S; O9 t* n# L! e: ?# }0 T4 Eptmp->jiffies = jiffies;
: s: m& x& @/ E; ?

) s8 M" L+ N0 D* H4 Optmp->callback = callback;

% X, ]  z" ?- q( @0 h: C- R" h- N3 E
8 J2 f0 r  @2 G3 ^
6 Z& A% R4 s, x5 s4 {2 N
ptmp->next = timer_header;

; K8 a8 A  b5 a# r& B( ]0 w0 r! F# W
timer_header = ptmp;

- O4 }- y9 n6 x+ Z5 Y. C& f" E8 }

5 E! O1 s3 f: C9 F, U$ ]/ ~% V//add bellow code to fix linux on timer’s bugs ++

; ]" I3 K- ~! \9 U4 m6 D" |
. c4 Z, @& j$ T3 ]3 Z& l5 xif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

9 u8 E2 S5 k. T, h  ^% f( X; R6 b+ d5 Q" h) u: h
{
3 F3 W( S; M4 K9 T2 g& ?; O% P

' ?' l* y1 B9 ]6 @ptmp->next->jiffies -= ptmp->jiffies;

( w) S( r" H) B3 }8 n1 C# T
) a6 I) A0 v9 v# O/ N% G}//end ++

: w# g& |7 B0 E! u/ g! ]
; \2 V1 L- B- k, _7 `) f7 k' u( {else
0 [1 d) r+ ?' _1 J% }
2 _7 A. o) ~: K' u9 n3 F
{
6 \1 ]8 _7 y8 V; t, F
; E2 A' j5 D3 ]: H3 L" X2 G; L; }
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))" G6 e" {/ E7 m# i# c5 h- N

, X) c* m; n9 C' Q8 G* P5 X2 l% V. B7 h# j. D  I( L
{
) M1 v1 d7 N. `4 e- N7 n

5 n& \1 j! x5 a: T) eptmp->jiffies -= ptmp->next->jiffies;
& x* g  s6 y5 a2 |$ D

! d) Z9 N2 N8 R2 Ucallback = ptmp->callback;
  U3 ]8 y% x2 k( L
7 [5 U1 Z% g4 z
ptmp->callback = ptmp->next->callback;

; A  ^) u; ?6 A9 x+ ?2 h1 P
. H! c. R9 F# f2 U; W- U5 Gptmp->next->callback = callback;

) J! l1 p: u. O6 _, m7 m9 D) z9 {" q
  @1 n5 {# K5 C$ d4 _jiffies = ptmp->jiffies;

, A) N4 {4 ~8 [. F( W
+ C* K* W  q1 o. p; Iptmp->jiffies = ptmp->next->jiffies;
# E$ q* ]3 G# r+ l
+ T4 ]! x( ^* ^8 q6 O1 W/ g) E
ptmp->next->jiffies = jiffies;
8 g  A3 E5 e2 C
7 t% p+ Z& F4 J# j8 B% ~; D3 R
ptmp = ptmp->next;

9 p! x+ @6 y9 k4 M
0 T/ u2 p* Q, G8 d: H}
; A) O4 M0 x* O5 B5 Y+ \: |% H
5 M: J7 \+ \( |2 E$ g: B
}
* z$ j9 |# q! a% C! D, f0 y
# z7 V$ T1 s. o( ^& o3 W
EXIT:
/ T' ]2 R) g! T7 t8 b" U
# `8 S' {( B, |8 c4 eEA = 1;
% A! ]) \# m, }, ?7 T

3 X0 d) X% ~" }! |  d) Preturn;
! r* @6 l+ J* }+ r$ T
}) T1 a7 w5 a+ v7 C8 {4 Q" y$ X
7 ^& ^) @9 I+ s) |  ^4 I
void do_timer(void)
( t  T) Q* ~9 r" R6 c" a5 E- m{1 W+ V' o% m3 ~3 \) T( k( I5 i) o
' P3 N7 T, e; J8 v

9 a2 }, ?$ g/ N- Y* A& X+ Dwhile((timer_header != NULL)

! o3 B4 `* r: ^8 u5 d4 c; s
4 w1 a* L) F% R( P1 t; b6 u/ O) D1 H7 W) u% b9 A& S
&&(timer_header->callback != NULL)
! ?, \- J: W) t& Z7 W

+ L: f( E9 \& v: m1 J. y% X5 i) w- i. w1 ^
&&(--timer_header->jiffies <= 0))
2 G/ T: h  d9 c- y- x

1 {1 B6 L  V) \  l/ }" I{

& G& [0 X3 C% P) c0 {; Q% P0 y; K+ y7 w4 e' k
void (*callback_fptr)(void);

# ~5 v$ q0 `" S, j/ R+ g+ ?6 N3 k& Q/ v( q, D; S4 Y

+ n  z) l7 A' R. N- Xcallback_fptr = timer_header->callback;

. A/ v* t" k$ X* P- @
4 g, s7 A) L; {6 N4 x$ wtimer_header->callback = NULL;

) E0 z' A* y) |' U
) T. U8 S$ d, f: r+ g$ {2 X- ytimer_header = timer_header->next;

# z- k2 o: o& L  x" f% R% M6 t
: g- B' F. ~. f( Q  K0 r- s5 h(*callback_fptr)();

: d8 X( \+ J3 C2 {! {& t5 L2 W
7 j$ E0 z) p# W4 ]}
, Y" i' N* M  O6 T" S, A- T
4 q5 k! h1 j! L) w5 v1 C
/ l, x- w2 s; c# P4 U
}
5 U( g) V  f8 V4 g///////////////////////////////////////////////////" I4 u( |4 i$ }4 R" L/ n, T

$ {. h) g; _7 f5 i0 |8 r6 X. V; x
3 I8 P4 J5 V2 g! E
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
" i9 @9 D, `3 u, w* d: R, r+ t/ t6 R
野人献曝,博君一笑. D. O* J+ N- \, c: x4 b3 Q
: K1 F4 e2 m% f8 Q8 |
Peter
& ]3 w0 @. {3 j% c# w  
1 c) \% F7 T: w: p' U9 N, w3 V( \) K, z; Y# h
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-4-29 05:47 , Processed in 0.030468 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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