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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
/ L; j  `7 ~% J# S) C; f
6 M& ?+ k$ ?1 ^! R7 j" a! C# W# ^
1. Why need this mechanism?
! s1 {) {9 H/ }0 P. `+ G3 p% A3 \8 U( T
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

& `1 O% U* r+ N$ O0 G1 n& j
' G' x, o% m/ F: I2. How to improve it?
7 j6 B2 T( P. Y. N% x1 g8 N2 j+ G; p
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)。搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code:, w! V3 i% z0 p1 U; O3 i' s( c' s% S
5 ]3 H* `/ v  I/ D
//header file) t: _' u6 b6 r. D2 ^3 _$ w
/////////////////////////////////////////////////* `1 Z& @( U7 g
#ifndef6 V8 F- [' A" O  |+ Y7 ~- V
OEM_TIMER_SERVICE__H

9 o- d0 ]' _- e; u) H#define
! O9 v# N: a5 T8 IOEM_TIMER_SERVIEC__H

9 A' y) I6 g$ q; A8 `0 H
+ s- W/ {( l+ Z% D) n: b3 V$ b7 i) l. d' ^9 O1 j9 Y# F* O+ x  X+ x
void add_timer(unsigned short
2 D: |, z$ G: e* v) U+ u2 Hjiffies,void (*callback)());
, J5 s' o' O& A# A1 i% \$ @* Q
: t* l# \; Y9 H/ u
void do_timer(void);5 ]! e% Z7 Y( V6 x
" F9 Z; M' {) o, d- i# j
#endif: ~- Z! L) Y7 g* t# i4 z/ l
////////////////////////////////////////////////// ~3 Q( s; k% J
/////////////////////////////////////////////////
% |/ U: w/ i" H' T8 J) Z- u% O: C9 h//impl file" O) p6 c$ p! r$ h
#include <stdio.h>, D# ~- J( ^6 S: T% y
#include "OEMTimerService.H"+ G( {* c. E7 |+ T$ J( W0 W

9 }! `$ d+ Q2 ^8 z! s. Z
2 g$ d( S- m5 `# ~2 C& f9 m8 q. `#define
, z  c& Y8 ]# k: l7 J9 gTIMER_REQUESTS
0 ]6 H- S6 i5 y/ i0x30
* \8 b# W2 T' `8 ^" ^

# L4 ^. `4 `4 }/ e8 ostruct timer_list
; M! \# v5 [! w7 q' N. k; f/ ]2 `3 t{/ Z9 q& Z: K6 e
4 w, ^) @* p1 n
struct timer_list *next;
7 X; a% s8 r% ]

