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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
) Z8 ~4 E6 b+ G2 g6 {& u& o+ Y+ P. E* _

& a- Z9 }2 w4 Z6 r; v; \1. Why need this mechanism
: i) f  G$ o/ L4 k% l
* ^  E, J7 c" W8 R  A$ e" w% _
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
% N3 h+ `7 B( a! p  s

: |8 o6 u1 ]$ D3 H) `" ~2. How to improve it?
2 ~5 s: i* ^" L1 X, T: U% {: ^/ G' z: X' }3 x) n
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code1 G! f2 d/ k9 y$ L6 {
5 E- K& _0 F% w/ _
//header file
2 j8 \: z; `  n0 a/////////////////////////////////////////////////
; S) {+ Q: J! z' l5 a- F#ifndef' n, S8 \0 ^6 _
OEM_TIMER_SERVICE__H

3 ^2 [0 g8 L5 P8 r) @#define
; p5 S" S  a- y* R& yOEM_TIMER_SERVIEC__H
* ~6 r3 j( u, O' N

5 O' Z; {6 J) a+ j6 Z, j6 c- V$ w. m4 Z
void add_timer(unsigned short; i) A2 x* Q! Z' G6 C* w% v
jiffies,void (*callback)());
" x& X) ?5 C9 p8 ?/ D2 r

! |& y8 ?# I  y' Ovoid do_timer(void);9 Q  g! L+ P% v; Y9 x

7 a, }5 o1 m, n! v* k' J3 A/ D* D#endif
% w" A$ T3 u) A$ @! A2 _5 ~1 F3 g/////////////////////////////////////////////////
9 ^6 t' J) i, @7 R7 y% i; \/////////////////////////////////////////////////
9 ^6 L+ \# e. L; d- r1 ]//impl file
- ?" @3 }/ V* x$ z  w#include <stdio.h>
, ]* |2 Z/ \6 ^2 e! T! C#include "OEMTimerService.H"4 P6 I& {$ E9 z4 f/ J, K9 c0 @1 D

! q/ {7 H, B; I9 J4 D- M* ?  d* [1 B4 s, C6 T6 `, M0 J
#define# \- ^0 B$ G5 i
TIMER_REQUESTS
4 V  s5 I2 i% ^3 _: d8 C0x30

& U* A0 a2 N& F# G" L8 W' k
+ t4 `$ w7 j8 {8 [) D: u6 P7 istruct timer_list / E5 X3 m4 y1 K2 u" a5 ^
{
! j! R. }9 y+ Y+ p4 K5 @- w8 [! g5 T, `# c% r% Y" O9 n' Q" l! w7 Z3 R
struct timer_list *next;

/ T  H2 ]. Z8 i6 g: X4 j+ I; @
( e5 F! H$ j. {0 K& P0 uunsigned short jiffies;

) f' C( }  l  X$ |0 q9 q4 F' o8 X+ G) H' P8 X  r9 V
void (*callback)(void);
. `- T9 m" a! N' `- s2 D0 o
};
! P' [8 a6 l( [0 [) M: h' R6 Y' t: ?6 _$ }

! M* r% K; j" \3 `. ?5 i5 t* Ustruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
- |$ L3 c. f, I  z: Y) l& k7 _) X' m; C- A- W
struct timer_list *timer_header = NULL;% X; D: P) N% H" u# q+ o

$ j! |% f$ n1 f" R: Y* J, j0 _) }2 q4 r. w: d" C, V/ o
void add_timer(unsigned short
) b2 y8 r, g: rjiffies,void (*callback)())
; {; C# n' [( F1 m6 m: G8 B4 _3 M) u
{
3 `9 h3 T& H. F% \, Q4 ~6 ?8 [" n. _6 I" l
struct timer_list *ptmp;
6 j' b( I% x. z" \' A

( j; |  k0 ]" [; G. s
; u8 f- ?7 e) @- rif(!callback)
+ D8 q, `  e& z; }7 B
/ G" \2 D8 ]+ p$ j* n1 U
return ;
& b, g3 |& g$ U! F

; k3 N2 w% y) ~$ l3 M0 A* C" v- l% ?

