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

Smart Timing Mechanism

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

1 u. n+ i- p1 J9 r* `& c$ s
0 M# j6 p) a6 p5 r& U% t" d1 e# W
1. Why need this mechanism5 w. t6 t9 J  s4 N/ w: D* T! y
4 ?5 P* C* E! x4 r' h- |
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
5 n$ P& b/ m: u* e$ R9 a1 n
. P, R+ c4 D/ [0 w
2. How to improve it?
( J3 @- P, n' b' I, K
9 F2 D3 K, D" Q1 ^  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code  h2 P7 H3 r$ r
: b( a# Q7 H( t+ _& j
//header file4 X* p& G& @8 ^& [
/////////////////////////////////////////////////! T. F$ N- `8 ~  i5 ?
#ifndef
' q7 M- X; o9 t& h3 JOEM_TIMER_SERVICE__H

3 D* K: D* n" b& z* H4 {  w#define
3 F" Z' r: ^5 v3 b4 F+ }' L+ P, MOEM_TIMER_SERVIEC__H

. J. @" m! S- C( K" @  _2 n% h! m1 G2 Z1 u. B( s% ?/ o3 D

  N* A; V" V! ?void add_timer(unsigned short
( F2 J1 z* I$ g- ejiffies,void (*callback)());

  \  m) D0 N4 m2 K" L' H. }3 M( p, t/ w7 {5 E  g& R+ \
void do_timer(void);. z+ G: q7 }: G  Q5 J! P- W

5 [4 \9 a3 E9 G: o3 ?) o0 v#endif' e6 R& \/ ^$ D8 k
/////////////////////////////////////////////////
- N8 @5 q( @% h' G/////////////////////////////////////////////////7 j8 h* o' D- e( _- }6 C# n
//impl file5 v7 R0 C8 N6 K9 J9 f0 W
#include <stdio.h>3 _# V5 w+ v, y! \
#include "OEMTimerService.H"
6 C/ @% U: d3 i" s" ]* q9 G5 O
7 ^2 |& a. k) r2 k
' k7 z( A+ x) f#define
' R/ x; k1 d6 u7 C  ?! D+ CTIMER_REQUESTS
# d4 i% p2 J5 w) `; s0x30

: ^' ]% Y; ], g5 _3 j% |+ n& d1 h. X4 `3 d# P8 \: v" X
struct timer_list
2 H0 X+ u# ]# b- i{
5 I) c! |0 u9 P, I. v$ W
1 m# w* F0 {' R+ Tstruct timer_list *next;
4 y% i0 B) d8 Y" @
! L8 U# S" e/ A+ R) O- L
unsigned short jiffies;
* P+ ~( R3 n5 r6 R$ l

8 g% X7 N5 [. `$ h, M# e1 |% Hvoid (*callback)(void);

; n, L; n; _; y6 a0 g% c/ I};
: S  r' Q: m, u$ z9 X/ P0 G  i1 k' j5 @

; x  J# C2 ]  q0 D2 I/ Qstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};  X# O7 Q( a# r" C; R5 e

0 p, \6 e# I2 F4 u9 s9 Lstruct timer_list *timer_header = NULL;
; K- ^% j3 r- D2 O9 ]$ E: f* O7 U' O0 I

2 w5 _5 N  b% }' \void add_timer(unsigned short
. u9 @+ p3 ~  G4 o+ E( Mjiffies,void (*callback)())

- n* q2 ~0 V! U2 k{
& L1 Q4 S5 p: j( y
; h% l; H) t' [% P% L7 Q5 W0 hstruct timer_list *ptmp;

1 D; o$ Y9 [. X5 F3 P" ~' u- s+ F+ ]" p/ G0 ^* m4 v3 Z
( l6 P% R$ B+ s% G
if(!callback)

& W$ B# ^' F& T* r* |! v; ?5 _9 K  k1 X4 k. b5 f1 G4 X7 h! @
return ;

6 [) K- N: I) w( z2 l: V) P) ]' F9 v- `+ M

8 e. c8 U9 ?) }% p
8 S9 _4 u/ ^) Z# y* r- ZEA = 0;