4 ~$ ]1 P5 x1 ~: ^. D9 `unsigned short jiffies;
  C  _- \8 \# |8 v/ @6 Q

2 z$ l' b' D, s6 w3 ovoid (*callback)(void);

; E8 D  i' W# E. W};
7 w" G2 U5 H3 o0 ~) }2 L( D* T
, x+ D: _4 K5 c  ?% Y/ x6 ~
* |+ `( |+ |4 q7 e& bstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};0 [) H8 y: Q- U! O4 [

# `* N2 P) c) W1 O* ]struct timer_list *timer_header = NULL;
" T! W! p" [# g- x$ j4 ?1 w+ V$ @; U( [$ O* }

$ B1 \% @# L# N- m) {% `void add_timer(unsigned short1 V* F& c- v. ]2 E
jiffies,void (*callback)())
! H( K3 |9 L" ~
{
9 Y8 `+ P+ l  V; _+ l" L% M4 ^. q) a/ j) g( s2 f
struct timer_list *ptmp;
; p+ P6 F5 j0 d- \9 e$ c. _4 U7 C
7 ]  x! K  `; M  t# C) b9 }
- }% [. f3 p9 l3 ~6 H
if(!callback)

  n! @3 L# V  b; f" n' L  j# |# c
: z5 E% Z; s0 B: l/ q; f+ [8 Vreturn ;

1 _  \3 u: x% F( j9 _% n, f1 Q! d/ [5 ?! d

2 i1 T1 N/ ?9 U
3 L6 r4 F, _1 @$ A9 L  c( R, i" n; Y' XEA = 0;

* {. b' g9 A" ?
* H) }) l' b, b0 S& a" C5 D' j3 I0 ?& X& i: c3 r% C
if(jiffies <= 0)

' M9 e: M" @( h1 n3 z; z
9 m0 {0 x2 t$ i% X/ z(*callback)();

: i" R0 F! o2 |0 O. }4 y  j9 a$ [% }3 p
# R1 K  I0 `8 f) C1 k- C
. Y- e9 p4 k$ ]5 F
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
; A- l+ i. Q% }& S# J! L2 T
6 |2 k0 s. z& {4 Q: n% O
if(ptmp->callback == NULL)

: z- A; f2 r; F4 x  c% F6 [1 B4 a2 o4 y2 w6 }3 `
break;

" C- P# i/ e% {8 e( g; C8 \, L# s# z. O* k2 I
! T% A" Q/ z1 r# ^4 a* N

- G" u- w- a" h0 k0 f$ h; k. lif(ptmp >= timer_list + TIMER_REQUESTS)
! r7 C* V4 }6 U% ?* n

2 N* l( v( |. E8 O  O3 X: M) ]1 [{

* Q# _1 o2 x; ]  B- d1 h/ N8 y/ O. h( ^; ~1 Z
goto EXIT;
' _9 ^% @5 K5 y* J! ^

# T. C/ E- n/ J' U4 ~! Q}

0 c# ~3 L* }2 M6 u% @9 O0 K. j( M4 ^
0 m5 b! x& J+ z+ x- a- B
- y# o3 d: r' z7 }ptmp->jiffies = jiffies;

& d3 |0 U6 c) v+ ^& n8 K4 v" O( b% ~2 H4 r3 M$ D8 j4 d3 j1 U$ `
ptmp->callback = callback;

1 v- k0 t, Y( r, R" s  k2 n) |* V2 H9 i. o

3 }2 N' F" ^, \2 i; G( _
; n- d: W6 k5 `9 xptmp->next = timer_header;
! T" [$ @- m+ M3 I) Z
% f5 i3 R& I9 z" P* t7 M
timer_header = ptmp;
- {- ]" e& A- l) L$ C) ]
/ ~" a% r/ [2 E5 t; v
0 V! k1 K. k( z* c% F" ~
//add bellow code to fix linux on timer’s bugs ++
1 w2 _4 t) F$ I

7 A/ j3 J# ^! |if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
* ?0 K+ s+ M$ ^
0 f7 R, W# E0 u6 F1 a# g+ J
{
; n! W: k5 y; x, s# O4 J4 O

& U1 `$ ]+ I, F. Yptmp->next->jiffies -= ptmp->jiffies;

( G2 {6 J. d6 X+ F2 P6 L
3 L: K/ z' x1 T0 d7 ~}//end ++

- q3 f" Y/ s( v5 L: H- P
. z$ _  @: V4 B0 zelse
2 P4 p0 O% X( Z$ z

. N. V! `- x  w0 Y{

; O+ l) Z$ [7 L- y) g- R
& O; Z" x3 m4 k; U; iwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
* G; L: A- n% W. u  v& N
# I* T! l- ?% g$ b
! e0 K+ N4 A1 n4 I8 i
{

6 W+ ?1 e! d- G" C2 ~& c2 R% X0 a: b; f6 O! X0 m; g% `/ G# T# R
ptmp->jiffies -= ptmp->next->jiffies;
% x% v* _6 _  [$ L
+ V; V* W/ l# B
callback = ptmp->callback;

8 Y+ Z: Y4 z3 U. l5 P. N: l5 _6 J' r- O# I* x# i9 g; y
ptmp->callback = ptmp->next->callback;

7 E! i7 I# T+ ?! C; }2 W# y, V! S2 g9 g. W/ W& J4 `& e6 Z
ptmp->next->callback = callback;

7 f  x% a2 i! }+ R( m+ q
# F% e: w  R5 _# V1 cjiffies = ptmp->jiffies;

5 |( w& E! i% s- q5 p" @, A4 B! ~. y& E$ K9 D8 Q- _3 i" M
ptmp->jiffies = ptmp->next->jiffies;
$ y. ]! s& w% K4 N
: H% V! y1 j4 I1 M4 ?
ptmp->next->jiffies = jiffies;
3 _3 ?0 V. C7 U# v

/ O( b5 R6 S( Qptmp = ptmp->next;

& N1 I7 ?* _* `& Y$ I/ `# G) ^+ v' N, n" n* f4 K( a8 K7 h
}
4 z5 Q; P) p% w! a

4 Y7 n4 z8 p8 r+ k4 Y2 l; s}
" g! A! \: ^& C0 m0 Q) i

3 v+ m# Z4 y' dEXIT:
3 b! c  h& G0 E
: Y, R4 u1 X! P' P8 lEA = 1;

! _" r8 E( r" H
) J4 M- u: S3 P; ureturn;

4 z% d5 Y& g& J( n# D- |}5 p& T- T  p  v2 g
8 z* y- |  ^6 H7 w( V* J
void do_timer(void)
3 [6 G1 z# U  J4 E& ^{. K: ]/ h" p, x8 r! ^4 B3 i, p

% a! ?$ M0 I& {& C6 z% |3 a4 x( G$ ]0 n
while((timer_header != NULL)
' P3 @0 w" l. A6 D3 n. G4 f

: ~( N/ @3 L. ]9 ]3 O* l" v9 s9 D& B+ J
&&(timer_header->callback != NULL)

6 r  K+ _! ]5 O# x( H4 q, y6 \- ]& u4 L# X6 @% s: G; _, R

& z" k7 U- p# S( U&&(--timer_header->jiffies <= 0))

( @% v  h2 Q" q6 U; {5 l
: h# V# Y% {  P{

  K- _, ]2 u& E0 a
1 w) K# g  Q  tvoid (*callback_fptr)(void);
8 D, x# C6 O0 ?3 P# n

" r$ }  h  ~  Q# v% f7 m# Z$ q3 A- b$ i4 ]. O' z! ?
callback_fptr = timer_header->callback;

. v8 P( b- R9 \' f8 }% M) b/ y1 y5 H& Z$ X) ]
timer_header->callback = NULL;

" I/ x+ w3 g9 ^: n4 e  i2 Z. o1 H( P& w! a
timer_header = timer_header->next;
4 o! |, V5 |( ?4 G; F2 t
9 O2 A' F) U) Z
(*callback_fptr)();
2 \& F2 ?, N  E4 f4 G( J
3 L' [) x5 p4 B7 \
}

+ @( U7 m9 q* D$ q3 A
' ?9 |8 T! }8 F9 b' [) v

: K1 z$ V! a4 M$ h! D. q}
% J0 B( \$ |2 @4 t( c. m& y///////////////////////////////////////////////////
% X, U2 @6 [! k) r, g4 [1 b9 p% Z
- Z9 M- B  @. f6 {4 v% d' _" _8 N
* o  D! b" {* m# z
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!) M% \" q( u9 e9 ?, M

* U. o6 \7 B/ ~1 x2 c( K9 m野人献曝,博君一笑, M) |0 {0 I' O$ y) u% u9 M
  t0 V2 g) u" D; _5 S
Peter$ b7 m' @! e4 l3 o5 }, z6 Y
  
4 a& s2 L& a3 Y# r' i) ^
7 h- S7 H* W1 W[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-10-20 08:37 , Processed in 0.078303 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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