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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
7 ]6 z2 T5 A6 W3 F3 `# D  i
9 e6 R  j$ `# a) u  E6 B
1. Why need this mechanism
" Z# F1 L; l+ |0 A$ I$ c( `  L' h$ l+ M+ W7 Q$ h7 Q
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
/ x3 @! \7 Y' O- G% Z1 o/ E* g4 k( [

4 K4 I% G) [0 W9 b# ^2. How to improve it?! q9 ]& U4 Q1 x$ u5 u
0 s; H: g9 V$ b) A
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code+ @" k! t" u$ H: x' z- x
, G, h1 h$ p" l$ q, R
//header file7 ^+ {  E3 ^4 W0 |
/////////////////////////////////////////////////
3 G) I3 L: Z  R( _#ifndef0 R7 s: z, S! c* w- o  L* A
OEM_TIMER_SERVICE__H

1 D$ o  R* y+ b6 o! n( C#define
* A! E3 S: }9 \+ y- VOEM_TIMER_SERVIEC__H

$ q# P/ X! z1 R/ r! F$ J- Z- \8 ^7 t1 s3 }- G% C3 ?

7 |  N8 s4 Y" g' g5 H% o! ~: F0 \void add_timer(unsigned short
. Q& U8 Y: I! r$ R  N0 e! e  _0 Bjiffies,void (*callback)());
5 r* v# @! z0 A$ Z; F
4 i( y0 t8 K; w! Q1 ]! z$ q
void do_timer(void);
" _3 K& z) B! F2 A  j/ @( Y9 O0 b2 I
#endif. p/ F6 _0 ]) R9 ^8 t) ^
/////////////////////////////////////////////////& M5 Z8 ]/ Q0 Z  l1 X* O% ~
/////////////////////////////////////////////////
8 e, Z! @7 P0 @4 J0 a//impl file/ @" Z* I+ i5 u) Y- e0 |: k7 Q& B
#include <stdio.h>! q$ H1 A7 s5 f
#include "OEMTimerService.H"; r- A9 ]  B. O- D5 C3 a* s4 ?0 i  ^

5 o6 z2 k$ v) H) T5 A, }3 x; c+ ~* e
#define  q! v% k+ K0 E3 K$ }5 g5 [. i+ W
TIMER_REQUESTS
5 z) v0 F# K3 o- R0x30
2 S& }+ Z' v) p$ O2 ?

