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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
( j& T. Y+ f1 C$ Z

! {( @# M$ S( v. d& V' n* e1. Why need this mechanism2 F  a9 E" m' U8 a+ j

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

1 U$ @0 u' g8 g$ T+ z3 P, m2 q- d. {5 o$ f; e
2. How to improve it?
, F. F! b; y! V" j/ t
) r2 z& P; G& R( t2 \  V2 g2 W7 U% J  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code! ?9 @2 ^7 V9 {+ H4 Q: z. K! E

5 m! E. q2 I# T/ v/ y  o3 L//header file: H" J5 m+ b: u9 X% m0 D$ g7 o/ r& M
////////////////////////////////////////////////// [! {5 G& ~: g* }5 M# R
#ifndef  z' R1 G0 O6 i; \' f4 w/ i& B
OEM_TIMER_SERVICE__H

6 W0 m8 U) l, N5 K! H#define3 i! i% ^% h) @  F7 k4 T
OEM_TIMER_SERVIEC__H

0 {+ Z5 R7 u  P( ?+ m4 T( k! |8 m6 i; T; t

0 H9 _1 y3 V# Evoid add_timer(unsigned short8 _) y, E4 H- R  X6 a9 v# |% ^2 I/ ^
jiffies,void (*callback)());

6 e7 t( N, O- `) v  Y4 }% t. H; d; B) G+ E. A+ q! C
void do_timer(void);2 i; _- `: d% w3 Q; c

$ t- T8 W# Q. G; \. k/ Q4 E#endif3 D& R" c5 o2 c' I
/////////////////////////////////////////////////5 b! @, f3 _  G2 i
/////////////////////////////////////////////////# {4 h- i% }  l4 P9 v( a6 v1 ^
//impl file
' `: b) K  @: ~# D  n* g2 A& [#include <stdio.h>! Q* z% P9 z) K" Z8 Q( K# o4 k
#include "OEMTimerService.H"
+ D2 h' X7 R, [  x
: m+ Z8 o, y! S8 m7 G$ k8 o) h& [  x* a/ H( N. r) |
#define
+ `! G' `- U6 TTIMER_REQUESTS
" @* n" w/ M7 W* g* f/ D. h# d" B1 G0x30
/ s& ^1 `( j8 z8 W( E7 t
0 P- R# q: G2 u/ M  g- q4 s# h& ^
struct timer_list & b) j/ j  W) n1 h+ P; R6 q9 s9 V7 \
{3 D9 C- b3 J' d1 |. l

8 Q9 s# a( {! Q9 f* j0 O' k- ~# zstruct timer_list *next;
& F" C# [7 X. `9 u  R; f: t
$ E# t8 G4 m, o1 I& J
unsigned short jiffies;
5 D  N- B$ x2 i/ A
9 ]) u6 @% b# K( H
void (*callback)(void);

  E3 z6 p2 u' o1 _" Z};
3 e' Y; W# H) q
8 ?9 S  q+ R7 I% i! i3 e! J$ I
; g7 R) F( E+ V# ^0 O" F3 kstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
" I, F& p" R4 b# R1 A$ i& c& J9 v0 M; p3 |5 a
struct timer_list *timer_header = NULL;
; N3 ?9 a! Y, w, C! A5 G0 M) W/ z/ e% y! y
9 ?' L, p. {4 d1 s
void add_timer(unsigned short
1 C7 W8 j' s8 G$ rjiffies,void (*callback)())
' l5 X5 C& }# N
{3 y2 L- h. g5 {
+ l2 y! x: K$ F2 C
struct timer_list *ptmp;

) N: ^, J: b: G- a- w; h! {" R7 Y5 F5 \4 [1 q
+ e7 W4 J7 ~% _9 M
if(!callback)
' r3 R$ \: ?9 K) Q' U

9 \* B& o* W. y8 s' treturn ;
% V3 G6 o" I1 T- T3 l
  z3 @5 }3 }1 ~- ^
; t  }. T% ^  v: y
; u7 ?" c/ `, j; q
EA = 0;

. X; e% @! J+ K! d$ S
6 ^3 ]" M: T& `+ M" C1 L! \; u0 z) R5 O. y) S3 Z
if(jiffies <= 0)
3 S" K5 i# s+ T3 _1 N
6 `* ?. k; D# E
(*callback)();

9 _- B( h/ K3 Z# I* Q
: D/ T8 ^0 m. q. V

. \. \; k2 G  S, ]% a9 F
) N# l  {) B) \7 j( B5 z" O/ Kfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

5 p4 B; j4 e; E1 G5 q
  C, d% R/ {6 o; ^if(ptmp->callback == NULL)

6 B5 i, @1 e! r) D5 F. i: n9 L  c; L9 y+ U9 H! h- J+ U1 W* H& A
break;

. w) k3 N; F! K8 o# K  y) |; n  f

0 H* l0 L* A/ N, A- X  r% R$ q- r3 o
if(ptmp >= timer_list + TIMER_REQUESTS)
' c; a5 \' R' a4 A% X4 i7 v

) z' I8 }* ^7 H9 v{
7 B% B3 s7 {5 S! W7 h  U% }

$ y! r9 Q* ]" Fgoto EXIT;

+ \% M2 ^5 A, p  m7 }
1 v7 }; Z- n  {+ Y  |. z& N% `  W}
; W/ l5 k2 ~5 E7 g

