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

Smart Timing Mechanism

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

, r2 p5 ~6 t2 ]! E
& N+ ]$ W3 U7 n0 |7 R
1. Why need this mechanism( l& j" q; T  s8 B
6 W3 \: r* Y: n$ J- B& V% v$ U
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
& ?8 m/ m; a  o8 f

: X4 U9 j8 F& {. X# r7 K) ^2. How to improve it?) ~! Y4 v5 q0 s1 R# R; Q

: o8 [: Y) ^3 e& b  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
. R/ `4 G, p2 g" m  E) g
; U& i0 H. F6 B/ \//header file/ D6 |& r& Q5 o" C  w" w
/////////////////////////////////////////////////+ ]% E  Z2 V) ?. A
#ifndef& J5 A! h* j# T
OEM_TIMER_SERVICE__H

7 Z' K5 Q/ H+ ^6 `0 @#define; t: \. g( U( C7 h
OEM_TIMER_SERVIEC__H
% I+ z5 F2 s" h# O7 c
9 U4 r* N3 x+ h/ d

7 f# c1 N1 u, s4 n5 ivoid add_timer(unsigned short
3 u% M. x2 ~. g7 a, y! U! |jiffies,void (*callback)());

' }' E: t& W/ s) w( a$ X! v1 ?2 z7 }) E
" E" H: G% }" Z* _void do_timer(void);
/ w: u. s" ?( @8 E: z2 Q
6 Y0 H4 K! T( T) W#endif" M# h6 M/ H' ~
/////////////////////////////////////////////////
0 H1 u  j6 h& T5 J/////////////////////////////////////////////////
0 w8 w" @: n* A4 v! T& F//impl file  S5 H% p8 P9 ^9 E* @
#include <stdio.h>
: n& j* i1 R% z. C#include "OEMTimerService.H"
3 |- c8 g4 C* h/ c2 P) M2 S. }% n, {9 V% W0 J5 f

- O/ E! D3 O6 R0 J#define
& U, ]2 Z8 x" ^3 @- CTIMER_REQUESTS
& ~$ E: D( `2 Y6 |0x30
9 X- |: d, m6 E9 [4 \3 \7 c

$ I" D) P4 k, P: k8 p8 g) b9 sstruct timer_list   ~: b7 ^7 `4 C! B9 k8 I9 |
{
$ _% D# f4 M" ?' O+ r1 N" O
, t8 l& Z# ?1 g  P8 `7 g/ P# Y1 o9 Rstruct timer_list *next;

) z* G7 ]9 r( K! u0 u/ V  V% K! A% D6 }( J
unsigned short jiffies;
* F0 g  i1 K/ v! E# V5 ]8 @

+ k+ ?1 o& k2 h( kvoid (*callback)(void);

/ c4 H" q& [" }: T9 R( [+ m};
1 H4 y- T( g/ X" U" K2 G7 E# z/ |$ z( i, O, o

  ~. G$ Z3 J/ I; hstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};3 }8 E, ~4 G/ _' |& E8 \

+ ]+ [2 y* j. {0 L2 x. K, o( y! K0 tstruct timer_list *timer_header = NULL;& P0 G- U! w( \

- T: t, c! B( l- v8 |, i0 _% z. ?3 u
void add_timer(unsigned short7 {2 M, ^6 [' K) Q
jiffies,void (*callback)())

: S0 S9 {0 {) J2 I5 R2 u{3 P0 y: _8 f& [1 ^' y
  }( P0 \/ q' E+ a; o# {/ N
struct timer_list *ptmp;

, O* Q1 J& y4 N' m" Q# B  G! s" w- U8 |) W( i

# G% [1 s$ Z5 u+ v: w- v$ M1 t  Lif(!callback)
7 C  l% {, ~! Z

0 [5 \9 H( S: o' K, Vreturn ;
# h( \8 `3 z6 M+ I3 I+ r4 x! p" W

4 x- \$ ?7 `5 j6 p* w

& [; f4 Q4 x1 }- |1 \2 {- [& u4 ?  c) n) M, e
EA = 0;

4 t" S) `; c0 p0 r; j# J$ j) J0 T1 C+ {

- Q3 g/ a8 @# u6 `if(jiffies <= 0)

5 Y' i$ ]0 ^/ j! Z  U! l5 R* [; k7 p; L! O' e
(*callback)();
& k( h2 J5 R7 N; v; D
6 `6 f. t* Q+ Z# s" M

$ n6 a1 W3 ]: u( q6 {
& J+ B7 \% ?5 i5 zfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
! |) U4 R9 I8 W9 \# J3 S& b
0 t& |. n7 V3 |8 [9 G9 g9 z5 |" O, Q( |
if(ptmp->callback == NULL)

2 I) n9 D0 w. q, X  q! m+ G  T2 a# o% M7 G
break;

. o, f& X. C8 i0 X2 y( ^* D0 ]+ s$ J/ h; S2 H* q

7 L$ O. z3 ?# }+ H5 N0 B0 ^8 ]; V$ [& O& @
if(ptmp >= timer_list + TIMER_REQUESTS)
% s8 W4 n; l1 ^/ S9 |* S+ ^

; C3 ?/ W6 }  F. n9 [{

+ s3 i, r, b( H; h& J
8 O5 {: u1 U* G$ {  T) Bgoto EXIT;
5 X, F6 j5 Q6 [+ u
+ L/ }# Y' w+ }6 E0 ]
}
: c2 n* A2 ~5 a" m7 W  ]# S
6 t2 o0 d: Q+ k

( Y% B5 d7 w3 Y1 dptmp->jiffies = jiffies;

1 G+ N5 I9 a. c" a) `0 _- S( T7 G+ u! f
ptmp->callback = callback;

/ b* k; S! l- Z8 c9 D2 c
2 s$ q/ F, t0 x, e! c* N! J, a

0 Q0 ^# a' {$ K( u5 P1 R# ?8 s* [4 I) X/ p4 X  ~
ptmp->next = timer_header;
% i% ]9 w5 Q0 k9 V. e

" z) q/ I  w6 `! P9 W0 F! Q% @timer_header = ptmp;

5 K/ m) e) h, i* `
! i7 G; G: A  ], b; c* L! x9 U, K1 \' `8 O, ]
//add bellow code to fix linux on timer’s bugs ++
# f' D9 W8 z: c" v

% W6 L) }# v1 e3 I& H5 V( dif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
% k+ F- o0 E; V  U! G, n

5 Z+ @! r/ p8 V' i: f{

" Y4 N: {$ w& Z8 y4 f+ `4 j2 L1 Z8 m" D, R8 g9 u
ptmp->next->jiffies -= ptmp->jiffies;

" B0 K/ Z/ W+ [" I5 X& N3 T% p' S
- A- N3 N' {; H* |$ H}//end ++

- I  ?3 Z. [2 d+ R) W" f2 \! o5 o& ^0 A4 a3 A$ g. q2 ]% g
else
0 U6 N; _* @! t+ N* m6 G
4 B( Z$ c" L: Z2 J  E5 C
{

# a8 p# r" d- r: d+ t4 f9 Y$ Y" i; L" W' i8 T2 B- y! ?4 j( ^" j
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
3 \- e* V8 y2 U# l

* \5 p( M; E7 m3 h( e# ]% d5 V- F" r" q6 L6 t9 ?
{
0 B5 S3 T! c  p

1 |9 H. a) l/ \. @6 pptmp->jiffies -= ptmp->next->jiffies;
0 C6 v5 C& F4 [) b

8 e8 d) U/ n9 m% X1 L, a9 ~callback = ptmp->callback;

: D$ B$ Q! {' F2 ^( T" h( ]& I) I' d( d4 i0 U: V" A. a
ptmp->callback = ptmp->next->callback;
8 v! y: O4 f* R3 _) T; ]

  X( c) I) N6 yptmp->next->callback = callback;

6 a  O' ~! U9 u* f- q! x$ b: I
6 h8 q3 h% O( a& h9 O' [  vjiffies = ptmp->jiffies;

6 n$ e1 S" Q4 y$ {, _/ O% u
' z; ~# o1 ~% I( M( ^  V+ bptmp->jiffies = ptmp->next->jiffies;

1 P& H; k1 J0 S# Y) {- k9 z9 U" }7 e1 T/ g; q
ptmp->next->jiffies = jiffies;

7 F$ E1 ^+ Y3 h5 `: }( i+ a6 v2 r) j' V5 X. }& n5 O$ m- f  J2 P4 S
ptmp = ptmp->next;
. }$ Q/ B, M4 o4 U

  s9 B) O. K, {7 o/ k}

, [$ }& b) e" d% r7 I# o, |$ n* o! W2 D6 N' s" g
}

6 m# j. Y, \- A' y$ g
7 y8 o% \' w* D/ v! N4 zEXIT:
! e5 K' N  F4 v6 a1 C1 K6 L- S& r9 F7 M+ C" }0 L  U
EA = 1;

, ^" z3 Q, {! p0 L. e: |9 {. P
1 `- G# r9 L! \7 qreturn;
2 j9 I/ w" e4 w
}
* e; H3 A1 i4 q8 `
9 D$ N- I! w. @: y1 evoid do_timer(void)
5 J* h. e9 I/ H8 ^{
6 m' B! ~; ]% g0 f3 Y; I" I
2 m1 W( ]) r( E1 e4 x
% d3 ?- L  ~9 l/ ?2 n& s
while((timer_header != NULL)

1 B. X) V  T- M8 J! t
# h) R. B  ~+ z; f3 W! H4 r; _6 T. K8 m' q  a3 d
&&(timer_header->callback != NULL)

9 Q. n" m0 ^8 c3 a
' f7 A, q1 @0 O- Z
( W3 Y6 e' W- o5 V0 a: i&&(--timer_header->jiffies <= 0))

/ t8 ]4 O9 }) S
: q  t& N/ v, C- Y{

: N' y  m+ ]+ a2 ]: t+ {% C: V: i9 j8 i+ L1 E- j" C1 j
void (*callback_fptr)(void);
* R5 Z/ C2 B- ]$ g: L) l8 A8 M% m+ x

# F2 {) b* ?5 `2 K
1 H6 F: U5 z( t& S* o3 r( f/ l, Ucallback_fptr = timer_header->callback;
4 B1 E' `7 ~8 m9 f" N6 _; W
6 n3 j0 Y9 X# l6 {$ f
timer_header->callback = NULL;
! ?' w0 y, y2 s; N

( l+ W2 v- ~* ^) `0 N8 Ytimer_header = timer_header->next;

. P2 D2 W4 ?8 \6 D5 R
3 z9 k. A+ h7 Q! E( r$ f/ [8 e(*callback_fptr)();
9 ?! u) M2 j, s, k% k" U1 L
7 p3 ~: y# e2 F5 J
}
1 D8 F# T3 ~+ O7 C
& s6 Z; @) D+ x. R3 M* v( |
* g0 c1 p: f2 a4 N* X
}
8 I& g! O  I1 x9 N3 {5 d8 L5 l- e///////////////////////////////////////////////////- Y( X2 w* z% ]% b$ n1 l1 W+ T  `

9 @! F. {4 C  Y
, k# e" v5 ]0 |- Z9 _1 q: I* T
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
$ ]. H+ x9 c! C- W; g% l- A0 M
# k+ z2 ^" p0 ^; z7 @野人献曝,博君一笑2 O7 W5 z. B# F" e) ^: J4 G

  G" X! G: R) S/ {# Y6 S5 `$ ^Peter; f, y6 N* h# f) B8 `( u3 E
  
0 }4 r3 B# G  L3 u" |! C0 v% q& p5 e, K* b( D* j
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-12-1 07:59 , Processed in 0.070838 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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