# E" N% Z3 x3 i- u! b" istruct timer_list 4 u! b1 [" e& _: t7 M
{
' {) L2 ~! z* j7 d& d, B, S
& @$ Z* z, Z- ^$ E4 Q7 s; A1 K& y3 nstruct timer_list *next;

. @* u: L+ T$ `$ o
9 t" q( ?5 F0 Kunsigned short jiffies;
$ m# \( _5 e6 Y' K! ^, o) e
" m( r. Y8 y3 J" D. P; D
void (*callback)(void);
+ d% j# M/ w& q: |
};
. C+ M) N0 ?* |* Q: n" t4 Y
, P6 P' t/ Z8 I6 f' U
8 S5 K. |9 Y- ^3 gstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};1 X7 i! J2 b7 p! g- r/ H# s" E1 r
" J9 H0 e; G  T1 W; F" A/ _
struct timer_list *timer_header = NULL;
( x' @" @" `1 ~( T" p! l9 k$ a6 |! N

: m, \: l  g( G( ~- ?- R8 ~void add_timer(unsigned short
3 l! x( Q; j, ijiffies,void (*callback)())

8 J1 B. o4 j% Q4 V$ t; r{# r$ I# E9 `3 g2 H% |* x. d

9 t1 a, e7 [" fstruct timer_list *ptmp;

; f& L1 G* T! A! g4 x
1 a4 \  G. [. @" |+ G9 ?& k4 S2 G0 y" `1 K' r
if(!callback)

3 S* A/ [# z5 `
: T1 G1 o- E5 jreturn ;

9 r+ x7 B; z' c& c  Q1 d' K5 g: R8 b+ e" W$ ?5 I

6 T+ C% a  F* B' @/ y8 `1 q& O
9 ?& |$ Y) G9 P/ s: J$ o$ \: XEA = 0;

% }. i7 i% x- V" x) n2 W
) w9 H) |( z1 |  O6 R) k# B7 I) y/ U7 g' o% \( d
if(jiffies <= 0)
3 X; H# |- \- r7 S( S# U6 B) e
! n# C* O* D7 S8 _# j& T8 R) q
(*callback)();

' L: ~. z2 ~+ ]* Z9 d: c
* T& Y, p1 U5 r7 V  G  {- L

- B* e+ C; Q, m7 q+ k3 ~2 r: m/ y! K5 v% o; h
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

4 E4 [5 A. J( z2 S/ o/ ?0 v6 D% a1 I* e
if(ptmp->callback == NULL)
% o8 F4 _* _; @7 n6 q+ H' }
0 d: H( H! U! v5 L; o+ _
break;
" F8 e2 ]3 m- `; ^) E8 Y# h

, m0 B! _+ a; x$ ]0 t8 ?! a& Q' v; J0 ]( e) z8 B
+ L# W1 o, r; r
if(ptmp >= timer_list + TIMER_REQUESTS)
; H3 c* h9 ^  D

3 }/ i  E! Q. z4 m{

% T' D2 L  w5 S+ ?* f
( J6 C0 Y# j" Egoto EXIT;

0 v$ @' o& ^) Y% K  W* e8 G/ S% q1 N: I2 Z2 p5 L
}
' u% k" c/ ]" Y% f. u4 T7 U
& f. t+ N: x: p7 g

: m  E) j# F& `/ @ptmp->jiffies = jiffies;
# {, a0 i5 O4 U9 @, Z8 Z8 y7 U

# J, e# ]+ S6 Q: x0 A( @& i; Rptmp->callback = callback;

# [% t, K" \  V) A/ I. A* S7 l; L, W4 m) z
* g/ R! M; l: M) Z9 b, ~& Q

8 m& ?+ o9 J0 Xptmp->next = timer_header;

6 W7 C6 t* j0 d7 K' K
/ H$ s. Y5 b1 m: g- b4 h' S. f; ntimer_header = ptmp;

* @$ [  y) ]. Y4 h9 Z- l, {! B( O( ^* t" d& i2 P7 H/ b

; v3 N; A, s* T5 ^5 y//add bellow code to fix linux on timer’s bugs ++
% c, g( Q2 \/ g
) V* t. `! J( I" e: T& W( O3 ^
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
/ b2 h' t4 ~6 c  d
+ t2 y9 L7 @  A2 Q% e2 @6 B
{

' {6 K. E" k9 K0 M, `+ G% z) p& h6 `+ O( ?3 S3 e: T& C) c: c
ptmp->next->jiffies -= ptmp->jiffies;
; t1 @8 ?2 k! k7 _
7 y1 t" O! X1 ~" f* C6 `/ Q% i9 l
}//end ++
  k) P3 a' {$ Q
, {% `! d1 O4 y7 }. d  M
else

8 Q! q) Y3 V4 ~2 p" i3 t; C0 C5 U4 E8 a  j4 F6 i, A3 _
{
& o3 ]% Q4 }4 b

+ q' T* f0 K! {/ B% uwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))* H, v/ Z9 _" j. W1 Q1 A
! t6 c" d1 \& z1 v' T( h
- T8 {! B; B' C7 }  o* ?
{

. t# X$ R( I! t6 o0 E/ m
8 H- f0 L) ^0 V4 Q5 Y, Sptmp->jiffies -= ptmp->next->jiffies;
6 _% {2 k/ g! \

8 p! t6 K: w1 K, X* |8 scallback = ptmp->callback;
3 v8 u& t  l2 v- |+ v) \
% @: c; k2 ^2 |0 M0 h
ptmp->callback = ptmp->next->callback;
/ y9 t  F4 z- K" {5 Y

) y8 M2 c" R% n& n2 @3 Lptmp->next->callback = callback;

4 u3 |* k5 C# C7 J5 s! V& t: s6 G! n' l& F
jiffies = ptmp->jiffies;
9 N3 @% F3 g( {+ b" k
- ?! i7 k9 d. e$ k5 `
ptmp->jiffies = ptmp->next->jiffies;

  g/ M/ C. ]' r6 q; r. i* ~
. K! ]. H" Z2 z+ optmp->next->jiffies = jiffies;

9 d; ~4 g: I8 S8 }0 r, N4 F8 P
; p8 s7 g) H$ t' c4 e6 aptmp = ptmp->next;

7 k! e( S# F# ]0 G& Y- v
( v5 l# |, S, F9 i  e}

- i) n( E: l, g  l% \6 I0 N7 d% N; C
}

9 \! l# w% w, ]; O$ s
4 `1 c5 g8 o: S3 L! P3 Z) bEXIT:
7 Z; x" e( T* K& m) \! D' l5 n* ?/ w. b3 y4 g5 b; L/ M: s
EA = 1;
/ {& H( s* o$ B: L: Z

1 g* i( a; y$ \" J& Zreturn;

/ z/ _% M# y3 {# d" b. P2 z}
; |! f0 p/ E& ?$ W( q" Y2 a) V0 S$ R# u! W
void do_timer(void)
8 H" Y) F( i, @6 v' m{
/ c' ^: j4 A+ f/ o
) d. o8 d/ G3 Q( @
( E& a+ b+ o. ~$ b
while((timer_header != NULL)
- I0 E, I: g2 @$ X( o, x( G

& O) F  c0 i( g3 p9 z, ^
& }& e+ ]7 L  U&&(timer_header->callback != NULL)
9 J8 I" o; L. M3 B8 k- V( u6 Z
1 n# [8 A7 f. l: u6 F! L

* j, ]9 o* j; n. Q: Z&&(--timer_header->jiffies <= 0))
' h/ g8 N/ u; f2 ]- Y
( Z7 K4 ]9 O8 h: q; T- w9 x0 p7 C
{

8 k. U: u% \% V' t5 {6 \3 t
- o( \" j% ~3 V! X# e$ ^void (*callback_fptr)(void);

% X$ {, i5 ]/ s) M" M# @/ ?; }
. o9 }+ n5 q6 h$ U- k: b4 w
% }) j6 b1 n/ G. c. Xcallback_fptr = timer_header->callback;

7 G9 L- T/ G2 s( N5 w
+ O, e* R( B5 k7 @; ?0 l/ y7 _  htimer_header->callback = NULL;

/ v/ l3 r8 _- _; Y' @
! \4 {6 J. s5 Q; i  f1 t( v- mtimer_header = timer_header->next;

7 R+ _/ u' {8 S- X2 f! L
- [. O' X, V& j0 A9 e(*callback_fptr)();
5 i' Q3 P. {7 K6 P! r& }: l
3 s9 x2 M5 f- O, [/ Q0 |
}
5 T' A5 s, m2 S0 |  O

, R# ^  f5 }& s8 j5 |! _3 \
9 q, u$ l8 K6 v8 F8 l  J- S
}
+ \7 y) U2 d# [/ X: o, ^///////////////////////////////////////////////////
& b3 q2 Q0 f6 f- J$ x$ m# ^( C# [; c" Y+ `0 ~6 B" v

! l& D8 Z3 {% w+ U上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!; A! t  G9 Z: I* Y; a) o
- k: ^4 @& u. N# S' C
野人献曝,博君一笑( a2 A! T) T: {6 ^1 N9 x
; b2 e" h/ ]  S+ D% z
Peter4 ]2 z/ j" x( ~' C
  
9 m: k6 c- m; b0 j( Z' E* X9 ~; A
1 ~1 S% h, g# J% K7 H: `! k) v[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-4 14:44 , Processed in 0.397195 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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