1 V& i' \9 m8 U2 G" Q' @9 }' A2 q# R6 b
EA = 0;
6 S' u) l: k* B/ R# W
& @  ?  w% Y* j* I
$ h! i$ p5 J7 c$ k7 r
if(jiffies <= 0)
( _, z- u- E" Z3 }% n  F
# J7 c. H* R4 s  X3 {6 L
(*callback)();
$ U9 j; Y6 ]$ D/ m0 [5 j

, v' w' H3 C. L: k

% r" V' {2 t$ [' X8 x) X
! z& h( n1 f3 f+ W! |. @. @* B  xfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

; X+ z2 o4 n0 }3 p: a: K% u5 {& ~9 K2 W* |6 X. o/ n( E! ?. i
if(ptmp->callback == NULL)
0 b3 Z* O! a; w7 r9 H' o
: \& V" v  j% h  l
break;

  q" W: |) z6 K" p. b  C- _3 T" y$ x4 e- \& k+ E+ z
2 d/ q4 a5 W. J2 B9 ~( x; R4 Y

$ p- N5 {1 b6 l8 H3 ~if(ptmp >= timer_list + TIMER_REQUESTS)
6 L8 p( ?" l7 [6 E

% @2 ^4 A, N' w+ |{

5 d* @3 g) v+ h8 G6 x$ B/ U  g7 A( L0 c; L: d
goto EXIT;
' z- B+ n) @) F" l: ~

  E! t5 o: C) @: s( P}

0 \  q% y5 F/ `) M+ c
( t! r5 p2 Q* t: J# e  W$ t* b! Y, r1 q2 h- a5 }* P) H
ptmp->jiffies = jiffies;

" Y# A/ W9 [# v1 K* Z% y0 W0 O( z$ Y2 ^# h3 m- Q, k4 b5 c! M
ptmp->callback = callback;
7 J& M* k9 {, K0 j: p% [) F  f
" C: D- U4 V* U, o2 ?2 a. v

8 F# q# M1 M- ]" q
  b# U$ ~# z7 S9 b% O" i( Aptmp->next = timer_header;

& U6 v! v7 O$ w* c1 p) a& \
" z- e: j  O- ^- V$ X$ u9 Ntimer_header = ptmp;

6 h. p, N. r+ f5 w( }5 j( Y5 F8 `3 b3 G+ m, V6 z. R' u, _/ v, q
! `! |( y3 ?0 W8 r+ u9 [
//add bellow code to fix linux on timer’s bugs ++
+ F/ H7 C& O- }

" E9 u0 U% Q6 l% p7 rif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
0 i* S! n; \% x& l3 k+ L2 a7 S
1 k* v8 a2 g9 p4 ?& ]6 c
{

; k9 S1 R5 }3 i. N" W; r' Z# S+ o8 g! b% V7 v& }% Q+ W
ptmp->next->jiffies -= ptmp->jiffies;
, }9 m* O" s' x% h

: p4 Y# ]8 D% s$ B}//end ++
9 h% [$ w) A/ g3 K( F" b

5 [% V, b! R. \1 ?" delse

* A% a* T0 j9 }4 Q2 c1 O3 S" p- A% f0 O2 d# [4 c% c
{
! k6 y$ d1 d0 a% B& H8 z% S- i% y
! L" _% U' G1 V/ x2 j
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))" _; I9 l3 g4 B$ O

: i& D+ W7 m( |% d+ W) U. O4 L
2 G" V6 w$ d/ g* _: K{
3 e; c- Q. `1 P2 I: o

, Q" G( i. [3 g& r* Cptmp->jiffies -= ptmp->next->jiffies;

: L1 T" Y6 Y- W9 U- ?- Y- n: j6 o. \8 O; `' v4 S% H7 @
callback = ptmp->callback;

: Q$ Q- r4 o# w& D6 V7 A
" W: ~4 I  _  u: G. H2 Rptmp->callback = ptmp->next->callback;
5 s' w: w0 ~! J) ?$ g9 |

' E9 B! y( S% u' ?4 ^5 j8 uptmp->next->callback = callback;
3 o% J$ D& A9 R
/ E9 a5 m$ J' M& _1 T2 T
jiffies = ptmp->jiffies;
! ?" f+ H+ ^; @7 ]4 I8 o

( d: H! f& H+ Hptmp->jiffies = ptmp->next->jiffies;

) t: C  t: n1 O( |$ S) b4 I( m2 f9 p+ ^4 l5 J) B, X: C
ptmp->next->jiffies = jiffies;

( ^3 I& P- Q: x! \; ]* B2 h6 C) F  d7 T! A; Y0 d$ P+ E
ptmp = ptmp->next;

- e$ Y+ z9 T5 R+ X6 v$ |9 T: S- N
1 X( b3 T' r% ^1 g( f5 G}

# s+ m7 ?, e  q5 F1 g+ }6 r! G7 ]
' [# [- V! ^# y4 r3 m/ q% `! D& ^}

- c2 A' A1 v% t( u& O6 g2 l
; z, J% d/ S1 ?3 `: i' m$ aEXIT:
, N8 |' ^& x2 u8 A6 B# X  k+ \+ H
7 Y3 [# d( Z1 i, ]" B1 q  wEA = 1;

1 A  R" q, C$ p/ S
# l7 J8 F' N7 f' @; f  Q" L; m# breturn;

) b$ Q1 I6 C4 {$ R& ]* O( x. {' y0 ?}1 ^  o0 n( H% N8 W$ C- b0 _

7 D& S" F5 i' b* C  r5 Y5 U# [void do_timer(void)
* a4 S2 h0 A6 F; @/ p, J4 F{* |9 B8 B7 X# ?# F

) A1 \! Q7 }* O# ^- T5 r' |# q" c0 L) Z1 @0 i
while((timer_header != NULL)
0 B. c, V; ?5 ]. T) G: ^
4 q% a( m4 l; E& b( `

4 `) y0 B5 J! h% Y- u/ }. R&&(timer_header->callback != NULL)

$ Z5 s) c7 ~# f/ `, A. i" D
6 u6 n4 s7 Z- \; ~% z0 x+ H( b9 u5 \& Q- r( f
&&(--timer_header->jiffies <= 0))
! W" S! d- }6 k) M
/ }; x4 `: B! p6 z, y9 v3 o
{
2 S" ~2 _2 y9 X& e

6 l; \2 u) x) m1 s$ H1 {void (*callback_fptr)(void);

* L1 q7 [: W/ v4 K/ Z( s( K+ X' w* q6 Y# t8 [  H/ Z
: g" @# G  C4 p' ?9 E. W
callback_fptr = timer_header->callback;

! c) S3 X1 A$ b% J' w9 \
: a# N! F8 U' D/ O% @, wtimer_header->callback = NULL;

; t0 `5 g: e  e
& t  r0 o- n' P& Stimer_header = timer_header->next;

. x2 t" i% B: d
- \: U. F: [5 g. @; ]) I% t(*callback_fptr)();
0 F5 k; l$ m+ N

& X0 i* N4 V' s- i; F( m}
8 E! i/ m9 c7 d) b

* S, o1 y+ l6 `8 E) D# R# \* p. _, b; B

( W% N  |; s0 {  |: Z}
+ k& F- s& E" r: J///////////////////////////////////////////////////
* T  h0 p* d7 X; O4 |' T3 J* J/ i' _0 Y5 V7 i( M5 j% J: n. g4 w
6 P' x" O# q& n, E
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
5 L& G0 k' m8 X( ~& k2 [' i) k( w
8 s8 x$ D( y4 [! x3 d+ _野人献曝,博君一笑( h- M7 C2 ?! M4 w' Y4 `
+ y; V( a. o" O$ A% d9 _7 E: A
Peter# E1 X5 ]) T3 I5 ]$ e
  
6 A  y5 }5 r% r$ h/ o% {; @; ]' O( `( ^& o0 G  y2 n
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-1-12 05:27 , Processed in 0.712993 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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