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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
5 ^1 g& \$ }0 I

; u0 _8 \- [; t/ b1. Why need this mechanism: E  x4 C  I' t( b. A' N

5 z8 }6 J1 ~8 W5 C  n8 S
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
0 W4 {! p' ^& Y. R  S
8 X* k2 U8 q/ ?% A2 Q& ]* S" ~; \. X+ Q
2. How to improve it?
# y: g7 b8 X9 N! X! t
1 X+ T& n* ?9 w  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
5 H; z( z* i  h' |2 V) w! F& y. @3 N2 ~# G
//header file/ a, u) f* A9 F9 R7 i  H2 S
/////////////////////////////////////////////////
5 _- E1 w/ F7 n0 V  l# P#ifndef. }2 A, U, c( u3 A9 E+ q
OEM_TIMER_SERVICE__H
6 W. i0 n8 e# M' A
#define
6 \5 K" w$ v. D+ ROEM_TIMER_SERVIEC__H

' k0 _  j* l1 ^  p! p, s/ ^7 l  y. G( b7 O. C. o: g3 W
; W4 U: j0 n) ~) B4 b
void add_timer(unsigned short6 j6 H  z  {! {  q
jiffies,void (*callback)());

: g  e4 C9 h7 d. K
6 }5 i3 i5 a5 x" pvoid do_timer(void);$ R% z; p" u5 d# p6 @
3 [. `7 w8 d8 D; U) k" y
#endif. ~, X3 N5 X5 \5 l
/////////////////////////////////////////////////- l) l$ z; |/ h7 t" E  ]
/////////////////////////////////////////////////
7 Y  t. e3 m8 r, Q3 U& A, Z//impl file
  ]! R+ H/ Q1 D* N$ \#include <stdio.h>% ]1 D$ V6 b) @4 x0 |: u
#include "OEMTimerService.H"
. b& C3 ^5 u8 h8 {" A( Z* m' d8 M4 B; R( @) j' T
/ V: y! h# k9 O0 e# r5 b3 z: V1 _
#define( f/ V* ]0 z" J! Q4 y
TIMER_REQUESTS
3 f4 j# z. ~; v. w0x30
4 Z" _' O$ {7 i+ {$ r

( d# _5 n" O& Q3 G5 nstruct timer_list
% H" N" K! h) b9 }{" N/ i. J+ Z) f8 V9 J5 v

. _0 M& ^' R8 z4 I: {struct timer_list *next;
% m" P2 m+ E0 W* R
3 Q' y5 ]6 t, q
unsigned short jiffies;

/ M, f1 I$ J5 ]& t
  e3 Y% e- y8 |; rvoid (*callback)(void);

& {  Y" }# J$ B, x- s};
* z6 \! j1 u3 T# f  H. k1 s0 j" }1 A0 _: i9 `( o+ [2 Z

! d" M6 a' p0 C/ Istruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
9 ~& x! K4 h; h5 t+ i
. `+ n+ Q/ r* \1 ~+ x7 lstruct timer_list *timer_header = NULL;
  s: [2 Z5 [# u3 C% ~4 V; u# X" p2 V2 B+ v$ n6 U3 w9 b( z/ N- M
" z6 g  o3 x5 f# B
void add_timer(unsigned short/ _+ T8 M  G) c& z* V) ^
jiffies,void (*callback)())

  L5 ~# s% h! R% ^: G{* n, y9 c  P) O) n- w# j

- V4 O; m; n. b! Y" S5 E) \& Kstruct timer_list *ptmp;
8 x8 B8 Q4 [+ x  W  [5 B. i
, u( {0 K* ?, |0 ~6 U* d' G' R7 |
7 i% y) \. C3 z8 b4 L0 @- S
if(!callback)

* x5 B8 @# q. F5 |6 X; i. h$ {) A  ?. ?* G
return ;
+ b" Q% \# E8 V+ A! r0 i
$ B' U) w1 \6 d
) i: w9 ]. [7 c5 V7 M& N% z

9 U. \/ P; _& Y$ BEA = 0;

; z) M, T  f, b: D( p, ]2 p/ A  i! g/ B  Z3 i) ^" c

7 A8 l9 ]" k* |# \9 `$ N2 {8 z$ J7 |if(jiffies <= 0)
/ w6 P3 }5 r4 a2 n% D7 \5 c2 {
7 v- R* {" L8 l* s
(*callback)();
2 @0 a( l  C' U. ~" l
2 ~2 C3 E: [% A1 i4 `( ~4 ]- {

$ h3 \; r  {- P3 C* v5 b5 S9 G9 ?& ?3 F. S5 X( R
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
3 ]7 J, P- O. O& d8 \4 {3 P

' v) M2 \5 D. s: |: tif(ptmp->callback == NULL)
% E8 o5 K6 v. ~+ e
1 ?" P/ ^- u. x* o+ ~/ y8 f
break;

2 v& ]& u, E- F4 B' q" l: {2 o( {2 F9 m; Y( ?9 s

' e, |! X8 k2 g; j& D1 [
  ~; w- u) u" V$ {; C* nif(ptmp >= timer_list + TIMER_REQUESTS)

% e+ V( y/ }- C6 L) A- P" ?/ T- C- d# W
{

3 y+ @$ _0 x3 F3 u: Z
7 p6 x! [9 K) N; {& C- o" G/ {; jgoto EXIT;
3 M& E3 u- h6 w+ D  p4 T5 H' L
* J& W6 D) |1 I; `: S, i% A$ }' O
}

+ Q, p: G4 N0 B. i* L9 ~4 \- D+ C, i; N6 g+ ]# u

# a+ N/ R2 b: _3 l7 t# q/ Mptmp->jiffies = jiffies;
7 [; ^5 N" b# B6 \$ i. R( U+ m7 x5 }
6 a. K6 P# T8 }, h
ptmp->callback = callback;

! V4 X9 S: J' o2 K$ C
- O) d. c4 Y! m  K9 {& q
) g; v7 n" A# ]6 D- _3 B

9 t, @" X0 X/ B, aptmp->next = timer_header;
% g& E) K3 @/ O
# ]$ w6 c6 `& b" ]5 V; D
timer_header = ptmp;
  `; T+ J/ p4 D+ \0 m

! r' Z( H- K9 g  h/ ~, D6 h3 d  `% K* m
//add bellow code to fix linux on timer’s bugs ++

- U. H* j$ x& C1 @
0 b5 d8 N0 W7 z5 P+ ^  l6 ^if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
1 o4 e2 o4 f2 y& K" f+ O; X
+ h- n! I& G# r; j4 G% O( m2 Z
{
+ [  N, w# y- ?
# F9 N" D# N+ t' f* t
ptmp->next->jiffies -= ptmp->jiffies;
! R) e; e, I$ V+ Q4 k6 T

! A9 U4 Q' l  p3 V5 v8 K4 t' l4 ^}//end ++

: Y* _) D$ S: j2 x/ [, n) Q' j: }) n' J/ K) q! m, L4 P) T
else

% H; q- s' ^* C  u0 w3 K! G6 @6 j9 h" B0 Q
{
: U) w* r, `# e* H, J# G+ C9 v4 I

' O/ l3 N2 y; \& Rwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
, b# Q# ~; Q9 X3 ^+ Y+ b( m

2 ]; K, f9 _0 J1 D# t7 }; R$ u
5 g$ ^' H! |; K" [{

" o$ c3 c7 j+ B2 j
8 x6 a2 G+ h4 p6 Xptmp->jiffies -= ptmp->next->jiffies;
6 k* |! V2 H2 M, U: R8 v

- a  \, t6 ^) O  ?$ xcallback = ptmp->callback;
3 r- _6 P5 e4 P

# j( g9 a8 Q5 j9 {: D( s' ~, nptmp->callback = ptmp->next->callback;
" {, ]9 }! b1 N+ o4 O

* S! b6 v% {# Q2 s3 G" Vptmp->next->callback = callback;

2 U0 t# ?. B$ {. ^; [* q! ^/ C$ r% E
jiffies = ptmp->jiffies;
, }' R. b$ M/ p, @1 y5 @
; W+ ^$ z- e" @2 T. ~# D! b$ j  f
ptmp->jiffies = ptmp->next->jiffies;

: l2 q1 V# ^6 f1 L
1 T0 Y0 ~" `% ?+ I. [ptmp->next->jiffies = jiffies;
5 H8 x6 ^5 F6 c2 [( f! m
- u% w" i( {8 y; d, e: \$ m* _4 Z
ptmp = ptmp->next;

6 E$ a% Q7 f0 i/ N$ T9 x/ P4 l4 h0 H; g9 B
}
2 d0 s9 m7 s# D6 O
: O( O4 A2 g: k
}
# S3 ?, x, h4 r3 \. a0 ~" l

2 x5 ~7 U! C+ `8 L# Y9 p7 Z& r! AEXIT:2 i3 ~" V# I* S4 j8 d/ ]& I1 h; c

* B/ c- f$ H4 D5 LEA = 1;

4 A, t( u3 X! q" d9 D
9 @; E3 w  @) o, x2 l+ K" ~return;
) Q6 L5 }& Q) o5 B& I
}
* Q1 C8 k% M, b( E
% [. z/ c! _+ r7 v9 S) ^void do_timer(void)
7 b1 Q$ R+ f* X( W* t* s{5 c6 D) A8 w& ^) i
  c3 H  f4 i9 ~/ L, I
2 ]* n5 Q" g! ]  q  M
while((timer_header != NULL)

& c- q: p2 `" w# t6 Q& U
, z% L# T! u; X; D+ g4 ^# r8 i6 F" Y; Y$ [2 x
&&(timer_header->callback != NULL)
6 A2 A+ V# f+ c* q( t: m
! G7 A8 i3 g: H  `9 x. k# g" D- s

- O7 @' a$ K$ C/ l&&(--timer_header->jiffies <= 0))
. V) m+ ^6 j4 N  x# ^8 ]+ @4 Q& @- c
0 c1 `' W( x6 ~2 u
{

0 K7 C- S5 _" w/ {3 r- u. N6 R, ~/ [) U; O4 X( R
void (*callback_fptr)(void);
9 b+ ^6 o5 R7 o* d7 l# L
" G" m) Y/ K* A  o
: X/ X+ T7 _! w+ ?8 K. g5 N
callback_fptr = timer_header->callback;

1 p9 D8 n8 X6 U  ~5 f
7 t, u+ u+ B" Rtimer_header->callback = NULL;

6 l6 Z6 v2 F$ f" ~7 p
2 ~# J  j- f! z/ G: `6 I6 j4 \+ otimer_header = timer_header->next;
2 P5 D: d+ g0 a

, A2 `' m6 U/ c' A* X: |(*callback_fptr)();

; t. M) U3 i. K+ r' l4 H% m3 C" y7 L2 O2 ?9 i% n5 i' T+ n
}
# \0 h; h3 a4 j% y& ~

: N' A+ @2 j3 ]  y4 _
; O; i. a/ g/ l1 n" b
}
. V( t% w: ]# s! T% y9 A///////////////////////////////////////////////////
  L( p- z- i2 O
" b# I5 z" s" ]" }2 ?- V) Z4 S, z
0 E' y5 `1 R* {' ~
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
; Z" r& A% Z' Q( \8 [! A( Q& a2 w' {
7 k' e$ p$ {2 ^3 n  S: {野人献曝,博君一笑
- f: O% W2 S( R! u* ~
( [  J0 N6 P/ ^6 t  c) `Peter
: ~0 d' Y0 C5 {1 _& v8 ^  ( z7 Q3 P* J) }, D7 w3 P
/ k/ M. s+ j; d- c$ Y3 a
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-7-19 20:45 , Processed in 0.216400 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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