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

Smart Timing Mechanism

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

3 E8 Z+ x1 Z$ Y% N  \

; z6 t, h5 i+ ?' F2 [6 T7 ^1. Why need this mechanism' ~8 n% Q5 {7 B$ F
  q0 U  I3 y5 n  N6 E
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
; g& V2 x4 Q( A8 b: {/ b3 a- ^7 k3 W
* a, t# T2 O$ E
2. How to improve it?
: G; \  U, G2 z1 b" X( @! F) x& v; \! B% q
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
* U3 D1 c9 j( M8 ]' |
5 f$ \. E  y- k8 W$ H& P! P( G" ?//header file) \  n2 p1 y' X) h- R- o  |! P
/////////////////////////////////////////////////6 O# `  R4 A6 ~  ~
#ifndef
5 r, C; d( t' ^$ U  p1 h( N4 UOEM_TIMER_SERVICE__H

, j/ L' y; k3 J3 @2 h2 q  d#define
- M. P. i* g1 z3 c3 t* XOEM_TIMER_SERVIEC__H

2 m  [- U/ F) n7 v0 I, ?: l; e: [: B$ C; j- @  ]: l$ @
) p) \( l' @  Z( |1 ^6 K
void add_timer(unsigned short, L2 a' ?' P, }5 Y
jiffies,void (*callback)());
8 B0 ?6 I0 \9 r- r1 s2 O

. |* P4 ~" A; M" ivoid do_timer(void);2 V, h; K/ U; e- F4 w6 R* A

3 N- X" l0 x: K  }  ^#endif
9 @/ O; O9 \, S2 ?! ^- }/////////////////////////////////////////////////: J2 z- J/ ?% c  b, Q0 `; Z
/////////////////////////////////////////////////
& K. v5 s; d- V, y: U* Q//impl file
+ W- b! M3 f, P6 b9 M6 ~  V4 U% `#include <stdio.h>5 L, n2 ^& r; P
#include "OEMTimerService.H", \8 s) G2 [3 g! G- t# c7 O
' W. j" h/ U0 O4 H2 s

* w8 g4 `" Q1 j; a* D#define
( C4 ?4 l, E  ]2 T7 E- h. DTIMER_REQUESTS7 Y. B: s! ?. d& Y8 e  @
0x30
* h, u0 P9 d+ @# [0 a

7 c; m, r' i' p$ j1 j2 d( B6 \8 l# ^struct timer_list   ?, B% ]( L3 z% K* U
{2 K5 i  d; o; a& D$ a3 d! ?

9 M1 @9 E) H7 _9 v8 Y2 |8 w: @struct timer_list *next;
' X" J- d0 j4 S
6 ~( f8 _! m# H0 _. Z
unsigned short jiffies;
, K- k1 E0 h2 D4 B

4 s$ D' i0 t' C- W* rvoid (*callback)(void);

3 A! f* ]; B5 h3 R};
6 O- l7 |2 G; F, A) F/ a+ f9 x
$ b' S# n$ t8 l* W6 P7 B
& T; n9 U: ^7 n# e7 R) ]struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
1 g: B' q; E3 _8 M6 x& `* d0 B( W' k  Y0 u, f- f+ G7 a
struct timer_list *timer_header = NULL;' I& A3 a- m0 Z5 Q0 V3 `) k

  s" a5 K2 R# M4 T
! f5 w) f5 `. T; j9 O% d( B* Gvoid add_timer(unsigned short6 e9 x! z0 b" i# f6 \
jiffies,void (*callback)())

# D1 v6 B2 S+ L  f' Q6 d{" _/ E  D% ]4 q4 Z" n+ @
! d1 S. e, Z6 ?7 ^  U* z$ s
struct timer_list *ptmp;
2 N( n% r/ o' q" h& o5 A
' l/ R1 o7 ]3 Z) B, q

. k% R/ A) T3 h: _% S% ?% \if(!callback)
) [" O2 |, c* S! o. J& X$ M

! c2 t8 Z7 ~! xreturn ;

* ~& L% q! b2 }$ k3 i/ m$ E
+ C1 ~0 j( ?  Q4 F3 T

8 M& ~0 n2 ]& a) u$ K. C" |$ B" [- _, R# q9 p2 ?4 d; b' Z7 t: r
EA = 0;

+ g1 d6 ?* L4 C9 [
4 \  ^2 v7 b7 @! N
  A0 f* H7 L2 t5 K: W! Yif(jiffies <= 0)
' w$ W- j( v! w; f# O0 Q. A$ X
& ~0 F( `) y! s# K  Z
(*callback)();

