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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
4 f# G/ e$ j" U# X( ?2 P
. Q4 e/ S/ I% {. I  ?( ]1 w
1. Why need this mechanism
  b: N  L* d6 I7 C4 e$ I5 n/ J: l3 i) ^9 V
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
- Q# S# F2 Y0 u& ]* z4 s

, P! K6 ]- a5 [$ d9 M2. How to improve it?
5 E+ Q! Z" p! J. X" q0 d0 T' Q# t7 E# w& r
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code+ y3 b; g! Q: b) z& t# X9 v
- A3 N1 d: \3 s" `7 N5 j
//header file  G! ?0 G! p4 o) r$ ^" p9 X
/////////////////////////////////////////////////5 r: r7 a$ A" |. T3 s/ Q. d
#ifndef0 R6 r2 `0 U- x2 A5 a
OEM_TIMER_SERVICE__H

$ h9 N% l! i2 p4 [4 h; U8 @- C#define
5 m* W% p$ K! z  zOEM_TIMER_SERVIEC__H
2 K$ ^: e7 t$ Y; [) a- |
& O: _; C% ?$ c" N- ~
* x/ n. W% a( z
void add_timer(unsigned short
) v( \( T7 U" P* ^2 ~% Ajiffies,void (*callback)());
% [9 J* K1 u. R# J& _% y! }
. H' I7 W* W; M9 A& H) L$ [" M
void do_timer(void);0 P' t6 r% k  a- r+ _5 M/ ~
/ x+ F/ }4 S6 J8 y: ~* I1 ~
#endif
1 t6 G9 E1 C6 g8 Z; Q) ~: z9 I2 }/////////////////////////////////////////////////
7 n4 R3 ?, \, }% d1 y- [/////////////////////////////////////////////////
( B" Y  F, d1 G6 i/ L9 h//impl file& ^9 N' t+ V4 n8 P9 S
#include <stdio.h>
# Q3 J2 Z! {) G$ M0 B: r/ W4 [#include "OEMTimerService.H"1 t" O3 Y8 t5 {; L( W
5 `3 T* ^& y; r, F5 W
1 d2 |' {- q5 P
#define
. K* C  w4 N7 H7 B' s3 z, FTIMER_REQUESTS
! r, _, o" {  m5 N4 d' P9 r& A0x30

* c9 r' E5 ?: w' ]" K- Y
  q' E( ?* L4 A1 ?" Istruct timer_list
- h+ J' s0 D3 J! X) f- l+ P+ h% j{  D6 ^( v+ Z% w  ]
+ @6 y. C2 `; z$ L" d
struct timer_list *next;

1 x" `. B7 O! F" s9 y) k, K0 {7 {: @/ C4 `3 w
unsigned short jiffies;
5 T7 |. [& U+ N) E( W* r
5 K- v& v2 R- v0 _
void (*callback)(void);

% R; d+ C( \! r) k. F  f) {};
" Q5 H) e) n& s5 K* b7 V- m  t
, X) ~( b: a9 N3 h2 r" ]
/ n4 T: k$ }0 T! h; y3 p  dstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};6 j% U0 h+ c- t7 c3 @% @( q8 F. Z

" W+ S8 [: J$ q3 N% X$ U; f# V( s8 rstruct timer_list *timer_header = NULL;
! T2 m3 Y4 v4 D, R# {7 R! y- \5 `2 m* U! d! |/ R

6 S+ s, @' `; y" E' Qvoid add_timer(unsigned short
# S. V9 a' y- X/ B- t; N) kjiffies,void (*callback)())

' s: x6 X) O' M, f, d! D. \( X% ]{. m$ ?7 u8 r/ A: {+ f
! v# f6 j* y# i: l) D7 F9 p, {/ f
struct timer_list *ptmp;

6 X0 X7 z' E. I" K2 ~$ V! {6 _. W
/ r6 [- g6 w0 ~+ x$ l" y. m% S9 e, U- N" Y% K
if(!callback)
9 p* N/ q$ W" P8 ^# F
5 n  V0 w/ E8 b* M! n" _& W
return ;

7 I8 u8 k. L  w9 f, t0 @; @) Y, s: ]! T& {+ L" s

" r9 o) v8 E  Z" ?+ E) M+ {* E6 n. [0 J; f# _
EA = 0;

, i, {! N" Q5 L9 P$ y6 p; H& V3 J2 d# v% u9 W% P
8 c: e! V# e9 ~* g" h
if(jiffies <= 0)
8 R1 a; \$ q4 q: p5 k
7 u' m9 v% Z2 x+ ^
(*callback)();
- ?8 n( }" w! y+ C9 _$ c
1 y7 n# h) s# q
9 H+ u3 Q2 L% Y, }2 Y( q

, c  P9 L; L; i" C1 I- Qfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
; v& L' V, u% J5 z2 H0 h

# [4 D+ o. t$ M$ Z4 P' Wif(ptmp->callback == NULL)

" p' A( T5 i. t" l
- e* ?* t& T: W- bbreak;
& f2 F% Z6 _, I5 W$ b$ J2 ^

- J" X& w' B! E/ D, _$ k1 d" q4 i9 F2 B% Z! l, i% q

) p3 O! X* J( s; Iif(ptmp >= timer_list + TIMER_REQUESTS)
5 e! L" \5 v' ~/ E' E0 O' O; g

  E2 m1 r6 r6 a{
' I. o. ~$ m8 u- h5 M8 y
! M2 f6 Q4 L& ]6 w
goto EXIT;

1 }$ `; r8 A+ g
& G1 L3 M' v9 t# O- J% n; g}

. T3 A) w% b* P) s" G9 T# l# D
6 M$ C/ h; l0 M- z8 P: }  U5 T: b
* d% U- h6 L, I! v1 C8 {5 Lptmp->jiffies = jiffies;

& M6 L% _4 R# |" E6 d, z  G" R9 t# [. C& u; c
ptmp->callback = callback;

- b5 L+ {* Q6 b( P, L
+ W* q( ?  p$ t3 s& i7 b. X* w
7 k; m/ A' C( f
) D8 ?: ^2 ]9 t- B: @* q
ptmp->next = timer_header;

- b# z0 a. L: g6 L/ w( M  p& \+ S# d+ _8 Z* [
timer_header = ptmp;

$ D. ~/ z( x% P! R3 i! T4 s3 w2 G. w1 r5 u
4 e  U5 E0 x% c+ _/ g6 T& [
//add bellow code to fix linux on timer’s bugs ++

( w5 A, y8 ~! k4 T* Z' G
/ Q. s7 @) [& Xif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
$ ~  L3 l/ `# L8 G5 L& ~. ?0 T

5 b' o* a- s. ]% ^7 ?* Z{

6 C2 j. \+ }4 O5 t6 c( E
9 @. Z, ?3 j8 U- }ptmp->next->jiffies -= ptmp->jiffies;

% a2 z! h2 v4 W8 O6 t
1 H# T) `/ V7 e8 m}//end ++

1 q* d, k3 Y% s: ?0 F2 S7 M" u: h: Q0 Q; w. m+ i& {/ o, _
else
; W9 ~, B2 y! f  q9 W/ a) S5 q2 ?
4 z/ P& x2 V* A: O0 t% p
{

$ k" v4 R5 J# W) ]0 F4 V! {" r. M7 m! x1 Z0 s
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
. P- m% {/ j  n# @

/ n6 ~8 y( N) \0 e" \
! @8 v. V( I0 J, C3 r{
4 S! L& V- N& L. o7 v) F, \) J; f( `
; `/ t" E$ A- n1 {: M5 k( I3 L
ptmp->jiffies -= ptmp->next->jiffies;
( Y( S/ J( _% o5 r* x! s

$ {/ _' v) e6 i% m1 r6 ?0 ucallback = ptmp->callback;

* }0 O' x+ H+ U1 e# q
; h$ @" L+ l& `" {, Optmp->callback = ptmp->next->callback;
; {$ x8 A" s0 i+ F

# k: v7 o, [  v% {+ Aptmp->next->callback = callback;

2 {( w; n2 [( G& @  v7 y. E
4 N) z) @: b/ ~9 mjiffies = ptmp->jiffies;

' E# v9 E# c" P! }5 x  p8 w- h2 h; e
ptmp->jiffies = ptmp->next->jiffies;
: v5 D9 g( G( @3 j$ f

4 {+ Y7 ^$ r# U  Zptmp->next->jiffies = jiffies;
' _4 f, G  q* ~- h! \2 v

7 d8 G" s( {6 L: Y3 S0 D, Hptmp = ptmp->next;

# C+ A) |6 H* Z) d3 I
- m6 }& n5 E4 c5 V3 |}
! p' u% Q; K* }7 l+ H
) q! ]/ t1 S6 Q0 i, S1 `
}
3 m/ m4 N/ T8 z1 s3 l

7 [* V! W* D! @- ^" oEXIT:" @. j3 h4 M9 z  C) Y

. I  t( g% t2 o! DEA = 1;

# m5 g: F& u" _: ^1 p2 n
) g( S: @% L( B) P3 D2 [  Yreturn;
$ `' ^( O3 C# _9 P6 Z/ A( h7 R. Q
}
" i  J/ z3 n" W7 z4 R5 _: [
2 B; p0 |: y6 ?5 ?& `& `& L, ?void do_timer(void)
% B5 P; p  {! g7 k2 S& n" F( x' K{
4 h, s! u' X( @3 j
  A1 Q/ g8 ^6 f8 g/ j
' D' f: h: m4 L# M- K/ M+ k; A
while((timer_header != NULL)
+ t( y+ a/ b) ^3 P. z

# S6 A1 R& \3 \2 T/ N# X. `# F$ s1 `0 A# V- z( R! M9 r
&&(timer_header->callback != NULL)

5 V, Z# K  W$ Z3 l% Z0 Q) h+ t8 q+ E$ a8 a: G

$ {  r' O1 f9 ]&&(--timer_header->jiffies <= 0))
( g3 i" M* y: N- X/ W9 ^' U

$ v6 J7 K8 [6 t* W+ @{
3 v) L, V- ~% h3 o
% _$ H% e8 {2 W# ~3 W# a# h4 ]
void (*callback_fptr)(void);
5 C( [2 e. x, q5 U7 C

( @0 q: s0 P) e- G
3 x4 }2 M6 {6 N/ r$ J5 V) Scallback_fptr = timer_header->callback;

! i- ?1 G+ s; A& |2 E5 _
- J, a2 T# {+ h& M& B& d! V! wtimer_header->callback = NULL;

  `! s4 y! r( ]9 C
! q, Z8 n/ V$ r- M0 ]timer_header = timer_header->next;

  Q+ R. O; s5 c+ A9 j, r
  }5 H- }+ w2 D$ I(*callback_fptr)();

" J) o% J% x" x5 D& J9 |9 q2 o$ \/ A9 [+ p
}
& x5 ^0 e% _: Q* ~1 U1 L

; q6 j0 F( b1 r- B* k( h# m% R9 {
! s! O$ N. c" Y7 J' X$ W
}$ M! E! \1 Z5 o" d4 M
///////////////////////////////////////////////////0 ]3 J4 L+ X6 q, r% o9 x

4 `+ @% n; o' m0 ^" M" [5 p  V
1 \) s+ v/ X5 j& M1 g
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!" I* {8 A( [* U9 G8 ~) _4 y3 A1 ]
. C8 [# S& F$ T: C$ Z" p) k! i- p
野人献曝,博君一笑1 D) y. N2 M! U& V+ F# _

3 }; K7 k& i1 T4 p; @Peter
# {) T, D& A6 [6 S* q9 x' Q  
$ |* W9 _5 F& F, G. D3 Q4 n
- q% ~8 U' e5 J7 F4 Q% C3 J5 M[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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