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

Smart Timing Mechanism

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

( @! A& g4 {0 N7 e

9 h! h; D  h7 v: r  U; t- E' @1. Why need this mechanism. d6 w0 W, c) l' h8 A; v/ I# @& k
3 j+ i. {1 U7 X  S$ K3 c
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
: P# i4 `/ N# T0 U4 R- i

  H! d7 K/ S# m5 K; C, f% P2 C3 l2. How to improve it?
3 B& U1 p- a* ?1 @6 d% ~6 ?
+ \! }& k4 g: u3 L) m1 h  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
" U( D/ c4 i7 p& Q
0 V6 R. J9 r2 ^0 T! ]  v# P. S+ ^//header file
. \+ X8 f/ j) N- N0 o/////////////////////////////////////////////////( t; k) G; V; a: ~# T0 P0 U& a  u
#ifndef) v5 y8 }* A, K7 G
OEM_TIMER_SERVICE__H

3 Z( `0 C5 E( a2 t$ v#define
6 J: d( t/ q6 k& z7 kOEM_TIMER_SERVIEC__H
& `# y4 ]% b- |! l" u: D

7 q: S  T0 M" c& A6 a( f/ {* v8 j4 u9 B
; N* W" j! H! ^! Yvoid add_timer(unsigned short
+ n9 |( C2 Q- E. Djiffies,void (*callback)());
3 l5 M# S4 M2 N5 U$ Y

2 D0 L! B/ N% C. [, u7 E3 t3 Jvoid do_timer(void);
5 R) V. u" d$ S3 a) D
2 h. B6 T3 g) g#endif* }* z/ ^# ?5 S# d! `3 ]
/////////////////////////////////////////////////' v6 S2 R+ c" A- @9 \% O, G+ ^% Q
/////////////////////////////////////////////////" x! \* S/ F. H8 q
//impl file
# E5 I. P" i! `* h#include <stdio.h>
# e& e& l6 j3 b$ v3 T0 ?! ^#include "OEMTimerService.H"
  ?4 T  a1 i/ B" H( c( l
# E6 C' U) P- }
- s4 k0 d" }8 P. [, h6 w#define
# K1 x0 @& T& c% h) w! f2 ?TIMER_REQUESTS' r1 h  [' ]5 |2 E! ?; z! ~1 m
0x30
/ z! h* U+ U- B- s9 [

5 ~, P* h+ V6 W' I( m: m, o( Ystruct timer_list , j  Q8 F( N; f' f5 i1 h
{
$ R: P8 q, I6 S# |5 V) T+ Y/ D+ e4 H2 R! ?" J8 o+ A
struct timer_list *next;

9 p. L+ L9 \9 U6 d2 d
+ Z* N  |* Y/ Z& Funsigned short jiffies;
- l2 m1 A" W5 O& X

5 E, y& ], g/ k4 evoid (*callback)(void);

/ E) s+ S, X+ e; W& M};( P9 C: ^# J% R& C% z2 P. @' a( B
8 S+ P4 I7 R# {8 b7 n4 m
6 z- L1 }. @. j" y" S( d
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
4 c1 \* T4 _$ S5 }- I/ d. ^: F# z) v" e3 v' }
struct timer_list *timer_header = NULL;" m8 s9 J4 P, [