( c8 v# H) U3 s7 L* m  \- \7 w9 ]; x/ }/ o: ~/ {
ptmp->jiffies = jiffies;

+ G4 J, ]! \' @! r( y3 y  B- [+ x
ptmp->callback = callback;
. {6 f) g4 J5 [$ _/ w: ]5 N' G* y
; d  A4 }( e/ X0 B( D# }

6 D" }5 y* R; m. W6 U6 F9 c+ Y) R4 m3 x" s# D
ptmp->next = timer_header;
/ t: ]' x: J( I7 U$ [

# a/ P7 C% V8 ?  Q# b7 m% {  [9 Atimer_header = ptmp;

# K. M. S! Q" Q  Y4 ?" _8 }, O) Y- f) J8 z% v1 X8 e' n
- a# [7 Y5 o0 I* g5 g
//add bellow code to fix linux on timer’s bugs ++
8 X5 Y% _6 C' b8 w

& d$ ^; b. P2 u5 Oif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
7 }0 ]* U; o4 F5 a; H& T
4 S, r6 K- f# Y# t: ^8 ^2 _) _, ]3 J
{

; X2 ~# `7 x8 D$ A5 C* e
# F5 p+ @5 s5 o2 u5 P) xptmp->next->jiffies -= ptmp->jiffies;
9 H1 k7 P6 g7 }5 S0 U
6 r' B$ B' G/ e5 p9 B
}//end ++

