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

Smart Timing Mechanism

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

) U, e. L$ |4 O' X9 K
3 T3 U3 ^5 Z% j# k: N2. How to improve it?: X) i: k7 E0 j4 Y
- O# J$ ~) |3 g8 w, U" Q& q
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
- f- _+ J/ m1 U! Q/ m; t
8 @; i1 j5 Z  v* H+ g! {& x//header file% I+ ?- R& Z# T  X( t8 }3 ^% A
/////////////////////////////////////////////////
" g4 \2 w1 R2 U' V* Z: `8 [#ifndef7 H, q/ k) r$ d2 d/ j9 [
OEM_TIMER_SERVICE__H

+ `# v1 W6 s0 E8 e$ R#define
% X, O8 e+ \  Z7 q5 S0 e! WOEM_TIMER_SERVIEC__H
; d- n) h0 J3 Q. ]) ~/ K
& z0 r( ]8 ?+ v1 k+ F- @
7 t/ C% }1 K% M+ i7 @/ ~5 P. m9 P
void add_timer(unsigned short" w+ u- P9 b! v5 E8 b' d3 ^
jiffies,void (*callback)());
7 R3 ^2 R& a* u' d

+ k& }( m+ Z6 |; U' Ovoid do_timer(void);: ^6 V/ ?+ K; P* l4 J& ]
2 M* M* L9 y" a! L! A0 K
#endif
8 |; H5 Z0 A; N( ~3 f/////////////////////////////////////////////////
+ H- f& o+ z, d4 b/ l" U/////////////////////////////////////////////////9 n8 l4 i' [8 G: m7 W: E7 G# d+ J3 z
//impl file
2 R( r! r6 o7 z2 f9 O% |6 h#include <stdio.h>/ V4 N. e$ @9 K! L+ E0 C9 Q) F
#include "OEMTimerService.H"
5 q% A  J" c. y" Y  v
% V2 b) u9 m- G" S. ?2 l
% I" Q2 \' F+ I; [* b#define+ J5 b$ I1 e' b; g: ]
TIMER_REQUESTS6 M/ A& A, C( W! _8 u$ g, f7 H
0x30
0 c5 w' @8 i! F/ F. g, s8 S
6 R! F) J5 r( h- L; ]
struct timer_list 0 y* Q& X, O, c/ P+ h% ^1 K6 d
{
' v) H3 g) B; U  f) r1 c% e4 G( _! H0 }9 d+ B
struct timer_list *next;
2 ]8 H2 X, p+ P7 i. W  G
9 U# U9 i( h7 u
unsigned short jiffies;
. u7 ^# x- U$ N+ e
6 B5 i) y6 r  Q9 g- i) C
void (*callback)(void);
; g# ~  T0 U1 y8 X* o
};' D; W0 S' G& h! X4 v
* y1 O+ {4 p. M  t: W

# S) p0 Z+ o- K9 B: Bstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
9 V' V* N. L0 A* l# S
5 m% W- v  p8 e# Sstruct timer_list *timer_header = NULL;7 l0 H4 F. o4 }; I5 f* R, M# y

" u+ ]0 c7 b- l" C" R' ^
* g. ^6 I" @; _$ h9 }* hvoid add_timer(unsigned short
( k+ i7 Q6 c: D( {1 C8 h. Fjiffies,void (*callback)())
. v$ `, B5 W9 b6 W7 r
{
2 S; v0 F& R: r, S" c% ]) p( E# {! U, j7 Q3 e3 A* m) H
struct timer_list *ptmp;
7 {* a8 n6 j+ u$ [. V

" \$ c# s+ Y' U1 G$ u& O1 V& E( p0 a; K: f
if(!callback)

; ^$ n; \$ x9 a, B2 z; P
" Z! P% _/ @) P! h* o7 @return ;
% z" s' a, }' }- j% j' K( V5 O
) l# A; m9 J; D* u: d& u
* }3 p  m: |0 m8 X
' B4 |$ G! f' G, |' @
EA = 0;

5 J8 B* c* N3 @' H  i  J  Y$ H. X7 _, ]) b
! g- J9 [. o& J) i, G
if(jiffies <= 0)
. J7 z9 K, i" }' q- l
4 `1 b( E- Q6 v: b3 f9 U
(*callback)();

$ |2 t% z6 [6 k' W' x, U( c+ p) O; G+ e9 C

# Y8 D, g+ V, e* I5 }# G
; k0 O# I* Z0 k) E. r  j, ?9 K- z- Ofor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
5 Z3 B9 Y; l" n
+ n  ^+ D6 F9 P  |# ]) I: {( p9 [3 L
if(ptmp->callback == NULL)
# C! i+ Z4 h% o

# T. B) S9 e% o& P  [break;
2 Z3 `6 u: Y  Y5 [& Z
0 {" n8 E9 O9 l

8 D. e) h- w. z0 ^# A% z$ h5 U; M6 G9 g3 A( S! ^# ~/ g* f
if(ptmp >= timer_list + TIMER_REQUESTS)
8 W2 h/ O1 ?+ v7 j

& J1 d8 S- b& x. `, d8 ]{

9 w5 |8 ?+ u( p" s. c4 N( j4 K9 ~, o* ?3 h' _5 m7 u
goto EXIT;
. F+ o! k9 Y* l' A$ \( \, ?- N
$ c6 n6 V/ L( n$ C9 v4 H4 _* R4 E
}
/ @8 y: s! T4 C& |

' a# s  P: R3 u
- H$ T0 _+ J2 H, U) Nptmp->jiffies = jiffies;

/ A: ~! J1 M; E/ k- S7 e6 O& ~* e7 I. y  l
ptmp->callback = callback;
. Y1 B& l/ \. k3 l$ G7 |$ Y; b+ j
  [+ ~6 j7 b7 a

4 c# s" u9 H; e+ s
4 c$ u# d3 U: U1 s  sptmp->next = timer_header;
3 H' h& m% _& y
! k, G4 g% A; g+ _0 y& B
timer_header = ptmp;

& m* X7 {! }2 f% b& w9 {1 i1 ^! A& n" ?' {* l' |6 K

4 G! q* R. j. u7 w  i, Z0 A//add bellow code to fix linux on timer’s bugs ++
0 @5 l9 I; U, P$ ~

) ~2 G7 G* A1 x" o( s4 r/ nif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

9 [1 q: R7 V) V. c+ b1 |; n
/ Z- d7 d, X5 \3 o{

7 m3 @5 r2 p* o& i( _+ b' U3 n# t$ f) F6 C1 I: S. |: F
ptmp->next->jiffies -= ptmp->jiffies;

# [( u6 A. F, o7 w% T' `5 ^- [  C* `' G8 B! l* Y
}//end ++

( {1 U/ b+ G+ P) f; i! x& W5 W% b4 h, c
else
; z( r/ {" F0 r+ h

8 y0 Q" E1 D0 |{

7 U2 P: D+ ~# g3 j1 k+ [
6 @! g, z8 _7 B  E& @6 V8 ~0 Fwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
' M$ m+ O; ~' p% K
6 P" f7 e: Y9 g, }/ k- z/ N
( a- o" W4 z& D- r/ i' g
{
, |- N2 M# e& f
6 ?6 C& v* ]$ p: f
ptmp->jiffies -= ptmp->next->jiffies;

6 G. K" \7 Y4 }+ C& W1 \; k1 |* H
, O) K$ c5 [1 v! \callback = ptmp->callback;
$ @5 [- T8 s" A  K' N
0 k( p  _" Q" Q
ptmp->callback = ptmp->next->callback;

: S" _2 x9 `  P) h  Q5 t  i! z, h$ R. [  ^+ R
ptmp->next->callback = callback;

2 I* w1 o7 o( p8 t& A5 \2 f2 Z) v6 X/ F
jiffies = ptmp->jiffies;
- j8 m& X6 ?. }6 r* c

  e& q' @7 N) e) _ptmp->jiffies = ptmp->next->jiffies;
5 y# D$ Z$ ?5 l2 ?6 Y4 c2 g

% J. m* K7 _6 _& Pptmp->next->jiffies = jiffies;

' v. `- R$ `$ \- \/ }  P7 {( k& }) u7 I
ptmp = ptmp->next;

. \; x& x: W: c" v5 I* c" `3 t8 [: H
}

9 Z" W7 a9 `1 C, d$ D  R
6 N, a# c* n: O/ B}
9 l& r. t" Q3 [: L0 i( A/ A
( G. I7 t7 V$ W* G, r) Z8 N0 A, W0 G; c
EXIT:+ ~8 b+ I8 R' O  L8 K8 z' W

8 j! l) v" P; c0 s8 TEA = 1;

4 A% C! `* S, U9 c* p; D# v6 c3 M# Q+ |
return;

4 h9 L( m! F% ?+ Y2 o8 C}
5 H$ S& [& o( W4 W
1 ~9 ~6 w; q3 Z1 S" Ovoid do_timer(void)
, ]8 @9 U/ b' f8 D9 }' _{0 a4 Z0 T' M- Q. Y- O

- ]8 p3 X* o' {# H, d: {; f  O# z1 ]% w; o
while((timer_header != NULL)

' }/ I% ?0 k# M
* m, p4 u; \/ ?0 O* S1 g
: P$ i- C2 }; Q# ^&&(timer_header->callback != NULL)
% W# D* r6 Z( w/ w2 V

! M1 f* d. |( v5 s
5 q- ~6 u2 j( P3 j0 }( R&&(--timer_header->jiffies <= 0))
- u+ r3 n* @. `) _4 {5 X; ~

' K5 h: K2 ^7 e0 u8 f- e{
" v, f/ u- {/ ?3 U/ C& l4 B. }
1 u& d" o- ], o2 u" d# R
void (*callback_fptr)(void);
0 A$ N) ?. c. W9 [! P* F  \5 M  c

% W" P- V+ T5 B" ?7 X  _; R+ G" m4 s; W- [) G& n! I3 ~
callback_fptr = timer_header->callback;
- I5 C- U+ g# J3 ?
9 n  z* {: b1 f& k9 _) ^* R
timer_header->callback = NULL;

+ s, F3 O4 W2 r6 I/ e
# c7 _; q7 k0 q% D' o' R( ttimer_header = timer_header->next;
6 Z  w+ M9 i7 X

5 _/ }  ~9 r- c) {(*callback_fptr)();

! I) h' T+ O* Z5 e2 u) E7 |/ F% x2 `1 m' W$ |
}
. P$ f+ x  t! x0 j6 ~5 G! Z
! E, q+ C$ |  f- G2 s0 S6 U& E

1 E9 W0 ]5 P9 x: [9 q/ h6 W; c}/ X* H4 H3 F3 J. ~2 K
///////////////////////////////////////////////////. j* ?9 f' t$ K' T

  `/ I- x  R8 E, E6 ], b! N% C) B( b
* m7 C/ F, I: \0 h8 S
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!0 z2 l% O# X6 U/ M# Z- _1 W

+ m7 n& s; P. n6 {5 g& H' g6 @野人献曝,博君一笑
5 o( ]$ t$ F5 i# x
: Z3 r" b1 y' j% [# O& I1 a# v9 N0 lPeter9 {& X* l, x/ `+ o4 B! D
  # W- d) e, `% H( ?3 c: K6 }! h

2 b- H+ H! i1 `% @9 t1 y[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-11-23 22:40 , Processed in 0.054826 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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