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

Smart Timing Mechanism

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

# ^2 ?9 u. l6 Y& s7 _

8 F" r$ j2 B$ b. |& T1. Why need this mechanism
6 S2 l% H7 l. }6 e6 R5 X# H6 Y
& J" S7 F  i0 X0 k# S
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
3 |2 U: A$ c- z+ \) ~  `

4 ], w8 s3 T. S  d# N, S2 r& s% L2. How to improve it?
5 l# Z7 n5 E/ z0 ^) i! a: g% L5 G- x8 [& V0 z6 {5 `9 O% g' n" c
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
( V4 `$ `5 A2 r$ ?. t) n+ C4 [7 t  Y
//header file
$ C  ]) u" W8 N* A* D* T- S/////////////////////////////////////////////////
8 W% v+ Y9 q" _- D; K! P( ^( \  P#ifndef
1 @. f" l! ]3 ]6 H8 O9 @2 U/ JOEM_TIMER_SERVICE__H

2 N7 Z2 ~0 u- X3 }$ K5 O#define
0 @3 l) V7 k% q0 e" h/ MOEM_TIMER_SERVIEC__H
  z9 O* c! @8 a

  O) A! M. A1 Y% S7 B
& v3 Z) p1 S0 Q( Ovoid add_timer(unsigned short
7 m* S; C4 @8 u# H/ H) e8 a& Ajiffies,void (*callback)());
8 I& f8 d. M5 w
! l4 }' K, a' f7 x$ M
void do_timer(void);; K/ [& X5 X) |8 i2 K9 t2 F. _& {

" w6 W1 j+ E  Y#endif2 v( m1 p4 X& X' H- W
/////////////////////////////////////////////////
  C# H- ]- b& z. V9 t/////////////////////////////////////////////////
& c1 d' R/ {4 x* v! C" Q4 Q' [//impl file
  U9 F9 J+ F8 Q2 b#include <stdio.h>
/ }1 `( p* m% o) U4 Q9 w#include "OEMTimerService.H"6 u# ~7 P) @/ R( `1 u- o
# ~3 |) ^5 y  _' v' L
7 A- e% @; \; @9 c/ @
#define
* P8 ^; S- k# ~9 V: c) u2 QTIMER_REQUESTS' v- b& ^& {( r' m
0x30
) s0 o* f; K2 P, a$ H9 n
1 D* E! w/ i! @+ n3 x
struct timer_list % e8 N6 J8 }* [1 V  g0 ?5 x, G4 w5 n
{
; {& Q2 A  e9 g( R4 |
, n% I9 n/ V6 A8 O5 d+ ?- cstruct timer_list *next;

9 C5 [! H. c8 F% |- `6 d8 U- k) e5 w
unsigned short jiffies;
5 e. P7 v9 k' S  D$ R! T
0 T. w7 v5 ?) [' ^' @9 ^( b
void (*callback)(void);
/ U# f9 _7 N* m' N0 `* S
};% e% r% `0 f! ?/ g
4 P; F* q: P/ e4 R& n- @/ I
3 j' l& v; N" P) A
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};) p" y3 E# y) X; X
5 l4 ?' v! o3 P  D0 ?/ H
struct timer_list *timer_header = NULL;
( T% I" A0 y: T! F8 C' h" [! D
# `6 L8 A# p" z0 ^  c2 w' E5 \3 M" h- }$ Z* D
void add_timer(unsigned short: W) v% z: q$ y6 B& r
jiffies,void (*callback)())
" A0 p) @. \  B( v5 Q  N
{" B- k% m0 ~  j, c7 W" a
* s+ D) V  u/ Y8 c% r* `
struct timer_list *ptmp;

" j8 ]. H/ f6 Z; i
. t/ L2 M: k' J: W7 d, \% a+ A. q, g7 n: K$ M, u. v4 ^& N# j
if(!callback)

8 d. C. g, Q4 i% [: Z' w- I6 B
+ E8 |! E" A& h6 _3 ?5 b7 lreturn ;
$ K* y4 p. U4 u. R
% j. t$ b, \1 l- @& s

; d; ?; m* p! h: z* a/ h) M4 j! e2 o  a, l  K) G& [( @' y
EA = 0;
) l4 W* M+ v/ `/ X: b) G9 f9 q. D
8 G8 B& L$ I% |6 i6 {0 M# b4 m, T
- P. y+ W. S% U/ V3 c) D
if(jiffies <= 0)
  h# V# V" l3 }- s; w

" S. E; u& A  x/ J(*callback)();
$ N% Q9 Y% |( d* R
$ J* E8 j, |& v4 a! c: r
6 N' o/ C: ?9 v0 x2 f$ A

/ u, T: d) A$ e4 K6 N4 M& E% qfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
9 o; q" L# O) C1 j" R1 e
" n! X: z, E3 F( i) n# s% J; l
if(ptmp->callback == NULL)
. V% v& Z+ v) B

$ x3 O; J' `+ [: Hbreak;

' _/ ^4 m: u' l1 k# Y
4 |& h' F- v6 c4 x
3 s( P4 t9 ~$ C  I' b0 I$ ?) c' h8 C) x
if(ptmp >= timer_list + TIMER_REQUESTS)
! u" F5 k* y& }$ h0 q( ^2 W

% p; o) b* }7 E( W{
  O- V; Q; v. W4 B1 ^; ?4 R1 }
% G+ J+ a8 m; b0 M) H0 g6 i
goto EXIT;
) g& T% T; E, D. ?6 z# D
& A8 D  l! }& h8 z7 [/ N$ `
}

( [% C" @& ^- U" I& v' @  _
; B7 L$ R) a4 }; m- U4 s# c+ [! I
ptmp->jiffies = jiffies;

+ r/ i8 J. L/ ]! l/ \+ T! V! B$ N. V8 R( f
ptmp->callback = callback;
9 Z4 G, z3 Q2 d7 s+ H
$ w5 L/ N! K4 x2 r$ {

: O' N$ w; n8 k2 C* P0 \2 j/ K
/ ~% L8 k/ X2 R8 G0 sptmp->next = timer_header;

+ Z. B3 a1 i  D- N
: P5 y  P/ ?4 c/ n6 N& B, t& itimer_header = ptmp;

. D2 ]0 P; |: [4 _
" E5 l; Y$ T  p0 h' Q; t% a0 Q, K$ Q1 M
//add bellow code to fix linux on timer’s bugs ++
, u! G! c6 j% g' g

/ s1 x9 Q3 ]6 e3 Wif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
) _! u% P* {  V0 }9 Y9 C
$ C1 d8 q+ u  n) S& R/ z. w
{
9 l. a7 k! M# r' B3 [( b4 n+ C: A
& |/ d- C6 w+ A! f7 u- u+ \
ptmp->next->jiffies -= ptmp->jiffies;

1 _* a9 N# h, @# w
/ R: i( z4 f6 K; r! Z' }) m. J}//end ++
( J9 N6 A' n: A6 a9 j
5 c# J2 Y9 q% w. N8 o3 E1 x
else

; I* z' m% Z% j
. [& E& N: O, p$ L! Y+ u, d% y{
% S) x8 \/ Z8 [7 Y& i) v6 Y
: P0 b" @- O/ h
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
; P5 z1 u/ l: P) A
* c( n7 h: W: R( {! A) [% o
, `) [& W( y" G; E; f, k
{

4 R- q/ y. i0 W2 y$ K5 X3 I! `( I# i6 m$ I! j2 F" V! s: T5 [* T. R
ptmp->jiffies -= ptmp->next->jiffies;

* @' o/ f  |9 g& a7 J2 u7 q  r" ~
callback = ptmp->callback;
- p& U& @7 l6 N4 x# Z

  e7 K: G! i! b8 b- ]ptmp->callback = ptmp->next->callback;
. f- }  k5 }" u- b4 `, J

6 r8 f$ i" V$ S# ~% s( f8 Xptmp->next->callback = callback;
4 ?' E7 a8 n$ R+ ~4 D0 _" v' v

. A( q& B0 U* K; d2 Q, zjiffies = ptmp->jiffies;
( T1 L  U- h, M  s. k' I
/ R. s  ~5 t/ J5 i% j$ }
ptmp->jiffies = ptmp->next->jiffies;

9 q, r% ]" t$ C9 ^" ~( u1 r# q6 T: W) _2 R! K
ptmp->next->jiffies = jiffies;

9 \: {# K7 [* Q
8 M* q3 m0 `) W8 i. L% z; W4 Iptmp = ptmp->next;

, [! _7 w: b( M$ |' H8 U! l3 t) Y; ^! U4 G5 n$ ^7 Q1 A8 A- `
}

/ L) [7 A1 g; t7 G: ]
% D% u- q1 }5 H+ n* E7 |1 D}

$ I; P* i, e6 F" l0 o* ~8 [( t. `8 @  Z6 p" j0 G4 T2 c
EXIT:2 @, \& @7 }+ w( l4 k$ V( H

- ]5 X- A1 Z2 c: K- R& w# E* jEA = 1;

2 t) t/ r* \/ ^" H& S& T9 a& g" I( p% y6 i/ O3 q7 n
return;

7 x5 }+ h/ {; s/ I}
; B# v& M5 K* J2 S5 `' ]( r- g4 ~) t3 w3 U/ u/ I$ O; a
void do_timer(void)
" j5 j% ], }6 ?# S' U{& A6 b& _5 v& H5 V4 e3 I
& }% D* s) L8 Q% Q; p

