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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
9 u) {+ R3 E' w8 F2 [5 D
8 u/ v, a* d# G( }3 p1 g/ ^
1. Why need this mechanism( M$ k7 O- l) ~) H( @: J8 g
+ `# ?) A) H- N5 s# q1 i' i  Z
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
, V( D5 ]/ Z. `8 U2 P
' l& T8 _$ ^& R: g  ?# }
2. How to improve it?
, E- B4 U+ g9 e3 W9 M
) W  t/ x- a, c) Q$ ^5 }  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code% x- @5 i1 x4 `4 j- `* _* }

  P& u& o7 [- p+ x; q. T( O+ l//header file& i9 g5 p+ i+ L; ?) R$ D
/////////////////////////////////////////////////
( [3 Z$ ?! O. K. m+ o#ifndef4 h/ L- [3 a( X0 {  c: |' W( Y
OEM_TIMER_SERVICE__H

# C: Y+ Z2 q7 p$ r* T7 I#define
* d+ r/ v7 L3 i: JOEM_TIMER_SERVIEC__H
- n, s% N2 V- |
$ v5 L9 F2 ~. P

2 w$ k5 T( ~) Z( ^% rvoid add_timer(unsigned short2 H$ g9 Z3 ^8 K7 m% D. y
jiffies,void (*callback)());
0 }5 P3 j- Z" N# K4 Y' D& ]+ @

  _0 X, j. @$ l9 _  E1 Hvoid do_timer(void);
! ?! {: `: x. e0 P, ]" n7 F% N' q& Q1 x' e0 s8 E7 q5 [6 a  W
#endif! w1 m( Z6 `( s0 l( H
/////////////////////////////////////////////////  l8 _1 f& |9 C. W6 k
/////////////////////////////////////////////////! U7 F) D  B7 e/ [" @
//impl file3 T3 j' S# Q* u0 e0 p
#include <stdio.h>/ ~  R/ g+ q8 s1 m9 u  ~2 P, O
#include "OEMTimerService.H"0 \) L: }* s, Q4 e3 b
) E9 X6 [% {7 S6 O" I+ l7 y% n0 `
$ s* y  n) t, E* O: n& a
#define
" H( G5 x/ }5 o1 v$ W( ?2 i* ^TIMER_REQUESTS
0 C5 F4 o( q6 p/ k; G1 d) x0x30
9 i( J) Q# n# _* o, d( M
/ }& z4 N- G. W! P
struct timer_list ; a" o+ D5 J1 n4 h8 h  L$ Q8 B
{
3 b- o* B* }2 V+ ]/ O' F4 z7 l, R2 E) Z8 X
struct timer_list *next;
* p! i9 z( o. ?, `

8 S0 m5 i" P/ w3 L. k9 N, sunsigned short jiffies;
. S: f  Z& y$ Q( n# }: p

9 W0 c+ P+ g, V* fvoid (*callback)(void);

, K* \) g* P" T$ A* y};
; y- [3 F$ g, U0 D  \" y  Y; w8 g! O+ I) x( r

8 C- S( P8 a! @5 O0 S* istruct timer_list timer_list[TIMER_REQUESTS] = {NULL};) `; f0 _  R3 h" |, v0 c

2 f& b. k6 r1 G* p. a; M  [; ?% ~4 Pstruct timer_list *timer_header = NULL;9 B: V% ?) o, D8 i. I

9 r* O8 J! M) L5 X  H. D0 ]5 ^. m' }3 L* p! C
void add_timer(unsigned short
/ R# s3 m' N( P; q6 q7 \0 Ajiffies,void (*callback)())

# K% d7 x% J7 X2 W4 r( [{; y" p4 r7 |  H8 p" _, H

) a4 q3 n' T' O3 y$ ~; lstruct timer_list *ptmp;

$ b2 F3 B3 N# j: q. }$ I7 l* A% }
$ i3 w  U# |- `( }8 x  q1 D; d
5 V9 A: K$ E5 @if(!callback)

3 f, n, t  Q1 M- G; X
' p; l6 B1 B, s8 U' \6 sreturn ;

: E: N2 b. T! B# q% o; R- x1 k
9 n" {5 w3 B$ t
7 l1 |' E; M# t

% t5 a' R; @" e! n! e; S1 }EA = 0;
1 x/ g% c  M' v$ v. \
! L# W" E0 T9 F2 j  m7 P5 W) S
1 e4 `8 \+ ~3 N5 J2 |' o9 p
if(jiffies <= 0)

& @- E; A" |2 O- n' R" {/ x+ ?2 h$ y6 w% Q& f
(*callback)();
2 I; ~2 d6 t) |2 c# e5 m" C

9 B! A5 v! a2 [9 q) p) u8 s
) v. B/ F! R9 w& B8 b# j
3 B& I( X" m1 \+ r
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

6 d1 ]  {! @& ]' ?4 A0 I/ W1 f) }9 h6 H7 w
if(ptmp->callback == NULL)
$ G! [: q+ q! J! S" y5 m2 J

9 q7 v% C! ]( g7 j- R4 j( Jbreak;

- H. V3 J- x8 Q! j, R* c6 S# d. o) [! q6 J9 @! b' m% o/ ]3 m& q3 z

) l8 m$ u! e* I1 h
# {, e, b8 P5 u7 _7 H1 X/ gif(ptmp >= timer_list + TIMER_REQUESTS)
" `1 W9 v# l* C* f

+ [  I0 b6 s$ {- B2 A2 l, \{
6 O3 L; r$ n+ [" r

: B6 H& T/ T, J& c- C4 x# T. Rgoto EXIT;
: P- O( q  N* U7 T" i
$ L! p1 B9 Y( n& ~% E. N
}

5 B- X  ?! ?  m1 d  u, k
- Z4 E7 k4 [6 P% b+ ^+ ?! Q, W
5 B2 _$ t; ]/ T% G; D  b4 Eptmp->jiffies = jiffies;
1 O, ~, v! f3 m6 v

7 N( w. {3 g9 M; {/ M5 uptmp->callback = callback;
* ~; q4 s( E/ g1 }

4 o! e9 r% c  c- u

" x" i: Q- t6 h: N8 z  X6 S  @6 U2 c4 t5 t& o  b6 o1 {1 ^  b
ptmp->next = timer_header;
( Z- p6 L3 ~- I7 K2 M( c4 ]
: {3 l7 A, Z* w
timer_header = ptmp;

  h5 l/ b+ |6 T5 e+ J8 K+ |6 ^5 j6 D/ W/ u$ v% F( x

& k6 ]# h/ z0 H0 R4 t8 H- ^//add bellow code to fix linux on timer’s bugs ++
1 ~1 S" d2 Y2 z: B* Z
! e2 ?# y# O/ I) u
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
, @! g  G6 E& f
7 b* Z5 W9 ?" {) I$ W$ U: s# m$ Q4 w
{
0 V& Z- t+ G7 v- K' S
) [( F; B! X8 ?; ~; ]: [8 ~, n
ptmp->next->jiffies -= ptmp->jiffies;

. F, y6 |$ |0 O2 m( R; f  h! |6 u* W7 V9 l& d- ]* v
}//end ++
. [, h: Z, c' s* v. e5 {1 p1 W

/ i  d) Y  E3 K8 ~2 U% O( T5 Qelse
0 E# e& z* c' C6 p: ]& V

7 R: Z% m! ]6 X! k4 l{
7 q( u- X6 h& N/ ~: s$ c' c

& b$ d# p0 L& X: p: Wwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))6 s& p+ ]8 x3 a2 t+ W. X
- E* ]; n# p4 V1 K" T. A

: q6 H7 C' F' j3 e2 I0 \{
7 N4 W! O* u# A/ I

+ i- _! O9 n% g9 v. ]ptmp->jiffies -= ptmp->next->jiffies;
. ], s; A3 U) F0 U

6 }2 _$ v7 D. Wcallback = ptmp->callback;

0 V1 A8 Z3 ~9 b0 N/ ?: A; B9 V4 G, D5 I  b
ptmp->callback = ptmp->next->callback;

, e: g* b: O5 ?% Y- H  L. R1 J% T; J0 k; S& a+ [0 R
ptmp->next->callback = callback;
  a- b, @1 ]+ d% Z+ t3 T: e6 @

7 T: o( |8 f8 W: O4 Ijiffies = ptmp->jiffies;

6 C2 b  E* l3 x4 f: _2 E1 E0 a
5 r) {! j" ]& z( y2 f0 j8 mptmp->jiffies = ptmp->next->jiffies;
: \- Q% z; R: f6 l5 l/ w6 Z
, T5 |: ?! \6 A3 V1 x; T1 c
ptmp->next->jiffies = jiffies;

: P8 L0 q, Y: o% \  z9 O" B$ U
" ~( n4 n( a1 o9 o# t% gptmp = ptmp->next;
% K( ?4 x; a* i/ e+ q+ F" B

) {, R3 Q( c1 L* W2 M# g}
) S) }: @5 N8 k/ h" c

0 B1 K. ]  s5 v4 |2 B5 ~}
8 K# C3 i5 q3 v

2 @1 }! d6 \( h3 oEXIT:
) }9 y2 y) R/ ?3 _3 l. |
1 q9 T- m; a. U+ a# DEA = 1;
5 ?1 B7 k$ E6 I, T8 r
. x* X! a( |9 h0 {: K: K& N
return;
$ y- l9 X$ i+ R. P
}
+ _) F+ K8 g5 ]7 l7 g! c" a6 v  A' p, S- J8 q7 C# d
void do_timer(void)5 x: J% {* m* I8 @& v2 V" I/ L, U
{
8 j2 x8 r! Q7 C& Q9 U  f
/ Q- S- S, j- r0 ]3 l7 f- |2 W
$ g+ n1 e- \6 w  e- [! `! ^" I$ e
while((timer_header != NULL)

; \5 f% [3 c/ w- D9 f( t# @- z& A% K$ T. w* l
7 t$ R/ t2 ~1 c  R
&&(timer_header->callback != NULL)

; v) j5 Q7 k- G6 n+ b6 v% U
, f0 L, v6 `# C% Q0 M5 T
( c6 M  ^: D# r1 e&&(--timer_header->jiffies <= 0))

. u6 @4 F9 \- ?2 \" X; }, [7 m5 Y# s; z
{

: C; b$ b0 z. {. X
! a, |$ Q. a1 Dvoid (*callback_fptr)(void);

1 N7 [. E: d' ~3 c, o9 X" J) x2 g2 |3 c! z* b& }% a- U
5 f# C, u6 j$ k0 o6 l. j& n- Q
callback_fptr = timer_header->callback;
$ }( A* l6 {/ x8 V2 X! w

/ E6 k, v' t) D7 N. O. [: \timer_header->callback = NULL;
  l# B6 K% U. o& g2 ~; i

# c9 e2 Y1 ]2 w" C  T+ v/ `8 C0 wtimer_header = timer_header->next;

1 G9 e% l; ^# Q0 F  B/ q
& O# ~  ^& T% p(*callback_fptr)();
! j* m* Y6 x0 O7 q1 e/ Z+ g- Z

1 u0 d6 Q5 ^  [" Y+ s}
  e4 B! `- g4 j1 G
1 J8 K% S7 V& N8 e1 r( r4 s
" R; d6 m$ |; P/ s
}
; U! d# Q2 d$ o" y! m8 g+ M///////////////////////////////////////////////////
' c$ ]( N) ~' L9 k& \# X7 q
* O. Z, ^- Z: f7 R4 b4 E6 z3 f

. k; _2 c0 F: S8 ~: u: N7 ~上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!; P/ i7 d8 d- R7 c( [2 ?/ l! \
2 [5 a0 d8 N6 u( `, V# s+ k
野人献曝,博君一笑
- [9 e5 z& t3 i5 z) I% D5 h/ e3 k+ K; R6 s
Peter. v0 T' ?$ M3 V5 f
  
# w0 O$ I8 {; _! N
( m* f- k+ J8 J6 l( t[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-12-1 01:28 , Processed in 0.097754 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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