1 }" p; @  W4 o( P# i! h( m4 w5 B$ d+ r
! K& N; V! v: Y. p
( Z. I4 @& X7 G  e3 D
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

; S( T4 \3 {3 a$ X
; e5 D7 k$ Y0 Tif(ptmp->callback == NULL)

  }3 Z" R" l, y& s8 B. l- l. h2 N3 D
break;
' A* X! F( j/ r2 |
4 J' l+ ]/ }7 F- v, x( Z5 b' H3 N

$ a5 Y5 @  E8 ]7 u6 q- X9 f
; \/ A. E# S$ w# W. s' S% aif(ptmp >= timer_list + TIMER_REQUESTS)
% I" q/ n+ s9 w/ I$ B" v8 E
" |: h$ J8 t' m8 ~
{

& c" i3 ~9 `; V' h7 ^/ m
5 d7 h6 q6 E% K. \% p7 _! }' f0 ~goto EXIT;

! [+ |, I- W9 f
; V/ J1 Q1 `# y9 \" H, N5 c}
; C# m! R: X) M

8 W( z/ \  ]/ z9 h8 d8 o
( X' p, T3 _3 B8 t; w& B& xptmp->jiffies = jiffies;
& l& t% k* w7 o% |0 |
' g' r5 Z1 W4 l7 o
ptmp->callback = callback;
6 U/ `; j& \6 p7 o9 f

. z9 U; n& v; U- M& }% `$ X& Q

) \/ d! `  u2 H" G6 L: ^0 o) i0 R
, M" S" g& w! v. ^: Qptmp->next = timer_header;

3 `  |# o6 A$ i& q3 L0 j! o. s+ Z2 s% U& T$ j/ `
timer_header = ptmp;

2 e% N/ T& d4 G: @9 n1 H4 z3 G# E( d" Z% b! T
6 i$ n& A4 r1 _( M% Y& d  p* l0 l
//add bellow code to fix linux on timer’s bugs ++
2 b6 O! Y% R2 n+ B& U% x- z
  g  t; \; m1 C
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
; h" k7 L8 n1 g. V9 q

0 e8 ?$ v9 m0 ?4 r{
5 R$ P0 |1 @0 `4 d( _/ V; k
6 J1 e3 ~$ s) `7 X
ptmp->next->jiffies -= ptmp->jiffies;
( \2 X' a# \$ @' T
/ ?! P: S% ]* w6 P
}//end ++

; p( b: n9 t3 m" D4 a: L7 P
0 g+ P% l2 G$ h& {/ y" belse

* @; _! R5 ]5 |' ~4 Q% q( |. \$ i
* }- {: c9 i( h0 u1 I) _{

9 @. a$ B* q0 f7 k! A9 t
0 T; _; w) E8 |& fwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
% b6 @+ X8 f: Y) @% o1 U' i0 D& [5 R

5 u( z  Y* o1 R1 F2 d+ k
. V% |* {. g5 Z3 _" z* _{
' A. X0 k/ X4 X

% M7 N) b4 q( L9 A1 ], Q6 optmp->jiffies -= ptmp->next->jiffies;
8 v) \$ J1 A  l5 k* A5 l
* e) j5 ?7 I( T+ p2 X
callback = ptmp->callback;

& N- g1 l8 J- n
3 V/ `! J5 o- a# ?2 Q! Z# zptmp->callback = ptmp->next->callback;

& I3 n$ z5 A: L- `: i5 ?
" N; U, T7 k5 F8 R; U1 ^$ W5 ^ptmp->next->callback = callback;

2 s3 m$ `" Y- R6 |6 b. L, @0 A& y  b7 m5 Z, i9 B9 I' H
jiffies = ptmp->jiffies;

( b6 n: X0 `, I) E; L
' h  N: L/ W& z" ]8 P7 ?2 |7 hptmp->jiffies = ptmp->next->jiffies;
) N; t) J$ z% L: p0 w

