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

Smart Timing Mechanism

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

0 M# I. Z5 r2 [5 l1 W( ?
$ f+ V5 H1 _3 g8 A
1. Why need this mechanism+ g) ?. n! ^/ c

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

( d' R* G& ~, ]" {& R+ l5 A+ k4 F4 H/ {: @3 O
2. How to improve it?' ]: c$ k, r& c

/ K: k1 {4 a( y  k2 D3 ]  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
/ j1 o' U* U2 q1 `0 {- i! ~# K5 U6 {6 U  x$ Y6 r8 U1 ^; f) Q; i
//header file, T4 m* e1 J' I, k7 T8 _5 y9 D" v
/////////////////////////////////////////////////
) G$ k. j/ [7 v. [% ?7 ~0 X#ifndef
, S) Y7 F/ [+ P% xOEM_TIMER_SERVICE__H

8 Y/ D' v* K" P' _#define2 ~3 W6 q3 a, {$ q: }/ i* T
OEM_TIMER_SERVIEC__H
8 e! v4 p/ ^  D( c( g
. a# r6 m2 n9 B/ W

0 i0 r1 _9 l  c! c+ pvoid add_timer(unsigned short2 ?' x' S. S  a' g/ O8 A$ Z
jiffies,void (*callback)());

! m/ S0 W  A6 s- |' t( ]* }& L7 k. \$ S( @' p2 \4 |1 ]' x
void do_timer(void);! K# T1 E8 z3 |7 z* w
5 t9 o" o- y! e" y
#endif1 j4 L9 _8 o' j! B) D7 e) m  }
/////////////////////////////////////////////////
  O/ d9 B8 [5 _/////////////////////////////////////////////////
. h: z7 H4 e: Z- b$ i7 x" x/ [//impl file
# z) E" T* Q' c: h- V* |#include <stdio.h>) w. P* n7 I# J  H% e; E/ O6 Q
#include "OEMTimerService.H"
% H/ {6 A) b6 ^6 u4 K2 W% G1 b, Q) `7 z; ~2 m1 U0 W

: u2 s  s/ _# Y2 v( w#define
+ G" f  x1 _  uTIMER_REQUESTS
) u8 [. a. [1 r# T% q1 r) G, i0x30

- \, Y5 u/ O- t0 M% p. c7 Y' K1 Z3 f+ j% w+ p0 i& G$ L
struct timer_list
3 t. x& N5 p: m- r/ Z0 k{4 z6 x. g) l4 n- S% q
7 D7 ?6 a; T* k+ E
struct timer_list *next;
# X# S4 `  V; V/ L2 l" ^
) W+ q/ n9 `8 Q2 p: ]5 f
unsigned short jiffies;
! N' z0 `7 \+ |
: Y2 n$ J) i+ O0 j  g" }4 y" t' u
void (*callback)(void);

0 s* d- _. i% {7 u; e  `( F4 ~2 |' C};
# ^; L2 m1 c! Y* y# }5 |- A- d( l
. e  H+ G) y6 `. H0 L, y; T9 ]# ^/ [+ `
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};) `5 h9 u3 y1 C; X

6 H) t+ N! I$ q& m7 hstruct timer_list *timer_header = NULL;) O/ ], L1 f3 @2 v

% ^# S5 T: S% N. y" J8 m
1 O7 L/ b% |1 M4 Avoid add_timer(unsigned short) D; {9 F) H8 K% E
jiffies,void (*callback)())

" i: U3 d1 N( E( T- `{5 _! T/ S: n, u' K6 H0 R
, U) |! B8 [! B
struct timer_list *ptmp;

2 V1 D, y( w8 F" w" L1 R% W; m6 O2 j9 N6 S
8 @- H3 K! Q% `) ?
if(!callback)

0 u6 V5 Z  Z3 U- b3 X# k: G
% w9 b1 d" o' [3 C9 @0 @/ i2 qreturn ;

0 H# g6 T% b& e* d* J2 m& N/ H, w: G9 p

; `! x1 J1 G- [  ~/ F" `
  ~; Z* S* _1 M' k4 C) fEA = 0;

) Z. t, z9 B1 N0 L3 s3 b2 }. f# D- H' h& Y
1 l! B4 F0 c4 Q  f; T- c1 Z1 u0 b
if(jiffies <= 0)
2 }5 q! i+ l' U& U3 G# L) q- h
- s3 ^! O4 W" T! g9 j" M+ J
(*callback)();
& @5 r1 _+ D$ E