; g) d( C* C. v# r4 e. Z% k; i  t0 P# ~8 P4 [# d
1 M4 B+ ~+ L) [) Y4 x0 E
if(jiffies <= 0)

3 f' r  d: P, p! i- k
; _6 R2 q2 s6 L% \0 y(*callback)();

! |2 K! w- F" A" M" S/ V% x. S! V7 g7 Q" l1 I

7 W9 L- c2 t2 m9 ?- G" _8 C
8 b6 m. m9 ^& J  o- _for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
4 E6 |( A! u- e2 {5 U( h$ E

6 [9 ^& _2 c6 W3 @& Nif(ptmp->callback == NULL)

: `: l  [1 A# H) p4 a' ]( z5 ]; ~% p2 f
break;
* q7 j- T7 ?+ f& @* A

7 }# [7 Q& f# ~- [+ l% H2 C! {: s) m0 d* b8 J5 D

8 `! L* h/ T! ~( M( L: Tif(ptmp >= timer_list + TIMER_REQUESTS)

# t. _5 C; m5 x1 f5 q' J3 M2 v! m
{

% j, i+ e+ w4 ^0 b6 o2 U$ ~3 v0 i# R! ?2 }2 y, z! j, d* z! L
goto EXIT;
) c+ [/ r0 ?3 o* ~3 y
/ t. ^/ S! O5 z0 P3 S
}
& Q* e# O5 ?5 @+ ]9 [( H; d$ S
% i  I& ]9 I; `+ r1 [7 j  N
. D/ B& S- W8 f2 P" z& g
ptmp->jiffies = jiffies;
; Q& R2 x1 w# C$ d5 _$ R

1 P; f* l, u0 K9 R) tptmp->callback = callback;

7 y7 a) v3 j, r3 g+ J) M, q
9 ^4 J, E& j( a# _. r* b; N5 Q

5 B/ _- c: s! h
5 ~) S5 X7 i9 M6 T+ y! J& Wptmp->next = timer_header;

- v; ~: h# m0 [& l
8 R4 I6 e8 u# g& ^2 q" Ttimer_header = ptmp;

7 E5 r- D* O# I6 l% L) [+ C! j
& z& U9 G0 z. z: P, F0 }, E# E* c$ B9 ?, a6 _- e9 c8 f
//add bellow code to fix linux on timer’s bugs ++
6 J' @* x/ g4 E- ~1 M" M

4 t- i" S9 ?. q  dif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

' s4 ?7 o3 ~  g1 a( f/ f; T* u* B% {6 A9 ]
{

. B% |1 C/ D' I
# W9 y  g4 m+ uptmp->next->jiffies -= ptmp->jiffies;
: H3 w) i9 j7 m' f$ E1 `2 E

+ ~  G& J4 r" ]}//end ++

( `) c1 R, q4 O5 H8 O2 Z- ]1 l/ J1 P6 J0 B
else

- q" E( h( f0 |) ?  b7 {0 G! G0 D% J- D& K- h
{
! a0 S! T7 l, W; k. |. [

) ^: o) X, {- _! s! a& Vwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
% v/ O' z! `) F& L+ I- D2 @

: H+ P5 h* h, x) H# |" c  g" O& B
; o% x. L; T  d{

% ~  q  N7 `( |: t1 K8 u- ^( _* M" p4 ^" S+ O# [
ptmp->jiffies -= ptmp->next->jiffies;
3 P, b5 y4 P0 R( i; S, \

$ j) P: i+ d: s; N& icallback = ptmp->callback;

, x/ Z2 s7 w$ F" g8 c: ^: a* i/ Y
% ~1 S* ]# a$ o: Tptmp->callback = ptmp->next->callback;

1 x3 Q1 {+ P7 j2 }  v  Q# ]: _' V8 p* M# b
ptmp->next->callback = callback;
. q, [1 }/ T! W+ F
- k+ c# X$ \( ^/ ^- D
jiffies = ptmp->jiffies;
0 T1 N  |) \7 z# B: N
8 o* l( O* C" [, t: V6 }
ptmp->jiffies = ptmp->next->jiffies;
3 l8 M6 M; p- [1 _
/ z* V; V; C7 P# P8 s
ptmp->next->jiffies = jiffies;
! S+ @; d2 z. m) s8 p& e
! D8 h/ |4 c* A) B
ptmp = ptmp->next;
" C4 s& m+ }  T: n: b$ y9 _9 X
9 b! h) {& R  \
}
+ g: \: t9 Y- K
' F. G* e. |8 N0 r
}
* j4 P% A: O; u; f; j, L

9 @+ b9 q2 K' Q  I8 q. xEXIT:
" \, ^- M, Y) j
8 p; }. L* g% SEA = 1;
/ z" s4 [4 k4 l7 Q* W: i

, |1 a/ a2 G5 F5 U; Dreturn;

+ L$ ~: n2 P- c6 ]}
$ v9 L& s7 O, u" f2 _% b% L8 y, A! U9 X1 X! |4 _; w, N/ z" h6 _0 q
void do_timer(void); W5 i3 I$ R1 N9 Y& U- m9 S% }+ M& l
{
& y8 ~: N: E$ Q  V: T
3 g6 c7 d- D* s3 B8 a, g7 Q2 q
& K( r4 m2 I' l$ Z1 P
while((timer_header != NULL)

# z) R) X0 p* Z8 w+ {! T# R, r9 A# \3 x+ {) k: ~; R0 L* M
6 R; u2 c4 b4 o- N5 r' Q! n# M
&&(timer_header->callback != NULL)
$ Q7 g7 U3 b; i, t4 s' {8 j; z

( n3 G8 k; p' {$ {; s
- x) N8 J1 H  T$ [8 \&&(--timer_header->jiffies <= 0))

7 b# I) b- A/ O4 m$ Q3 O- T7 e* O
7 j# b* Q: `" {8 t( ^* `{
% f0 M$ |6 i* ^  U5 s6 s& G

7 g$ T+ Q# d! j  uvoid (*callback_fptr)(void);
8 q  {* c/ u' F9 n

4 _9 I+ p; ]! s3 u9 k4 K! X1 V) w( n" m' y& Q  T
callback_fptr = timer_header->callback;
3 ^1 N) V- X: M0 P
* f1 `  W; C4 I, k: i; r
timer_header->callback = NULL;
1 E# K* Q% R3 V" n" I  }

' q* R: g7 n) t! T7 e, w9 r- itimer_header = timer_header->next;
1 @8 O( Q4 a( A! S3 X

; O7 C; U5 C5 D( D(*callback_fptr)();
8 x; G  s; k' g$ P/ U8 z
% h  @8 b# c* U# z( t' N  `) P
}

  x$ H9 h& b. w+ q4 ?8 V1 [# f& k4 p" C& P( P% S8 ]' O5 S
4 l6 [+ P& j) G# p
}
% a+ X- `: Z3 p  j///////////////////////////////////////////////////' @9 L; ?( @6 c$ X! v- Y0 _  F0 m
4 S9 R/ |- m' |' v& `7 `
; F8 F, T+ y+ D3 |9 S
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
  W0 E6 @& p! v# }, |% K+ W3 V4 H7 i/ o
野人献曝,博君一笑
: @2 T- k& Q, b. Z4 s, m+ S# Y" S8 o! B% z% D1 p
Peter+ o7 g5 k. r( I, D; g4 |
  
0 ~% e, _& P# C' y4 e; {' l9 M# O! o& n: O8 }8 P
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-5-23 10:32 , Processed in 0.060137 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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