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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
2 f' e" q% c! C

9 O9 d% g- T# h. P( j1. Why need this mechanism0 F% ?: o" X$ @( v2 \! C8 N

( V, x) ^) `) |0 L* A
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
, W) v) E( S: H. A

" D, U3 }* N: v: X! K# q1 ~$ f$ F% U2. How to improve it?
( p4 |6 O! q8 ]3 i, x- ]6 p. k, u' ~, x9 X, m
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
- ?  B; _) }" d& U/ L$ P; z3 D
/ W( T3 P0 W3 V//header file
6 y6 ?2 B$ e) S5 a+ n0 b, D/////////////////////////////////////////////////
' v& p8 e% v- X7 j# c5 N#ifndef( ^' G7 q2 b! B% a  }- i1 O  P, B
OEM_TIMER_SERVICE__H
- o" P- Z' t6 P1 M
#define
+ @3 \/ R. ^) }" R) N: C! n+ ZOEM_TIMER_SERVIEC__H
$ G0 V* k  ?5 O3 O" `
( c8 P, ]8 F5 X; M6 N" f

. u& t: @6 i9 H* B  Z! q. lvoid add_timer(unsigned short
) c4 w) }5 S, e  u8 _& Sjiffies,void (*callback)());
3 F4 {& d! E3 I! _
1 e6 N6 L+ c2 d2 ^3 r
void do_timer(void);) q: V. A9 \) [' ~

; ^+ c$ f8 E* i2 `- e5 |#endif0 I& |2 W# H# X" ]: ~: G1 n4 S
/////////////////////////////////////////////////" Y7 f2 p& ?" ^5 K: `* p
/////////////////////////////////////////////////
3 b* W8 ]- m( B; {( i//impl file4 q1 c2 s" j  I7 g* p! S& }& u0 v+ Y
#include <stdio.h>
! x. l& W: e4 c# ~) `3 f# I#include "OEMTimerService.H"/ O% J( n( y+ f6 M. [* s$ S; T

2 F, X& H" @* q5 v
& J, w2 E4 g7 c$ T+ p% {) m#define; ]; A# O' e) k1 |( Z
TIMER_REQUESTS0 A8 S, S0 U/ |0 B
0x30

6 I  F/ O$ e$ T% o4 t
. C9 W1 i7 z3 w. C- L- Estruct timer_list ; i0 q6 ^) @3 R0 o
{
# L+ G8 E# O7 I6 B4 v8 c% s$ `1 q# g+ ~* @
struct timer_list *next;

3 l/ r4 @; V  z& f
& f. `" V/ x4 Ounsigned short jiffies;

$ q/ l6 ?2 ^' O- L9 `( ?1 y4 k$ m  A9 G6 [' m  T
void (*callback)(void);
' |( b$ t& Q- t8 Q4 ]; v3 K, E, G
};
1 I! j8 l' q, ^7 m' r: S' a  J+ F- ]1 k  v: Q
& [7 Y0 W/ k$ |2 W1 ]% D9 y
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};* A1 x& _+ {! K! q/ Z1 D8 j) ~

+ C+ e$ O! |- B* q: T; wstruct timer_list *timer_header = NULL;
8 q4 u) N3 V# n+ g. i+ A% B" D$ u! B- A( ?

; M- W, X* B" C/ L: b- A1 Qvoid add_timer(unsigned short! V& q5 |# K' c' G7 D. g5 X4 [; p
jiffies,void (*callback)())

" S& {1 X6 k  [% O{( f- o+ V2 I5 f* D

9 U# ~/ A7 p6 J4 Cstruct timer_list *ptmp;
) Y; y" v  s2 U# z

2 \& c. M( }, P; r
9 x" w( R& U! `  kif(!callback)

8 E1 z4 R' `5 G9 V! m) r+ Z0 F) _) R: V1 C
return ;

% }" s) I4 e' k2 m, l
2 b7 O; U0 O. K4 b+ Y

) f5 |4 Q) }; t# }$ y4 F9 T6 R3 p- i
( j5 o% B0 m& b7 Q* ?$ c1 }+ K  }; mEA = 0;