5 I, `& j7 m" O" k' Q/ _' z, m0 p3 hptmp->next->jiffies = jiffies;
2 m( i3 y" L! t4 A. g
0 s0 E% z2 r/ @. B  E/ c, o
ptmp = ptmp->next;
! f: q: \+ \1 W2 B5 \9 w8 d5 ^

% G1 L. s9 |: ^  \1 O" N( C}
  @+ Y1 _  t% p

) _7 ]* Y# n" L( I6 S1 C# n}

; L' |; t, c* N- {5 I' z' R9 M8 M3 E8 q9 v0 {0 i+ O
EXIT:  Z# j. x* M$ Z
8 B, r, r3 p$ s6 i; I
EA = 1;

/ l3 [: m% Z; j* B/ q
3 n2 r' c$ b+ Y+ f2 breturn;

, h# P$ O, Z# n; j6 }; [5 d: Z}6 e' o$ h" B; k% \7 M- v
) S3 U0 X. G) v3 U6 ]6 V7 G' r
void do_timer(void)
3 U1 x1 K& m- S! K1 }{. N7 y% f8 P% Q/ H; b0 e: R& h

; O0 H- H# Q* @$ F' Z* q3 K& ~9 ]9 U9 x( Z% f
while((timer_header != NULL)

: C# g. O- y0 A2 N, p. E
* I; K5 f1 N4 H% u; P
0 K. `& T* s1 x) B&&(timer_header->callback != NULL)

1 `2 h' B1 |2 l) R8 h+ B3 K4 d' T4 ]
/ d4 @( d' c+ C' P2 ?! K) D7 D  u* b& j# m& l, t0 U- r
&&(--timer_header->jiffies <= 0))

! e+ L9 E: ]( \% h$ v
1 M/ K- {$ ]% w: a. n1 T1 G" V) H{
5 b2 Y, }4 u8 T# ~" B
. s- R  L2 z" X) H
void (*callback_fptr)(void);
! p$ h/ z4 R5 T+ k

+ K+ q( q  c$ C( J; {$ p8 A7 D* O  ?
callback_fptr = timer_header->callback;
' K. H& I$ q/ e7 _# e; P: H* g0 @$ e0 h

/ k4 K2 |  `! r/ ?: B% Utimer_header->callback = NULL;

. |% C  |' H8 y7 a( ]* r( @% E1 C( R9 ]2 j. O0 ^
timer_header = timer_header->next;
2 @% C& p9 ~: @: d$ c/ h

, ^9 h8 T( c$ z2 U: x(*callback_fptr)();
- a1 g. g3 S: h& f3 j
4 Z- a4 X) g1 H$ d0 C" M% ~
}

# w2 f& }3 C& M0 |- |$ _0 U
0 e( ^( }) ?; g3 T( m7 z* e

$ t0 s8 d2 T) Y! M3 b}
  y8 e5 u0 r& e7 ?2 d  j: D) ~///////////////////////////////////////////////////. \' ^* L  O: I, W5 g) ?9 h/ t9 m: }5 H

# }4 L8 P# T4 {  u* l8 T, A

1 k! f  Y: `6 ]  Q& Z3 C上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!7 B4 s1 d5 h1 |+ O8 V

# \2 ~/ W3 d% [5 j野人献曝,博君一笑
# h( ?5 y* [# w- ^, L4 D$ c' w* {3 j$ j( {  K. z
Peter. a4 N  Z1 X# B/ n: z% G9 O! d
  
& b3 E1 s8 S$ Q* F" y$ [: F+ _" x. \' g9 C% u4 o
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-4 14:32 , Processed in 0.100909 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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