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

Smart Timing Mechanism

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

' m1 |! L8 J+ J" e  @5 U

0 u! B: E( z# o! J1. Why need this mechanism
; `, y+ T9 W- R/ H* h8 W7 v1 A8 A$ t9 k% s& P0 [- }' B6 g# K5 @' \
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
5 F# S: ]. h( B2 A9 x* D

3 K6 ?1 F2 ^" b. A) ]2. How to improve it?- v+ p9 u. H5 l
" s0 Y* @% Z. o% h2 `+ Z7 _
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code  ]2 X( f' ~4 m/ r
7 Y$ |2 u+ J& V' ~7 Z% S5 S1 H
//header file
, H$ b8 C: A6 ?/ c3 |+ Y  f/////////////////////////////////////////////////
; j: i/ m" u1 m3 ^8 x2 b  M2 p: x, _. w9 g#ifndef
0 ]8 T7 {+ w% tOEM_TIMER_SERVICE__H
0 B8 p; D- I* X2 H6 _/ Y% [5 C
#define. p. j4 f/ }9 \
OEM_TIMER_SERVIEC__H

( a( p& J3 m$ B8 u1 p6 Z* m0 U8 l" ~4 ~2 {: G
8 U. u- D% W2 [. P$ m
void add_timer(unsigned short
1 Z5 H( J( C1 W) ]jiffies,void (*callback)());
) X$ w2 a9 h" E- K- }
4 _* M, x% ^8 {+ Z# t* L
void do_timer(void);
- G1 H  r  O6 l0 R. N
0 ?. u( P: S2 z) u#endif
5 o/ G' w4 P3 l2 e) c: F2 o/////////////////////////////////////////////////
6 |( o" E  H& j& m7 v& H/////////////////////////////////////////////////
5 ]3 o8 i; g8 N0 c: l//impl file" o5 {6 x0 e" ^% ?) n( ~  \( C2 i  C
#include <stdio.h>
+ ^" P/ Z* l: c; X, _/ E$ }#include "OEMTimerService.H"0 N" h; R1 g7 N! ~$ t0 t

/ D1 I4 @8 O( l1 G& u
9 `- F! J5 b6 b# R; C* E#define+ W3 F" ]8 V' Y. _
TIMER_REQUESTS" g0 g/ Y3 ~( V
0x30
: D9 S8 h" X% e9 v3 X8 ~7 A) L# D. m
: J, Z) ?4 f  d. K) h- A
struct timer_list " K0 {, \, K' D. g) l/ c. r1 H5 E3 h7 o
{, Q1 \) P2 U8 s4 v) i! B; U9 q
, f* o, y8 {! t9 I  u4 [
struct timer_list *next;

( Q5 Q3 N9 O! M! X  s/ w% ?! T, a# L% V; D' R5 {
unsigned short jiffies;

' v0 }! q: u; k5 W. C" N  t" _) N8 B- |# Y
void (*callback)(void);

! z8 a' z3 l: U3 Q};
5 Y: R$ `" Y- [- [) n3 b' X
; j, e- d3 @' i2 t! l
5 S5 j7 v9 n5 _, Q% Q, nstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};, I. X& Y/ r; C! w$ A, [. \

8 i; I0 d) P5 M9 x' tstruct timer_list *timer_header = NULL;8 E! A& U; v) F2 Z$ R) ]: X1 n
& I  l5 A, ?* P! F* _; B3 o# ^& ^) y
  Z4 m2 p- Y0 x( K' L
void add_timer(unsigned short6 `5 N2 O- E, A1 c
jiffies,void (*callback)())
$ z* V. h7 H5 k6 N! M: g5 {% {
{
0 f: E8 p: e0 D; ^  r3 o
) t: A  I7 J: H' qstruct timer_list *ptmp;
0 {+ W# l# V. K9 S& z9 ]( Q1 ?6 b+ _
2 W0 G. g) _. M' ~* u
, t. P5 r8 K) A: R9 z7 G
if(!callback)

& w; U8 N/ _, q8 R
0 `# Z7 U1 q9 S3 {, O3 sreturn ;
; ?  a" t8 d9 @! i8 I

* Y9 [# o! g+ I7 [1 W3 x* o! l2 y6 x

$ d9 C7 ]7 J: q; C6 D+ r+ x# B
EA = 0;
8 c6 u( p% j9 C: M0 Y* @

& _4 l: @. K; U+ g" g2 ?" U" ^0 H/ Y5 W: Y5 G5 @1 D) F; a
if(jiffies <= 0)
8 t3 F* `1 \3 C6 P! z; g8 |9 B
. ]/ y& {: ]! }1 A6 f+ U- {
(*callback)();
2 ^' M. D% W$ g# p( G6 H5 _! Z
3 c6 C* s' r5 o
" x; k; }5 ~9 F) c' {

9 e2 x" z- c8 r, C' s( Vfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

" R. V+ G  k+ p- i) U  Q) ?5 K' U2 L4 s2 @7 R# E
if(ptmp->callback == NULL)
# [& B+ F3 N. n* B% l- c$ _

, R, E+ ^" |0 cbreak;
; }/ e( M- s  n& F

0 X9 _: t; @# b& P$ z5 b
- P" Q0 I5 O' ?/ S' U+ S' d  `, A# P. M
! O4 ]* g, A1 x) b/ {* @& O. dif(ptmp >= timer_list + TIMER_REQUESTS)
. E8 d, q0 {) K4 v$ O  \1 F

1 C- b- m5 i$ a9 S( u6 M{

! F3 u8 n6 @& L' n5 d3 N
% h$ {6 x- x3 J$ E: L: y2 K2 W/ e' ]* ^goto EXIT;
' A0 c/ i1 N5 n, Y- `( ]
7 Z  E7 r( U9 ]0 d/ _7 B
}
) P6 t" h( t; z4 b- y
, E% _3 I( V( C
& X) ?8 M2 Q6 J" ^% r* G
ptmp->jiffies = jiffies;

# p5 ^% p0 r& G! R- i* e3 ^& N4 u9 F
ptmp->callback = callback;

0 {) O9 Q1 L. _; x5 I& P% \) q6 W& H' A7 I9 O4 e! [0 q. z$ }
) p/ N) r# B4 Q7 Q2 U3 E$ ~

1 \3 v( V# i! t6 z, b9 C5 sptmp->next = timer_header;

5 \$ v7 ^) T9 b% x" v% N
: ^5 x# n$ G+ y9 l0 T9 t6 Utimer_header = ptmp;

! V! g8 Y2 G" m7 u" q! [6 o( T& Z6 X& k. f4 t" i" _9 `
( `. O& r8 q0 l7 R! m. y
//add bellow code to fix linux on timer’s bugs ++
: P- Q' h: w: U, s. u1 L7 u

9 A) {" h& R7 \. uif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
" D* W4 r- S+ m
& |; Y0 O" f  M6 c& W1 ^
{

7 T& i0 u9 T3 v) m- e6 N" \# I% y: A# C' Y1 x3 j7 P
ptmp->next->jiffies -= ptmp->jiffies;
- a4 b9 b0 m" P1 d) A1 o9 D
& k! c" \+ e% Y! Y/ Q; Y
}//end ++
8 }( }7 b3 T/ _3 K) t- @% {% S
% U8 _" w. `; {& h! q
else
/ s, L4 I3 L3 B
; v# Q7 `* x# S3 a, W5 p2 w
{

' b3 [( L. ^4 K7 c& E
$ P9 Q5 H9 j) w4 f4 u4 Qwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))6 w$ G! n  S  h3 s0 Z3 f
7 ^0 j* r- Z" B

+ `6 G# A% d. U7 P{

( B; l0 n# B7 T* E: M0 n) T" B' q: K3 P0 Q
ptmp->jiffies -= ptmp->next->jiffies;

, G. K  @& A5 \; p
6 ]: C% I8 b# D- a' i+ Qcallback = ptmp->callback;
7 S, Q: H; B9 o

6 u+ I7 L/ }" @ptmp->callback = ptmp->next->callback;
2 B% \- k$ a$ P% f  U

! ~/ _6 b1 X+ d9 vptmp->next->callback = callback;
+ L+ r6 j' h' G, e! y8 D% a- n" u
1 F2 U: z0 V7 \0 @; P2 g- a7 y, n
jiffies = ptmp->jiffies;
& ?, N8 g' ]7 W! S/ Q0 z

0 W; ]* H& O( K$ v% l, E' aptmp->jiffies = ptmp->next->jiffies;

. V' `" n* e/ m! ?4 H/ v: J$ y' H
ptmp->next->jiffies = jiffies;
" g1 d( R4 c5 s- _8 S! e
; z! q" `/ b1 l# ~: d; K
ptmp = ptmp->next;
6 H3 \2 f6 x8 e, f6 D) y" K8 v

$ [* x: A! n2 Q& \/ y. n  f" Q}
4 \' B8 t% P' l6 V

( Z4 t, \2 p7 E% I' n) ~}

3 i. G2 W! h, p+ A: [9 A# m$ p* D  P
" W/ j, K( C' n, h, \  B& REXIT:  x) J3 ?+ T) Z1 g$ _% @& T

1 x- H4 A2 p8 ?  F; K' x5 vEA = 1;
4 O  n+ O8 U: P
" {% e" v1 U2 @
return;

! Z* D' j5 s+ X, ^0 X/ ?}
9 `/ P5 z) `" N7 `% j! K. ^6 W. }3 v; W
void do_timer(void)
) r  Z+ J; O7 ?& X0 ]4 b% I{
$ o8 g( M. i- N' m. k7 w. H8 j, D# J

/ G) k0 c: H- E' Y
0 g' C1 g  }* F7 Kwhile((timer_header != NULL)

& E2 v$ R% Q; l1 c. {% [, t( f* j* [* s/ \/ f6 a8 @4 J7 R" [
" U  N; B/ D/ G* [4 B
&&(timer_header->callback != NULL)
$ ~8 m; _4 N. ?; o8 }" A8 o

+ a2 C. l( n8 A! I( m  u" `
/ \5 ~( D  o0 @' A. f8 i&&(--timer_header->jiffies <= 0))

4 n7 `+ D/ o; l2 x7 Y; d. E) }2 }' N5 ?& w9 W, a, P* v1 a2 c
{

; C. z1 t9 I- p
( [7 z' ~! M9 t+ zvoid (*callback_fptr)(void);

) ?3 |# G* P& o- P! }( N8 l7 z
8 g/ Q! @! p* D) K4 r4 i* O9 n' V
callback_fptr = timer_header->callback;

% J4 J# B: i1 ^' M8 T* H; t8 J7 s% l) H% d
timer_header->callback = NULL;
4 d3 r! m7 v& y# g

# I8 g- M0 e, p$ Ntimer_header = timer_header->next;
0 Y( R1 d- K0 a( S1 T/ g4 z3 q
; N" \% Y: v! h# L* Y5 x
(*callback_fptr)();

4 h/ T# m1 U; q$ N9 e& Y$ K3 G  F9 z. p' _! Z3 n, Z$ |
}
: |% u/ o6 `2 }5 Y

9 P8 z5 q0 C  v1 p& L- Y

" ~" S, o3 G8 P: T2 o6 Y) U& q}* o0 a2 y# S3 c1 q3 T! {
///////////////////////////////////////////////////! x( f; x6 y7 V) ^
9 R  X7 S% l2 W1 W
% V/ u9 p, u& C/ T8 i: B3 v
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
4 N2 y+ D4 |5 V8 m
) v% G. `  o& L. v: H9 X5 v! u, N野人献曝,博君一笑$ ?7 A8 C9 c' w& M

: V% n9 N8 r$ B5 N, bPeter
+ t* y  F/ {' v, |* Y: @  
( Z& o% u4 t; y
9 l8 i3 i+ y( f. q6 J. f[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-9-21 22:27 , Processed in 0.554840 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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