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

Smart Timing Mechanism

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

9 x4 R1 J' z# H( p5 q! `. Z' Q7 `7 E
' z" H) V8 b6 K' K" T
1. Why need this mechanism
, ]7 y* a  s: |0 N  C" S& m- o$ f' k0 W" _1 X9 b
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

  N+ J3 {3 ~( ~0 ?
8 i& b( ?: F0 ]. ?2. How to improve it?( C, W' n) @8 y& M

7 J$ R* r. Q9 Q9 ?/ k" F# B7 K  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code+ J& x4 a  o3 I# G" D3 O* I

; u8 Y- q5 x6 f- X//header file
' `* q! F7 l: b/////////////////////////////////////////////////7 m8 c. n: @+ O3 J1 {( y
#ifndef
( B: r7 u' W0 o8 |( o5 C8 UOEM_TIMER_SERVICE__H
, Z+ b* L) B' ^; \1 K; d* I( k8 i
#define
0 }$ h& h3 C/ s3 u0 qOEM_TIMER_SERVIEC__H

7 z) u/ i* a4 M9 E) O7 k" ]% C
+ `  g- I8 _- J4 {9 u1 P4 C5 m; G' c( l0 z0 _- a" }* c- D8 _
void add_timer(unsigned short- A% v* S9 B5 X5 _% q0 ]. n4 G
jiffies,void (*callback)());
# P- Y. f8 X* ?& z& ]. @
! i2 S+ E' k0 m% u9 b: A2 w
void do_timer(void);+ d8 q1 u  X4 ~! l' K( r% f
' l$ o* E+ J. w# p# n9 ]
#endif
) I) Y% x: z1 ]6 h0 i3 b* L  C/////////////////////////////////////////////////
. [+ O' D# i! V$ M4 f# ]* h9 L/////////////////////////////////////////////////, f8 M6 r  c: _
//impl file5 R' {  s0 w& W# T) W& F% M* U2 U9 {
#include <stdio.h>) U8 Q" @2 B( V& V( p% `
#include "OEMTimerService.H"
% d7 h( r3 x- b9 R  u# ]
/ t$ h7 Z: k. C3 I( n9 b
4 M0 V% m3 M7 w9 j- x4 W#define8 \% a8 C2 e+ I
TIMER_REQUESTS$ `0 R/ {+ f# I+ @, d& }" `3 _
0x30

8 g3 G/ H1 V+ q5 s5 X
3 q' `; J6 l' C/ S# nstruct timer_list # f$ H9 x% V$ N0 i& o4 z9 `/ R
{% R! ^1 a7 O" [# I+ D4 Z; a

5 m; v: Y% o) `struct timer_list *next;

3 M$ l" @) v$ I9 C0 |
1 t9 V$ J4 I4 E: y. bunsigned short jiffies;

8 G6 s- Y  X! D, W9 M/ @! b' L
void (*callback)(void);

: k6 s; M) v8 F5 b8 v( b. J};
2 W. }+ j; q' S
. {* u4 U: M( _2 Z( e; m9 s# g6 _. t8 T; B2 ~. o& L
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};2 g+ X, \! R8 K5 R! q

$ ]+ H+ W+ p8 ^struct timer_list *timer_header = NULL;
9 u6 `- Q6 O3 ~- Q8 _5 z5 D5 V  Y5 T7 c& E

2 c3 s* D$ W$ o" \* T- fvoid add_timer(unsigned short% Y0 u# {2 e6 e, Z
jiffies,void (*callback)())

! j3 v( U7 e5 E* b{
* I: N9 |! Z" e1 D
8 \" @; t! B8 Bstruct timer_list *ptmp;
9 ~# Y( ]0 I" F6 r( Z4 G

3 k; |1 S( G# D' l$ s  _3 w- }* x1 ], ]$ N9 e- s$ B* K
if(!callback)

  ~  C) x* C- Y2 I# Q3 C/ ?4 {8 M( z1 h& g4 m7 i
return ;

1 T/ T% r" v! g3 J+ l- y1 q& ]1 U; d  J% @/ o
% D9 i8 \( y- z4 G& _& ]

! @  @6 h1 C; ^8 V# Z! gEA = 0;

; w7 _5 b* G5 e  |% p* n+ G) m- p2 [/ Z2 r& e/ l7 d  {( ^

; X, D6 M5 h; \8 y" R0 Dif(jiffies <= 0)
2 V) o$ v  g' x7 y+ E
$ c3 s+ N' P- D! d
(*callback)();

' I& d9 G/ C9 |& e, \6 l! \  H) c8 x4 P5 |6 l( u
5 g* y# W+ @: s

) X. D0 l. M% [0 ?) Nfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

& u9 @0 Z% L2 k9 Z/ L9 T! r& X
" A% @8 |% \6 y% \& y( K/ lif(ptmp->callback == NULL)

: I. ~2 Z, {6 ]% O; q+ W; C" P% w9 S6 W2 l/ V. a8 d) u* x
break;
+ [2 I1 \! ?6 {" V" b- q4 H9 l

! r6 a1 j* Z, A) `3 S- u* i4 p6 j5 B
" s8 J" Q1 E& Y* u" w6 @+ R! p0 `6 Z% w
if(ptmp >= timer_list + TIMER_REQUESTS)

2 v  T' I. k( A4 R3 O6 u) u3 j* n9 O, b6 ~
{
  e/ N$ G' }" e4 a$ e. h5 i2 S

2 T5 L. j9 J' ]* c; C5 ugoto EXIT;

7 C  g7 ?2 @, n1 O1 I- @: {4 R
' B) X! ?( b  `  K1 n/ J& x" B. }}

/ z5 O5 D1 k; [( u: [+ H! ?2 ?$ ^9 F, N  A+ b3 m8 ~) o
9 ~; q$ p% W8 C! B
ptmp->jiffies = jiffies;
5 U4 b: }/ ]8 E! K5 b- W
( T$ _0 G% [1 [( E) q( C0 ?. B
ptmp->callback = callback;

2 C- r0 ^3 C% }+ O8 ^* [5 P( H+ k3 o7 M
3 c+ {7 I- G9 S/ V1 z; j
! W% y% J6 n; Z; m
( l- J. s% Q/ f* M0 w6 O$ @/ }
ptmp->next = timer_header;
8 Z; c, c7 G: V! T1 X  V

# M( j1 d/ h* I5 m/ u" dtimer_header = ptmp;
0 \6 {# a2 ?8 j/ R% z0 ~9 O! v3 `7 z

5 i4 M. W+ {1 p; K" P0 Z% p* p; T! n$ R8 n5 K' n
//add bellow code to fix linux on timer’s bugs ++
$ ~& D" n  v+ @
3 _( N$ T9 @7 A! I, F3 w
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

( `1 g* T; b" Z6 k; A# F2 k0 J9 c1 P' L$ W- l$ s7 {7 a/ N
{
7 p9 {9 H  l2 S: L

- A; z/ {# Y! g3 sptmp->next->jiffies -= ptmp->jiffies;
+ e% ?$ Y, A# r2 p8 c' [

( a0 a" C' z/ i2 b1 v}//end ++

4 b* H: C. m+ H5 V! J( r# W! v: g5 B4 z! c" \
else

- ^3 H; \6 _  P( W  P: v
3 Q1 b9 }+ a( X' A1 R6 \2 Z1 B  ^{

" P' Q% G5 _; o, P: l- z/ i6 `( r9 v
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
. g' f7 {" y  A2 A5 }

8 o, T+ ?& _3 L  r* K" P0 o1 t& ]5 R: b% {
{
7 ]- Y& E/ P: N! M

- K* G( }; P( c* hptmp->jiffies -= ptmp->next->jiffies;
" D# R7 Y1 D% o
$ r' _- R& e) @, Z* K! A
callback = ptmp->callback;

0 @: ?5 O3 y1 n( e  p# w! l5 T& h
6 ^' H6 @; O/ J) optmp->callback = ptmp->next->callback;

$ }8 T- H; G% r5 \  [: M, I1 x
2 s9 v, c+ K  B$ y7 J# C- ^0 N1 _ptmp->next->callback = callback;
( u- a- i5 J! X6 c" x4 K6 m  h

, f8 a8 c9 z  O- h, J: P9 njiffies = ptmp->jiffies;
$ v' [6 n5 [+ y
, C. M$ c. y! }' V) i4 x+ U
ptmp->jiffies = ptmp->next->jiffies;
( n- ?. C# q3 N$ O9 h" O  l

3 k9 J: D3 o" wptmp->next->jiffies = jiffies;
: p; g$ `1 `, J% B  Q7 H( x

$ f/ D' o* k3 S5 z' k$ A. Y' rptmp = ptmp->next;
+ ^7 K& F2 U# p
$ _( S0 {* F6 U' }: N6 r" S& y* e
}
! M; b0 k& P1 N8 u- @( ]
1 O' x; f6 o% X& y9 K$ B8 F4 T, Z
}

) A' D- ~. L0 t& s* h; f
6 S6 M& O% f5 Y7 TEXIT:
2 D5 f7 C  h2 V
. S1 r" L, P$ z" J9 K- [8 o" nEA = 1;
; A9 K& k* j! a  C; ]7 N
8 N7 e- r4 J9 Q: @
return;

- C1 B4 v$ P4 Y6 y6 b1 I}
7 A( F8 ?0 y; a: M% R7 y5 l5 n$ p7 m1 l6 I+ J% |, J) u
void do_timer(void)0 Z7 }' j/ a* T  a
{9 a2 Q% U9 I* Z$ g7 p
  X' e7 R% x, s! W" K4 s
8 i$ H% @7 b: i. d1 S4 F
while((timer_header != NULL)

- ]' ^9 p# q% s- V4 \) u& F7 P* I2 E
: M& g: ~4 W4 W5 X6 P) S. q: q  d) H9 Z* s& L) p! `6 K' Z5 u! o- Y
&&(timer_header->callback != NULL)
# b- B1 x4 m8 T

5 ~/ t) c. ]7 G3 _$ R' W, U+ s3 T1 b1 c9 g
&&(--timer_header->jiffies <= 0))

, S4 x' [8 p, W" l. e
7 ?; k' h9 l! W3 p( O{

0 J: R: S1 a7 _* i5 c2 n0 R
. C1 D+ n0 O0 \: @$ zvoid (*callback_fptr)(void);

# D' q; F* X5 w5 @* P6 _; ~3 z8 _/ }& m: }

5 v: l- y5 s; ?callback_fptr = timer_header->callback;
' ~' C% L. H/ b" `8 C
* c, T4 k& |! U4 e7 G* k0 z6 A
timer_header->callback = NULL;
1 g6 o9 h3 j. K* g- \2 J8 _
" b$ y# W0 i% e, Y( x; ^, ~' J
timer_header = timer_header->next;

( U+ |& h* z) G1 s2 }! h
/ ]- ^- ?8 F( ]+ t# q(*callback_fptr)();

, N5 r7 K  ?! I) k9 i  y, j9 r" s6 w' j4 S1 a! z; n( ^7 c
}

" ?' J- U/ T% ~: o. }# s+ `0 Z% [) L! o& ~% N
. ?  h3 [" W: ]: x' Z# v8 N$ y
}
* q& l0 i# \( E2 U% U5 o///////////////////////////////////////////////////
+ H& m% ]/ R+ K( e$ R4 T7 A  Y- @

+ W" Y4 a. m; k7 f1 `- l上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!8 E+ p7 t8 K  S. u/ j' B' A' f

* s, c3 N9 K7 C9 \1 T野人献曝,博君一笑, ~) n& p3 ]' y
8 `) m/ _* P( N. L. i  D
Peter
" p5 t6 z( M/ l1 L( D  * D$ {" n' p% b1 ^/ x9 L

9 }8 L/ ^, t) N[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-7-19 20:42 , Processed in 0.183592 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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