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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
& M/ R* n; Y8 i6 @, d# z, \  a

6 j# s! e+ a  u4 t5 X, t' F/ E1. Why need this mechanism# Z: P& }& D# x3 ^6 p
/ T  C( q0 G' f# K' }" J
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
( X4 C9 f+ {- y7 {

9 ^5 k0 A* g4 F5 ^+ @2. How to improve it?2 M+ i- q" {6 ], t1 d: X& X+ Q
/ r  [* j3 Q& ]
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
+ I) Z8 |5 N: @) `) p+ e* N; o8 Y0 C+ w: P4 A4 P, T( y
//header file& |7 R! P' A( F+ o5 J& Q/ w; X6 }  e0 M
/////////////////////////////////////////////////: w4 o0 b* K* u' {! q
#ifndef5 K- v( E) N" N) i" ~
OEM_TIMER_SERVICE__H

* \% H" C' E- W#define
/ j( i9 z  y( O* j+ G& }6 p! w3 cOEM_TIMER_SERVIEC__H
- S6 k1 W, M6 _+ e; H8 v

9 I# }" O" z1 X# |
1 x( c( K$ J4 O( m" w( kvoid add_timer(unsigned short8 s' ~* v  M, f4 G" c0 y# j0 I
jiffies,void (*callback)());
; U. q. P5 V8 X$ r; p( F6 N

  @, y) h9 i5 B: r+ J8 Y  jvoid do_timer(void);5 _- \  m) l! E9 J% m4 j

$ Q7 w) X$ v) Z7 a#endif
* a4 g2 g7 e$ V0 `1 _" I/////////////////////////////////////////////////
2 f" U; Z$ ^$ ~7 |6 P/////////////////////////////////////////////////2 P' D9 S, Q* s7 M% M  g% c. {
//impl file% R4 G2 @9 |8 x; e
#include <stdio.h>
0 d6 x* }7 k! b% F+ ]$ N#include "OEMTimerService.H"
; f' q, |7 s7 I: z: g4 j$ p0 ^" L. x) B; ?
% a  m$ [% S: O( ]4 N% U& I5 o& _" E% W6 ?  j
#define  Z6 `& N; q5 v8 z
TIMER_REQUESTS
* @) X% U  u. j/ {' x0x30

# [. s1 h* [, s) d9 n6 ?* z. W  P
, g1 G6 R9 b8 B$ P9 ^2 R: vstruct timer_list
9 \" [: R& y/ E8 G7 t1 ~8 M# d{, x' b5 Z  T% O- P) K7 u3 c8 m

/ |( c' U' u3 s  _struct timer_list *next;
$ @0 F3 V; `( N2 l; @$ j$ g

1 _! j, x5 I9 K, K* ounsigned short jiffies;

! w+ n3 v, w) V9 [  \& [/ a, z( P; S. W8 ^
void (*callback)(void);
& o% g* [8 T3 x0 `( F
};
0 E) f% h" A# j+ C' `+ K: {& s( g+ i$ B2 a0 S9 Q' S4 F) m

; r; l! H/ g3 Q- mstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
; A0 P! D* ^9 o* ~1 Z3 p+ H% }/ e) H5 v/ r; o$ [$ f. Q3 o; s$ y9 i' ~
struct timer_list *timer_header = NULL;6 l  t9 Q9 I* q' L
8 v: t& e6 E% G) m1 z- F
9 \) N) ^, W) S3 g* }4 e
void add_timer(unsigned short4 B1 p6 q% G* m& p& k2 M! k$ X
jiffies,void (*callback)())
% P1 h" ?9 H9 k4 R! L
{8 l) \7 b/ i8 k
" s. f0 ]& M: Z8 i: z; f) a; K% I
struct timer_list *ptmp;

" b+ t0 E+ J4 E1 J8 }1 t
! L5 V# ~/ r7 ]5 z: U# }4 E  T  p8 W+ f% q
if(!callback)
& z. ]# I4 N) d- \
  o" ^1 v: D( Y& F; R3 l+ m