! `7 _4 U  D0 g  X3 c5 `" b- ?
9 B, z- S( w2 T) M( u7 s4 W# A7 S% P/ _! u) C+ T; J& `2 G& R4 T  d3 u3 g
if(jiffies <= 0)
$ J% k0 |# p/ H% O/ v: @- T
; u- ?6 V" R, b, M+ a2 h6 g
(*callback)();
* g" B( F3 i- i* v

  s( Q' ^  n  d3 N

' t4 N: {& I0 r6 J9 Z
+ H4 q$ p0 K. @* p5 `# Y, Cfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
0 D( T& i3 `9 B6 d! l) B
- `( ~2 s9 S: }5 q
if(ptmp->callback == NULL)
; W  I. N* G* K

+ s1 g$ p' l# q; Y4 Q7 v* @break;
8 g2 b8 W$ E& n% M
! f: v  y( A( [

: m8 ?9 B8 d9 x% S% j4 b  f* p, G- O8 B  v7 S
if(ptmp >= timer_list + TIMER_REQUESTS)
0 ^6 {1 |1 h3 X" z% g2 m
4 g; j# `6 ~6 R5 p
{

) t) j" P  `1 @. y' o) D( Q
+ q9 z3 C0 h7 }4 _+ Y( [2 A1 r+ Q/ }goto EXIT;

: ^+ h1 N9 Z4 n. w
; r! r* D* ]( X: ^}

4 Z- d5 P) @6 U
' [5 b& R1 v2 v, [) `
7 x$ O# X0 [8 k, O. U" S' Qptmp->jiffies = jiffies;
& o& I* p8 Z! I
/ d9 d5 H& j, p! x; k2 m
ptmp->callback = callback;