5 v& j* _" f% m" t7 B. ]5 Swhile((timer_header != NULL)

8 G, f% _+ h2 g+ h0 |9 g% }. G* \+ D% n! C1 C. S/ V
+ g; r# U: Y" C& |$ U
&&(timer_header->callback != NULL)

2 ?. e" T! e. d. w6 {% ], V
6 \' t5 z9 H+ [* Y/ Y7 w
: p) X1 Y: ^$ ?* U& _! I&&(--timer_header->jiffies <= 0))
9 a1 f( B3 d" _- f" Z9 Q$ G

# O9 ^, ~% ~4 \{
1 K, L3 c( w, R5 x" k' W; ]+ z

% m" V% c& h2 gvoid (*callback_fptr)(void);

) N* @( W3 b6 [! F- m
4 m3 l* Q, b/ o5 I5 n! b4 Y9 E( }# w- W' H, j
callback_fptr = timer_header->callback;
1 [6 Q0 b+ E9 s

1 w9 g: x* i* k) ctimer_header->callback = NULL;

7 h- t/ K' V  J$ }: f5 l5 q( w! f* i, A
timer_header = timer_header->next;

, E( m9 G! e6 b. Y6 m8 m$ [7 O0 @- ]
(*callback_fptr)();

# ~0 x; U) X% O! t" I1 ?3 {( k6 }* Q8 i6 M$ o$ d1 q
}

; f8 D/ ?* @# S4 ~9 s; r) N, d9 ?0 g0 c* Y' c. E

% L. f" {, O9 _5 ]) q9 y4 c  O}
: f, x4 m0 I0 G1 e9 y( w///////////////////////////////////////////////////
& k0 D: r/ c7 W/ U! H! Z& F8 y  h1 ]7 x" z3 {$ u

! K% U& D' ?: F, Z上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
7 O/ q& k& V8 Q- v' e5 [; V( k
0 t3 d1 o* O2 U& }- w野人献曝,博君一笑
1 \9 @! a* G" ]2 L$ Q5 O/ T; n8 A- T7 C& @
Peter7 F7 U  t3 \: t# {0 z/ J
  ( M; \) N, b2 x1 I2 ]. Q5 Z5 c

) I; L: ?( h- C% _2 _3 ]& Z* b[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-9-21 22:31 , Processed in 0.582359 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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