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

Smart Timing Mechanism

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

1 z7 p" L$ A0 P* |5 z

, f* M& ^9 w4 U0 g1 ]5 W1. Why need this mechanism
9 d5 l! ^8 y. C2 V$ B+ l- Y" z. s+ v, o5 f& Z) o% i
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
) g$ o3 f) ]. B4 f7 F" B

9 ^, U+ ^4 a4 l* e4 n2. How to improve it?& r7 v- X  N, }: y! Q' r; p, C

# n* J0 G6 ~& o+ S% a' H+ A3 B  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
. h8 z; w& P5 K1 ?( a5 p/ Y& V: Z$ h5 o3 F! [
//header file: @4 F5 t, a3 ?) D$ u/ z1 c, A1 i3 D
/////////////////////////////////////////////////0 u. a( D$ m1 @7 p6 g; ?
#ifndef2 ^: S9 l* \3 j- j) y* [6 F
OEM_TIMER_SERVICE__H
0 V: t: X# q# L2 M
#define* `! l0 ^( @8 @
OEM_TIMER_SERVIEC__H

4 W$ Y; e' j' Z0 \: N4 P3 W
. K% `2 S2 r/ i" d( j1 l" w6 g- K4 M( Y5 L  I0 Z
void add_timer(unsigned short
$ p/ q& @' r( ^5 Sjiffies,void (*callback)());

& B8 A# a$ L' w$ z. T6 ]4 B9 C$ [3 x! z9 o6 X2 W. m; q" r
void do_timer(void);
; s! _) x0 n' J; \8 r& X
- O) ]% F8 J9 m) B6 `#endif
& |$ p- x( A0 b# q4 I/////////////////////////////////////////////////& \& T( y$ Q! }/ u+ r3 ]! q
/////////////////////////////////////////////////$ y# ^( w0 J# Z, T; Z
//impl file0 i! I1 M( D* }% h
#include <stdio.h>0 t' T# s* K( y5 V& j
#include "OEMTimerService.H"  Q, U1 L+ V2 B0 M+ O

- T+ L: n( K+ T  _* ^* \9 |  ?& j- g/ |' h
#define
6 K* q( B4 C8 y6 W" s" Y2 b; nTIMER_REQUESTS
: d' q" y  j: b: {7 G: w* ?0x30
, j1 k6 x& R4 |/ t

& J  k0 I5 i4 b' vstruct timer_list - S9 r" C1 Z; V  Q! a6 F( q0 A
{
. X8 F; d8 q! d+ c% \) {7 _
0 [$ i1 e$ U% Z/ h2 vstruct timer_list *next;

0 Z" \+ H) W3 h. Z! }
7 |. S, ?6 I3 Q+ k1 U  Cunsigned short jiffies;

# {' c( M' Y& l3 r, [- u3 C1 h
9 ]0 B" V" h) p; R: c0 ?! yvoid (*callback)(void);
, o" w. ?- O( ?) M# r
};
, e; ^  f% ]4 ^6 I6 u; b6 ~9 Y: A* _- I, `3 l4 f8 E' A! E/ D

, Z' s, K* S4 S4 tstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
3 _5 X4 i3 Y, O# X- b# w0 f2 W+ r. V; A6 V6 d
struct timer_list *timer_header = NULL;
$ {' U7 }$ W' S, @/ i: b
% Y! k; w3 {( \0 x% q6 o* ?  K. Z+ [3 h
void add_timer(unsigned short
' W, i) e9 A! Y! u9 rjiffies,void (*callback)())
8 t  l8 W$ H# v2 m" M7 r* \
{- `' E* |& ]# I2 @* s+ J& g" W7 v

& e( @* Z( Q& m& z4 V# Dstruct timer_list *ptmp;

' s8 d. g1 Z. E/ v9 R' f1 c
3 k4 W( D  n4 p* D! b( [  }( e7 Q; w. P0 l9 V" L5 K1 B. K
if(!callback)
. H( L! K; @$ z6 |3 w

$ e' V* V$ p4 |2 @: k; H. T) M9 hreturn ;
, v' a2 X& v- J3 E" N

# D: `/ Z: Y0 B3 O" u' E7 r/ J" g5 I
6 N) G7 v6 c. k+ I* a) X
3 n' \0 {9 y& }7 u3 f
EA = 0;

, ?% P5 a, r! g( t
  \- {# w) r5 P# [  }* A/ p2 v' ]( M) O' }6 m
if(jiffies <= 0)

% f# z/ p- Z$ e3 D5 R* n4 {; F* c' D8 [9 o: T
(*callback)();
& ?* S; }( s3 u2 v6 [0 U& A  M
9 B% |& w+ `1 P# G; L

/ F" J% }4 j: D  u* h& T- Y  k" |5 _9 \/ d
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
7 e8 T  F8 _7 W/ d
& F8 ?3 a7 o# H. c# H
if(ptmp->callback == NULL)

6 C1 x7 B& {; \9 Q, P
1 L! ]6 R8 t9 ?- C# ]) z; rbreak;
/ f% a8 m: |" @
/ k1 H8 ?; w4 ^/ t& q6 e# ?# |4 N

# ^1 o7 g2 b3 `) O1 Y+ V' x$ Y- Y/ m# e+ A2 `
if(ptmp >= timer_list + TIMER_REQUESTS)

& A4 m8 f& C! {; G8 [) b- t" w( \4 c, W
{

& S/ f% O. w3 S; y2 m4 J7 P: W. A# e6 d4 S/ g
goto EXIT;

- W! X1 C: H4 L0 g- }2 _: }3 i% S6 d9 m7 @% F
}
7 T8 S- P1 J$ @0 g
/ \* }7 Y" g- K& X4 u

4 W$ \, D: Z! ]$ optmp->jiffies = jiffies;
7 y4 D, a5 f. A5 L& A  T

. Z7 j/ v3 a8 z9 R5 bptmp->callback = callback;
! v' h1 _6 ~% Q- @# c" r

2 a: S$ d9 b" X
$ {9 ]0 E7 Y* x; f. c6 v5 H
! w1 h( R6 @! m9 g9 H0 z
ptmp->next = timer_header;
; [8 N9 k6 {" x: I3 J# N6 z" [6 U
/ C- V2 Q; I. ~9 R0 B
timer_header = ptmp;

! `9 Z; W" I7 s8 K- p$ A- V8 n
/ i6 d) W& V9 z" S! _9 f1 Q1 \4 T6 q+ _4 c" ~, F
//add bellow code to fix linux on timer’s bugs ++

* P1 O6 g; i4 {/ i5 E  b2 w' E/ a2 J4 w, n. s1 M
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

; p3 y: S1 M7 _: }0 m% `- z1 X- y) Q- i: A' X2 m! H2 d& c4 A
{

+ V$ a( w$ ~5 l0 ?% b+ ]
, N) D# `' s/ O; g9 U* }ptmp->next->jiffies -= ptmp->jiffies;

& \# M$ Y4 j5 v  ^9 h; ^1 }2 u; M) ~2 J- e/ S* q
}//end ++

3 ]2 ^& `1 A) T3 S- I' a6 H1 ^# u* a* g
else

! {- ]2 _4 Y1 h/ ?3 P5 V; J+ r, E( k* W& x0 T- O
{

; I7 m5 [8 s' m5 k
6 w* R: m6 z1 T& ~9 P+ U$ |while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
/ C. D  f$ Z+ z9 p. e; F3 _

) W& i2 O7 X' [& `* f8 X5 S
0 \& H- Y& w( K' d% f( ^{
: k$ _( K) K4 F3 L( f  Y+ y5 S- T
* y! W, o  G4 I8 e. H7 h
ptmp->jiffies -= ptmp->next->jiffies;

" L; D; `0 Q- K2 ?, C7 d/ o6 ^- d% W  \5 ?$ p: z1 E, f
callback = ptmp->callback;
) P, K& u4 q* A# k9 l2 f9 M! e
4 N6 A+ [/ P) Q7 x
ptmp->callback = ptmp->next->callback;

% c% G9 z; e( ?. @4 ?( Z0 w+ |
' L' C& ]" w' F! F7 o5 kptmp->next->callback = callback;
0 _# m, ~6 R' R" [
# F/ S( {1 Z; R& J2 O. I# @7 M
jiffies = ptmp->jiffies;
8 q/ s  H2 i' p8 q6 m. t* h  L

6 g) T* g3 q6 K, E' Jptmp->jiffies = ptmp->next->jiffies;

- p% ~4 I8 b6 [9 j/ p7 p# }
5 ?$ i$ B+ j5 i2 M6 ~$ [5 Q  mptmp->next->jiffies = jiffies;

' I' N- F: U+ r0 i( m1 @
) k" n& ?, t6 n5 aptmp = ptmp->next;
: a0 w) F& T* G* e: B
8 ^" Q1 I, w0 ^% L/ a" T7 U5 v+ e
}
; T' ^& @  ^- q- c- i! I
- L9 s1 s5 K6 K3 Y5 R9 ^4 O
}
- t2 W- X* ~: k2 U: L* z
) @8 R  e- O, Z% A
EXIT:; Z4 h, A  y" N6 T* N# z/ @: S! L

; Q9 t1 A8 ?3 _0 @" ]& `! gEA = 1;

8 }2 k0 ]. L4 c9 J; n1 `: f, b0 E5 ^3 U& F% Q3 N' H
return;
6 f( `9 e- E- E- m0 S! ?
}0 b+ C7 _( J3 i0 x" n. S
& D5 T4 h% J% s1 P# b0 e
void do_timer(void)
( x: L) O! ?" O2 g  c  W{. [5 B& Q5 w  P$ E0 R9 u/ o, M
9 ?/ {7 I8 I  n; ~! l7 B% S
2 z- q8 ]  C% J  f7 ~3 U( o0 |
while((timer_header != NULL)
( L% F5 |( S4 x  ]6 I0 w
- q, t9 P7 O/ K* ]  ~

0 c- l5 n3 Z! g& l: U- l( a&&(timer_header->callback != NULL)

' b: `& i5 O8 f( C' S' Z; p
' a8 u; @4 C; \7 g  l2 M
& |. J8 `- a1 W4 Y! g&&(--timer_header->jiffies <= 0))

5 ~: M* q6 s" G# L  K# V; f0 P/ V& `
{

; M" b, e+ K9 K" x* E! ]9 p( C2 \
void (*callback_fptr)(void);

1 ^" ~; J, c5 @3 y' Q( r
& t4 m- v9 ?- C2 ]
/ ?# O9 {0 t8 e: I& Bcallback_fptr = timer_header->callback;

2 E8 H9 j* u" I; k" b$ _( k# k9 [+ E3 K4 Q1 D
timer_header->callback = NULL;

, {: E3 {$ v/ I6 H! ]7 T* B) P: g0 P: u# t  e8 P
timer_header = timer_header->next;
+ |* K! S# |9 V

6 p& {- d5 r% U, [(*callback_fptr)();

: J6 ^- P$ w; @7 h' b' b9 J8 A
& e  V8 R9 Y# \}
' o$ k$ ?. d+ c' |% g- f
4 Y  V/ _/ T# }2 }& Y+ s/ H

5 u5 Y4 @: |- \9 v7 a% i. k}1 b2 X  z/ Q: H' y7 K
///////////////////////////////////////////////////
# ~7 P& t8 p' T& d0 `4 N5 U/ }" @" v0 H  Y8 i5 ^$ Q
2 A2 z9 X) U& A5 D9 T
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!4 X/ J1 c* _0 v( t* O
0 J8 B  b& E! `+ _5 J' Z
野人献曝,博君一笑
' T" q% a6 N5 _, s7 S* H) T* q! k7 @* J0 Z$ l0 a! p
Peter  b) T( K' V7 @! D9 J. I* z/ F8 }
  
5 F9 V# R3 M& l( z  e7 E1 x) c# |% V2 h
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-8-11 16:58 , Processed in 0.127565 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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