! A0 K6 N# ?- s/ r; T8 u8 ?
8 E& q/ @! g1 N$ Z3 b& [
& h7 b9 e+ b( u0 w
! b# x0 n( M) P* F/ Q$ z
ptmp->next = timer_header;

5 e  V$ [6 l6 }2 a* g
4 m  S" e! \: A4 \8 `- ttimer_header = ptmp;
& L0 V+ c9 A% V! h$ I
+ N% g' q  c' l: m  x

* b( H& f/ U  Z, D//add bellow code to fix linux on timer’s bugs ++

. w3 G. J7 H7 K0 E4 ~. C+ b
% z5 f% `0 }1 G( w$ v& g7 Uif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

# G& ~' [: D( X) U/ b& e; `9 H
9 {# u, E# l$ _8 ~" H; j  M{

1 z+ L: y" v! |2 d
0 S$ `5 Z3 T( O/ l0 M# Jptmp->next->jiffies -= ptmp->jiffies;

/ i2 v% r/ Q/ J' m3 w$ L8 D* @( g* T# e! y, Z" C% ]
}//end ++

2 D3 ~' e9 u+ U% x: {, C
3 V2 K; ~- r5 {# F3 Q* x! O/ h# delse
( Y/ [) g# |  r3 Y2 r
7 F" `6 O1 |. H- F/ W& `0 x
{

4 H  [& d& M3 z4 ?# b6 b& o$ D: v# d! g. P1 P/ R! q1 r
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
* U- k% H4 H& G& g% L$ L5 T
) d% E. Y9 _; \3 m( J1 Z. p) C
1 e3 L9 a' Q% I( E# F3 w/ y
{
. B. S; x& h0 F5 C

. A3 Y; ?) E2 [/ @: a, Pptmp->jiffies -= ptmp->next->jiffies;
- h2 Z$ y6 S( C! c
3 P0 @3 w7 N  J
callback = ptmp->callback;
2 V% ]1 J) L5 d; q$ y
# V( l/ {+ r5 g: l
ptmp->callback = ptmp->next->callback;

* I4 h* W0 W  u. F2 K" ~
) T8 v  g8 p9 x3 R. j& sptmp->next->callback = callback;

5 g# g* n4 u) o) P) Q% v
0 w4 @. {2 a0 w8 O* h/ i5 j9 Pjiffies = ptmp->jiffies;

* {) h& i. [8 j: k6 N& R& S- l
! q0 A7 X# |8 K# \4 }' Aptmp->jiffies = ptmp->next->jiffies;

. x6 B: b; [8 S8 N9 J2 R6 X+ {9 N- O5 D) p/ A+ u5 D
ptmp->next->jiffies = jiffies;

  b* W6 Y1 a; T1 b8 J6 D, e" G; P. C: k/ }& Q
ptmp = ptmp->next;

+ Y+ m! d/ `/ |( `0 }
* _1 X8 y8 g4 w$ N3 a* G}
2 n4 f0 i! X( O- G

& J+ `% h- ?" e}

! u- p3 _- U9 g! n8 h7 {/ m
$ e6 M  B) r' o: C$ H6 K2 gEXIT:/ y9 N& V/ L# ?1 U4 b" M9 A

; L. G4 g" ]/ h7 ], j2 d6 Y& bEA = 1;

0 B$ I. |; o: l4 I8 I1 n! h- Y0 M0 A; @- n$ a' p+ |
return;

* |7 V+ M8 K5 M7 @, F- |}
  L, a! _1 f" f5 H
3 R( F) z9 Q, H% S7 T* _, lvoid do_timer(void)
0 v+ H; J7 F& ^7 A1 _{
& H4 V6 p4 `6 i! t  h
  x" V: ?5 X* o

1 v$ v8 Y8 d% B$ h: Swhile((timer_header != NULL)
' ^5 q/ Q  y7 v" p

$ ?: _) Y6 L3 N! z1 g( N7 K5 k4 X( v3 E) C# O
&&(timer_header->callback != NULL)

. ?" s# L  h* I& U. ?
0 ]3 Q: h8 C( D' w7 [
( g* _# k" H% O( [% g1 R( J&&(--timer_header->jiffies <= 0))
0 V  b, T* \7 f! z: a

/ p+ w3 \2 v  s" w{
+ @8 t3 J* z/ s4 {
1 \+ s" Y8 F5 J3 F* f
void (*callback_fptr)(void);
+ N$ x5 \$ A  R+ r$ c( u8 D7 W
  R* }5 }. k/ x# B
3 e& T6 ~- x  D8 G" ]
callback_fptr = timer_header->callback;

" u  ~/ G3 {/ Z  u. X- Y! [) c' L
' W; l2 E% n0 B' u% \timer_header->callback = NULL;

1 K- o4 D+ o+ S/ b5 j: y
2 u: \" C# u$ N7 F* ^% c. ~/ o  atimer_header = timer_header->next;

% y. I0 e) _) h2 g' |! ]( j
2 f* C$ i) i* _7 @0 \+ x(*callback_fptr)();
3 q# N8 D7 \8 J& ~) ~$ Q: n; F( k
. U3 \: e; c/ I* `6 ]
}

: _3 ~5 z- T7 Y6 E" Z$ l! ?) H  C, O& i0 ]. [# |9 t, t) c

1 G+ e; W4 Y* M- X6 H$ }9 U1 S}
8 W: K& S- S) W. T$ F' x///////////////////////////////////////////////////
4 v' r9 `+ I7 L1 \9 A% G
7 z/ y3 j, ]( g( g; s7 X0 ]3 u! o4 ^7 p

$ p! G$ o2 Z: Y$ u* J上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!; l( @/ }9 k0 y

! U$ K* D; P: W7 Y野人献曝,博君一笑+ t9 B) k6 m0 O9 h
4 H" x. u! ?& Q
Peter
* U- y9 P( y) X9 o- l) X# I  ( W  t1 N1 E) U5 {$ m, D

1 v/ i" a7 @! q9 S- m6 R) `[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-3-5 14:40 , Processed in 0.771292 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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