( ?/ M3 s+ V! x( W
: M1 c% J$ A: W7 `/ `+ eelse

% ]8 {( w9 @: B5 c. [/ g+ r+ V0 T4 G4 F4 Q' [6 s! U
{

. S# c# ^: m+ A2 x* E7 u8 {! q. z7 ^4 n& {3 \/ v( e; ^/ v
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))9 D' A; L( q1 Q% c$ d6 t
0 J" u5 Q3 B% q" t: o$ A, S, e9 m

3 c: r6 P1 k; \. M3 w' Y# p{
# E* J& n4 Q5 r" a

1 i: T5 h2 t5 a5 q9 ~ptmp->jiffies -= ptmp->next->jiffies;

8 K& G  G: e" ?4 V9 k8 `6 w1 _- S2 ^4 g# O( n6 e; W
callback = ptmp->callback;
8 ?; _* v4 O( v+ w+ b* Q; z% Z) {
( }+ u+ Q/ x! i( r+ x7 ^2 j* w
ptmp->callback = ptmp->next->callback;
/ F& q  l7 S. W) |
; T: q9 g, M, z2 ?9 Q8 j
ptmp->next->callback = callback;
+ ~9 `$ \7 O9 g7 W. f% V
( P( u' X; \4 l
jiffies = ptmp->jiffies;
1 B1 w+ A% z3 R
2 j3 b& w+ }& q
ptmp->jiffies = ptmp->next->jiffies;
0 u  x' U& i8 N8 X: W' C# k  i- `  I
0 `1 c" U7 a) L+ y2 t2 Z
ptmp->next->jiffies = jiffies;

* p) x- T5 t) s$ o8 P- X* u6 h$ K9 R* t
ptmp = ptmp->next;

' {9 U1 \8 c# K1 T; b
; M1 U7 B4 m9 _0 t# h}

9 c3 v/ p6 W1 w- a9 j6 A4 x( t9 l5 m( B
}

3 T" A0 X# E- Y7 v2 P8 P1 z
- E3 V0 a; C+ Y% UEXIT:
% m: P4 a3 O0 G# |2 M
" q' _% r) o4 A4 Q5 E* \3 U6 aEA = 1;
$ @" [& K; m; R% R3 o% w3 }

2 Z1 M7 Q7 @0 q2 y) v. k& \& Hreturn;
& Y0 e: x0 O+ Y! g+ G+ B+ W5 k
}
' y1 }7 f- ?( i7 {  [- V+ `' M5 Q3 d& _6 J7 c& k
void do_timer(void)
5 n4 J. [+ O7 p{1 w1 S; C' v" Q/ k
" l6 M6 T, J" `* R9 Q/ [

8 z. \; o& d1 }# jwhile((timer_header != NULL)

2 v9 y3 |) K! L' U' ~) k' u- q" C3 Q; e  r
, w/ I! r9 L& ~. o8 S8 [* ]
&&(timer_header->callback != NULL)

& n# L; b% q% z8 q) \  F' J9 W- X* A+ E1 t% ?& K

  P; c, }7 Z: f2 x7 }- {&&(--timer_header->jiffies <= 0))
& y- C* z4 d% p/ N2 p" B: U

4 O6 o* T& J: \7 l5 ^{

/ z% [. L* a1 T3 E  v8 e, X% J, ?- P: W" \
void (*callback_fptr)(void);

6 J" G$ b5 d/ q( ^9 Q! J  S( `, T  n7 ^  N

6 l+ c+ [$ Q5 {  [/ D3 }callback_fptr = timer_header->callback;

7 i  k/ `  U. X1 D" s
5 L6 O( @9 Z( Vtimer_header->callback = NULL;
- j  t1 Y  |# p9 N. M" U

) V+ _: S7 |+ f3 G: f$ c, mtimer_header = timer_header->next;
$ D- e6 Q; O1 D( x
4 C, A/ Y' ~* w9 L/ L5 M
(*callback_fptr)();

) D9 l/ J  \& n0 a( z3 x& w! m  Q# Y+ W; [
}

& i  L& b% y+ `' m  _5 S, O" a& s  M; A4 `+ F$ p' C& |
) B2 M+ a* T& K7 X3 b. X
}
4 Q4 i9 Y, j. V6 \( [2 k///////////////////////////////////////////////////
8 l/ B1 V+ V/ o0 e6 A: Y* N9 Q! Z6 m- Q0 i! m9 W- c% n
7 O# B# `, y# @" N, H- |& @, p
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
6 C  @7 h6 l! Y4 B4 |% b' M0 G" a/ Y* `& s7 {2 A* M# a" X2 G
野人献曝,博君一笑6 m4 }: r) s" K2 c4 ]
0 T6 ?4 Q8 q7 Q; ^, a
Peter
  U+ q% G3 q+ \5 p/ a  
3 A. [( p6 C5 e. V# A( b/ W4 H/ L/ J+ h; }' L, _
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-2-1 12:04 , Processed in 0.213575 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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