return ;

' G6 h3 \4 l* J, X& A5 s7 ~$ \! W( t2 A; E: d( @
4 q% `& \. }/ H$ p

: [( r5 e- k# t" oEA = 0;
: l% O; e; L* F3 S! s
# p) [- I4 m0 k' P+ t9 j" X9 Z

  Q( t% E  T/ s. p0 R8 z9 {' Hif(jiffies <= 0)
9 m, I& [2 b$ k: j/ a
- I+ V$ V( w, Q: x2 k3 ^
(*callback)();
0 G3 L) O% H/ ], q
9 h( l; j# r2 q6 {1 A1 L: c. O

9 f5 d- k& D8 W2 C# N0 W( }8 i
7 O4 M! O3 _! b  D) Bfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

0 y" Y- J' y6 i3 G+ R( Q% P0 y% }7 f% k! W; }; W
if(ptmp->callback == NULL)

0 v1 W0 P' H4 l5 A2 `
2 n0 G  D: G& w) \break;

9 _" f# \4 |% W* T) ^3 e4 J' ~; P( [2 U: B

$ {& @" u/ x: l0 @# l; a
" }) r( o+ @7 ]: }3 k% W8 G0 @if(ptmp >= timer_list + TIMER_REQUESTS)
# a8 `  B4 S, k6 ^2 y* c; o4 T

: {; j" R3 Y2 t# W5 M{
. s; l" y2 Q+ d& `
. @! n3 p6 }5 ~% I, a' t. M
goto EXIT;
/ o& m. U1 Z/ c  w6 d
3 p( E  |. a+ _. I, k
}
$ }! r# O' H6 ?: T

' e6 Z6 t' n7 H" Z4 r, H+ `( x& ^( u0 }' P
ptmp->jiffies = jiffies;

1 d8 F0 c; r" N+ S  G5 e+ y0 f: R( b' |4 u+ U6 W. W
ptmp->callback = callback;

9 S3 d' M: E% g* F3 u7 H+ A3 E
7 k) M& G1 z) t( \

( E$ `$ Y: \/ J* T/ _0 n6 b; a3 F/ v2 C, m- E' x
ptmp->next = timer_header;

+ G/ C3 T" i& Z' S7 D" p( \7 {; m1 u" X& i
timer_header = ptmp;
$ ~$ S4 a4 H, E6 v

5 s; E8 Q* [8 e8 G" {' L5 I" _6 \& o3 j  |- X8 F# s
//add bellow code to fix linux on timer’s bugs ++

: B7 S" F9 ]$ c. u! ]# `) j" ]* n* _9 ?, \( m4 Z
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
8 F! ^8 a% J+ Q) L8 G4 l; M

2 l6 F, X, t3 q$ x6 i{
) _; _: F( d) H! r
+ X. s( j8 d4 _& E3 q) I! x+ d. [
ptmp->next->jiffies -= ptmp->jiffies;

: X" z* L; E/ u. u' m4 |$ x2 g$ w$ I' a" r" V
}//end ++
7 N6 f- A* ?2 T* v  R) Y: ~: I' T
( ^) ^& G3 _$ Z  V* ^, R
else