! Z) X, s  J! x! o/ N

( D7 |" c/ ~( K% O; X1 a0 y& r7 K- a! T! {# z0 O
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

8 _) s+ h& S$ f% Q+ q& H( ]7 C  L  K- v9 ^& T! X
if(ptmp->callback == NULL)
2 h1 Q4 ?2 x; p! j. Y4 |/ x; Q

9 {$ ]% b  `7 s1 B. abreak;
3 D; [9 ?6 w+ K
9 @& K* R4 x: Q& E3 Y2 `: e4 D

0 J9 X1 p# w' P- d. y6 e5 B( b2 u
if(ptmp >= timer_list + TIMER_REQUESTS)
7 w" h& N) k1 q6 _
: [2 u$ d5 y  Z% }2 f+ X9 M
{
- ]5 y! C7 J+ T0 [5 R4 F% q9 `5 N
, g" w& P% t  C" k
goto EXIT;
0 p8 n+ k$ A9 G7 @1 t
; W4 N" k3 \7 Q" i, L
}
3 Y9 D/ w* q  ^4 A4 [* r" @# M7 [$ [' _
1 T' d4 a, D9 o5 E) u+ v
: @% F6 w5 I4 j7 S0 H
ptmp->jiffies = jiffies;

& s4 O9 ?8 r& E' r/ |& Q6 W& f; J, D1 v& b; @
ptmp->callback = callback;
" F% G% ?, a% @3 R) {

6 G6 k. S! B$ S) w3 P: T2 k

- u/ G: A- b# C9 V
4 @2 g$ X' y' H2 R# V1 Kptmp->next = timer_header;

3 O- ]! C. Z! f5 \5 l& i3 }  h8 v5 k5 y- l! n4 a0 [; f  N0 r
timer_header = ptmp;

# D- Y  ]5 Y9 s' i/ n
# H" {# s0 `7 U: h0 r* R8 y  O: O& f7 r" ^# Z) f# W
//add bellow code to fix linux on timer’s bugs ++

/ U2 Z2 Y( A, K* H/ ^
3 r$ D0 P* S; }9 N% |+ u& Eif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
. u; l* \& _4 J

% c0 P1 L5 ?# I5 j, ^0 A9 z{

7 _+ b6 i( p) `: d0 R2 |0 k
0 v. M5 Q' O5 iptmp->next->jiffies -= ptmp->jiffies;
' ~4 H# x) \+ Q: T% _
9 g. f7 c+ ?# y4 V: i) B
}//end ++
. _" F, S$ O! E
7 Y1 T, U4 e$ t4 x/ G' r& `; y
else

' s; [! a7 B5 P% U4 W2 ]6 [- w# N0 x2 ]! ]
{
! p3 q) @7 u8 m% j

( f# Y+ ]$ j$ \6 E9 s1 Uwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
0 h% ^! I6 R+ T: n* x# q' T
4 d8 I' n4 n* `0 c& R2 p  j

0 u( Y( o0 Y) r8 N$ ^" n) E; o1 X{

0 \- y  Z( K/ p6 R- y* @, h: [- u9 U: H3 |, i$ T* ^- A
ptmp->jiffies -= ptmp->next->jiffies;

; I+ y9 w2 p. B" e! c% ]( a6 i" B* S3 i" n/ }( X- b8 C
callback = ptmp->callback;
3 L4 b1 q( [. i& D, D" u  c

) N. t5 U  d4 m+ `, j  ]' _$ s1 Jptmp->callback = ptmp->next->callback;

. M/ |0 y( k1 j# s& y4 h
4 b9 E. J5 R1 h2 a1 Vptmp->next->callback = callback;
( b/ H9 y$ \: N6 r5 i$ j
! L; n4 X" G+ B& q$ E; g  B
jiffies = ptmp->jiffies;

0 |3 l2 t6 {. p3 F" z' I. ?
& C: E0 ]# O8 W7 Yptmp->jiffies = ptmp->next->jiffies;

4 W2 A% I; K5 }9 Y+ l. }
/ R$ [( u9 O( f# l% F& Optmp->next->jiffies = jiffies;

1 U! g8 E! C- [$ @' P( P* o' d6 g; O& G: U6 m. }. a/ Q
ptmp = ptmp->next;
5 C9 [7 D! s( f' w# V) Y, j
" z% @# h; a/ K+ H- K
}

* [; q2 X4 A/ f0 E8 c% h! Q$ k8 N8 t# b# R9 f2 x* l
}
: c8 Q& H; K8 b7 B+ Y. a& p" ?- ]
' j% u9 d4 }& ~) l6 ?7 h& U3 p% L
EXIT:8 o9 b8 Y; H+ P& w; R
0 P" g7 H0 |* }$ O3 |2 H
EA = 1;

& s, b& H' I3 X& `' \2 ^- J8 f5 F# m& z/ O" x# P! r
return;
' k0 \8 `* ?  g5 w! d
}
1 F2 _( E* v0 ^# Z, p; |/ C/ ~9 d8 M3 X, |  C+ Z
void do_timer(void)
! \4 X1 }% A$ W{6 l, U/ I0 z* ^( h( S' x
+ d! ~5 `- z2 g+ _2 J+ R

! d4 ?' ?, ]) W) t) y$ _while((timer_header != NULL)

+ q1 n0 ?0 K: H7 n% u$ N, G9 c, X" m0 y& j, C, E( x' P
7 h/ I+ l# e4 l: ]# z2 V
&&(timer_header->callback != NULL)
  W) Y! x) M0 b3 L( k
) k& z5 A! W% b0 G! d7 `5 f/ r6 R

2 Y8 B- I" Y+ @6 i! M&&(--timer_header->jiffies <= 0))
, {$ F# D1 u# k- L$ V; j+ `

- R9 f# o3 S; I" i& O" V; e) J) E{
" y1 d% T* W3 Z' @$ n( q0 ]2 {9 P! i

1 X4 ?0 p$ }% j& ], Dvoid (*callback_fptr)(void);

7 _, M, x8 }9 |! l8 F0 ^; ?3 @# H& d: ?

& X, g% `4 }% }+ a) x5 Ucallback_fptr = timer_header->callback;
5 ~- M- ~8 f8 f* h
% t" m6 U  y" |, _
timer_header->callback = NULL;
5 p8 {7 M( ^; o( H) t

  p/ k4 s9 i5 F% {2 D2 ?8 m8 T+ Atimer_header = timer_header->next;
. G5 {- p$ w6 K9 ]
0 b: L2 T: C. F
(*callback_fptr)();
* S8 Z2 U) r9 K0 f: C/ Y
: d0 l# N, Q9 j
}

2 Q* P/ h. v- a! J. O. n9 f) N

/ _$ s) E; V8 W% B3 v; u! w2 h. ^& D}
" D( A3 Q; x% p# u$ [///////////////////////////////////////////////////
8 \5 j4 b' ]6 ^) ?2 h; c% B. x# k
' }' ]8 i! W; _- m' {

: y. K- m0 @% Y" n. [上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
7 _% b3 p8 R) p6 t3 o& H: T; J6 A( u; a
野人献曝,博君一笑' E( H" x- j' w& c3 e  u
( ?' }' l% L& f% a& L
Peter3 f9 \4 W* H3 V
  ) C2 K$ X' h3 M3 X: B
& l, j; R) H4 b3 E
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-1-18 21:17 , Processed in 0.130138 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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