2 T4 C7 F+ ?. d" G# ^- b7 A$ K& v, _
void add_timer(unsigned short5 x6 y8 {; z$ {8 ?& K/ R1 W, q
jiffies,void (*callback)())

. n: ?. K$ y. [3 g{/ I1 r  P1 o6 {4 t' M' M! t% k% M6 L
! J- t. Z' M4 P! Y& L- j
struct timer_list *ptmp;
+ R+ m! @3 H1 v3 J% Q

2 G# f& |* L  a& N8 ^& F  O: G% D, u  R
if(!callback)

; K  A! V# j: F$ q
5 B5 ^6 \3 p% {8 A- treturn ;
& v# C- K- ?& ?
# P& |' M  {/ P2 ?% D3 h) E
- J( T0 J( ~- j# ]/ |* f
9 |: z, d( W% r" i
EA = 0;

$ V4 B" I+ r( x( c9 J2 ]0 }
1 T5 H  e, D$ E6 E( f' E
1 V, |% \+ z9 Yif(jiffies <= 0)
5 E0 u6 ?" h; [8 a& N1 e4 u
: e7 b1 d* g4 H: F2 f
(*callback)();

2 m$ p, D( K* ?1 L* F3 N* r2 u# s* w& f  c' Y7 Y- I
9 b; L( M% |6 n. V) F5 Z

. g% b3 @$ P/ T% S# ]for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

8 F. X( S6 r2 r9 u# U) f  f' ]4 A; Q# i( v9 U  D' B: Y. r
if(ptmp->callback == NULL)
' Y( F0 K0 i# j

. a" {$ A& u$ obreak;

1 X4 ~+ v, @, `, O0 f
* @, T- ]2 i$ C5 M
; x; a+ p  T3 \8 L; c
3 Q! Q7 _3 j$ ]) Mif(ptmp >= timer_list + TIMER_REQUESTS)
7 T+ ?6 ]4 {3 h' m) N

6 B  d( e0 b$ M0 q{

8 q$ _) M  O9 O
! }% P1 R0 w  L: lgoto EXIT;
/ U9 g1 W2 ^* \8 |7 I
" f; Y2 v# [" L# |  h+ m# ?
}
# N; {( E+ X8 v& y# {
2 l8 Y2 W" }. K1 F/ C, R9 [
5 `8 m3 O5 E  T* u! C( E
ptmp->jiffies = jiffies;

! ]6 I7 X8 _/ G: W8 H8 C/ m" ]8 h" C4 u3 G. t7 l
ptmp->callback = callback;
1 N& M' g5 M; x' M

8 R* W5 a( j' w) A) l

1 d7 s* O1 {9 R8 w: @  v
* d/ z& ^6 U% ]: M6 ?/ _# j; Wptmp->next = timer_header;
+ n+ w4 b# g: X+ ~

- C' r/ h! n( w, D8 z9 R( o/ t9 Otimer_header = ptmp;

% I( q" Y) S! E' A2 o- [' K2 [+ T0 Q3 \3 r. R; a
0 \6 U8 h/ i3 }" L, J2 A& r/ R
//add bellow code to fix linux on timer’s bugs ++

' W) A5 E! o, X' T( y7 u
2 U6 q% m* M7 @/ _3 Cif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
1 g! s+ D7 b+ h/ e
9 T  U, q6 O3 Y2 W% p9 U/ A; `% p
{
2 h8 F4 g: @: i, o8 p

! W. T: p" l, I0 k! J0 ^ptmp->next->jiffies -= ptmp->jiffies;

3 C9 s# |! k6 {/ j; k8 n5 \0 w: F
* D2 V: R( f  |" ^}//end ++

/ Q2 R* G  l* {" Q; s$ z9 y* S& S# h. {
else
5 ~6 G5 v( j/ Y" \

7 g; h+ `- F  `5 H  ^& b( b. h( ^{

# k$ p/ Z) s  b& c6 {: s7 L. K$ T
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
& ~$ B& S0 A, C+ T
9 F1 j6 ^7 T; [
3 d, w/ ^) d$ A$ x
{

3 r  e/ l& X" w2 }9 B" v6 L
8 A  w' s3 c( @( P1 Qptmp->jiffies -= ptmp->next->jiffies;
8 ~1 q9 `- @6 S. j' B' K, _
. B8 h! T3 ?  U
callback = ptmp->callback;

6 ~* x: ]* S; X* Q& ~6 q
% D& C% q7 S1 w3 S$ R6 bptmp->callback = ptmp->next->callback;
% _- w; m$ Y( x- d1 |: k
" U) r( X9 w. f* D) P
ptmp->next->callback = callback;
& g; e' Z7 D" `) ~  w, O3 |

9 _$ d, D: {- R4 o$ P" I- `jiffies = ptmp->jiffies;

" p: N% k4 @+ u; l  |
( h- d8 W$ V: f7 `ptmp->jiffies = ptmp->next->jiffies;

, ]; m$ o  q$ q1 H1 L7 h' S
& C9 f& o2 ~1 [  M, T5 W! r3 h9 optmp->next->jiffies = jiffies;

- u1 U3 z- W/ @  r+ N8 m4 D3 K4 c) x2 j3 D* g
ptmp = ptmp->next;

- z# y  O* v4 P; `8 _* {6 P7 ~) Y2 Z
}

, o- L/ ^8 F2 e5 G1 a, a$ _
. s# J' H0 C/ H# J}
: r! v1 Z( {, k1 a

1 M9 B. O8 p, A: CEXIT:
) ]% R, Z5 |9 |. x
4 H& W0 O2 Y8 p, G. t, c& BEA = 1;
* `$ R; e: X0 G% _/ Y/ E# A9 q
8 \* p" n3 K9 S- ~* J  [# s  q" {
return;

$ C: y+ T& V$ u2 {}
1 ~) f$ G) {. B- O! E0 D: Y! x1 v# A2 q) u
void do_timer(void)
0 u9 X3 u/ |# B: f. i{& d8 v/ C' x6 ~+ [, R7 D  ]

( V: V. Z" y+ t) J! x8 c  W* F1 P6 u2 r/ q
while((timer_header != NULL)
: Y0 v- r, q/ B0 J' D; h

& e( I0 P7 t. s9 h% E- K/ m) S1 h$ D  C: _, Y3 H; F2 ]' e
&&(timer_header->callback != NULL)

, U9 t& Y# r* {- C/ s
  U& W7 a1 t* g4 U: z( ?; W; B3 z- `0 V- B0 P/ e4 G+ U3 a
&&(--timer_header->jiffies <= 0))
; Z/ A1 a% _# N3 l: T1 T

  N3 `* k6 ^0 W& c# ?8 w7 ~{
0 H4 |, U# @3 d

0 d' e3 N  e/ z7 Evoid (*callback_fptr)(void);

% o8 m: i4 W2 i1 u4 \5 v2 a% r9 _1 f6 Z+ u+ ^8 u/ t& G
( c, ~+ s/ _6 S! j# J2 m& x
callback_fptr = timer_header->callback;
' P( t, C0 X# g, z  Q1 Y3 \& T
5 x* t5 L; ~' U) l" Q
timer_header->callback = NULL;
: i; O- L+ X; {( _' f) H
; s! X* ]+ Z. H& v# h
timer_header = timer_header->next;

3 B7 ]; ~8 k1 K' c; ~% h- Q! I. K2 E2 o. B! ?0 q& c* b" o
(*callback_fptr)();
; r. x1 Z- ^& \- }

/ J- E2 v% g7 L; ^) h}
5 M9 r" M2 g3 B: Y9 m4 ]
+ p7 W3 \  g. S" p! D- k
: ?0 B/ z+ n0 m# H4 N
}
1 L: a- n0 Y4 x: [" i///////////////////////////////////////////////////. \# u3 i/ n5 w9 S% Q8 W) n
* h4 C9 F4 q  I- I1 l
+ d6 }! x$ G2 C5 s
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
& g8 o' j8 r$ t- Z
8 {  d# `) k' Y' c! Z) T野人献曝,博君一笑
. Z7 J* M7 P% H; U9 n! ~( f/ m
" i; i; D8 |$ n3 LPeter( ^2 i. O/ N7 Q
  , H0 S7 }, q% l" [: Z  Y
# i! p1 x- b" E: X' E3 U; v) O
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-11-14 14:37 , Processed in 0.030673 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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