5 L" ~% f. c) @* y$ P' q' b9 i- s& H
{
1 L# F; o* [4 F0 d  G
& j1 z* N# _  f
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))* T/ p( V6 o5 I8 o
9 }2 m% T5 f6 Z9 v% v
# ^# J- A* O2 x& o9 N
{
7 B- w3 [& Y2 z' y7 `. [( S# @8 Q

3 K' d! o) V/ x  H  \3 K5 E% G$ ]ptmp->jiffies -= ptmp->next->jiffies;
2 `5 L* a3 f" d* ?  F; p

7 p8 D% L" @  S8 i; o/ F4 H5 `callback = ptmp->callback;

. F* K+ Y3 J" e
) s, H9 u( o4 L% ]ptmp->callback = ptmp->next->callback;

# e4 ^9 q, b6 f5 i) }8 ^; L9 r
) ?- ?+ [( k" ^7 ?" B- Hptmp->next->callback = callback;
& K0 Z$ G# c1 S  ?" K

  @+ b7 T8 @" L* n. h& B" o$ p, p* U! ejiffies = ptmp->jiffies;
& b3 @; I1 G9 i
9 D9 l' ?* k) j2 ], B  [
ptmp->jiffies = ptmp->next->jiffies;
# n% p, D2 w; O8 R# s
+ t+ @4 ~$ m3 ]- O3 _
ptmp->next->jiffies = jiffies;

0 j( Y) y; ^1 E2 S
9 _# G* j* E7 d3 \" r2 u% Kptmp = ptmp->next;

+ _2 }, R9 l  y- O& G6 ~  W, Q0 @) n9 x+ a) T5 _1 i3 w  x
}
4 u# e" [0 w7 n: L3 M

! m' X0 r0 c1 B& t3 U* g}
" k7 c2 M/ C) e/ W' B. U
/ D- p, v; z- j/ @
EXIT:* f8 j( q9 _3 }0 z0 r7 t' \1 M& R

3 t, x6 f/ R' P. {! G. m' QEA = 1;

( b: g& @( `6 Q1 i9 e" s
+ y$ M: `( s# y, x* E, lreturn;
, R! b! T; `1 |# L
}* e) C. N1 t2 J% f4 v1 ?) |7 s

1 R" Z" `7 m) Q7 S* Z, w: h) bvoid do_timer(void)
) ^. B7 O. M. j# v# }( I{, k* z# ~: U) h* W$ u0 U

' q& w( x' I5 y9 l: L3 \8 }) }9 X+ U6 u2 J1 C* Z: g
while((timer_header != NULL)
4 t+ v( s: m4 Y8 s1 `

& \, z% T2 O9 l) Q2 E
* h, V$ }* z7 C; D  q1 I/ s&&(timer_header->callback != NULL)
( C# t! b& g1 V) `! @" G# V
: ^# Y, P4 C0 ^! p3 x5 X- ]& M

4 E) ?/ z$ t# u&&(--timer_header->jiffies <= 0))

# N' j! F: @' I
8 A& l: m. w; o{

! c- P5 [$ K) C( Y5 D+ A0 g/ U1 N. t
/ B6 L& p1 u7 v1 Z& j/ [void (*callback_fptr)(void);
  W- `7 {( t7 ~# [" y

  ]' B  s5 L/ E+ [0 L. {
- z+ {/ l! f  @: Wcallback_fptr = timer_header->callback;

4 ~/ I3 u0 n% p7 q1 ]) ^& @( `+ ^9 {1 n$ u( @1 J
timer_header->callback = NULL;

% O8 H) P* ^* a$ S6 o0 Z/ t  X) x
4 l+ n  x) l, M9 Rtimer_header = timer_header->next;

) G* p( _9 ]2 j. Y
& J' f( K9 ^+ K) |' _# q5 o+ f' }" Q(*callback_fptr)();

" k2 M: ~% \4 G* }
- B3 d. N, N: T$ ~' l}

8 [* J  z. i' ?& P" S( Y8 D% \  N  \
+ i7 D, L! e8 k! p5 r  P& c: J9 g
}$ {$ J$ |3 ^5 j5 @- z# j- D
///////////////////////////////////////////////////% ]; S+ p7 q7 C. {3 z, Q
$ i: I7 Q: [6 O' }: T2 F

. A, }! b, h2 J: r* Q/ j$ r上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
6 I+ t5 f# ~! _6 i- S5 J. S9 |, O3 v3 W0 X3 R
野人献曝,博君一笑7 I3 S5 p% y; Z" b

! C9 @& m- m" |Peter0 E; ~3 C6 L/ R. ?
  + \, _. [5 U* Y- ?

% g8 q" l, M' n1 ?) A" c[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-12-1 07:16 , Processed in 0.127533 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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