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

Smart Timing Mechanism

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

+ y# d  z, R6 Y' e' L

, C% z( I+ O, D+ r  k& s$ h1. Why need this mechanism3 V) v: d0 w5 I5 G
! Z9 V3 ^4 `  t$ k( d, n. K
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

+ B7 J" o3 A, c2 k% l
1 R" Q, T, L1 w9 {2 o2. How to improve it?) i; |$ s% g  P0 N) d

, v$ Z+ a1 C3 Y6 c7 Y  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code' \6 s& M+ ^. d! G2 `8 q4 N1 m

' X( A" _2 V. Y( ?7 E//header file: C* `* {, Q9 F0 Y
/////////////////////////////////////////////////
6 X" q9 Y. G$ c5 B6 ~+ N; u#ifndef; K8 U; o9 ?. S, G3 O
OEM_TIMER_SERVICE__H
  c$ U7 |( |5 W
#define0 ~2 ~* Q" v) S0 N! j
OEM_TIMER_SERVIEC__H

# w; k8 k; Z; d& g9 U1 [& B) C: ^* \3 B& O# L9 O! s  S
/ n  X, B  N- c
void add_timer(unsigned short
+ e( C3 R. J" Vjiffies,void (*callback)());

! `. d$ j* s3 S9 T! h% y* u  p
/ Y/ N  v$ [% ]/ B/ @void do_timer(void);
" C) O9 }- y/ T5 D2 T( @$ j* O5 C+ @" z
#endif
! l; P- i2 s* C/////////////////////////////////////////////////& F- |  w! |& o, B6 W3 A$ \
/////////////////////////////////////////////////1 y8 L* b! ]( F5 k1 y
//impl file/ K3 v5 C1 t5 t6 M
#include <stdio.h>$ y( K! Y5 J7 G1 r% n
#include "OEMTimerService.H"8 b; x" O: g: }4 A# d6 D9 g

* Y, e, @" u4 h( t& e  {( u2 Z  ]( |! `
#define1 Q( `5 o/ [3 E8 w+ a) b
TIMER_REQUESTS5 N- O( j4 A- `6 j& m0 X* r
0x30

& v- c+ B) `0 {' g7 n" B% Z- ~" I7 F. L
struct timer_list
6 u/ N9 e/ K3 ?6 e  I{5 t, @8 ~  ?! S, ~8 J5 Z

. @* y8 r, v' i; @6 U9 Cstruct timer_list *next;
8 d9 z8 \3 @8 m* d6 Q$ ]) Z
4 L+ G% x; J8 _+ ~) S' v1 U
unsigned short jiffies;

7 d) r0 C# I5 M2 s7 i, D# q8 h; v5 m% b
void (*callback)(void);

/ s2 Y. g+ \+ x7 m% C5 R( u};1 o! s+ Y$ F, T2 g! J2 T$ ~
9 \/ G" }% v/ W- z

; F. ]! B! ?( g3 g6 Lstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
  `3 K6 ]1 N9 x: b2 Z) P
8 Y; |( ?# K7 {* E: d- hstruct timer_list *timer_header = NULL;  u: P. T) l5 A& P1 H3 A

" @: k# l/ [* R  i3 k( z' B0 M. `7 s8 s# c1 S
void add_timer(unsigned short
$ ^2 v& y6 Z( ?9 t* H6 xjiffies,void (*callback)())

% A. N  v, `: ]5 Y3 s4 l  a3 @3 S{
8 J5 `! B! {$ p6 S; s0 r5 i2 S1 c- \* n# x! q* \& r
struct timer_list *ptmp;

& Y; O! c7 E' _; f: M
- S) M; i) O- z+ K! Z& g
& |& ~' G9 k( O5 e1 r, ]if(!callback)

/ Z0 x4 G6 F+ J9 z8 L8 `  @! c- W$ H) X1 I' y" ?1 I4 r3 z
return ;

& q5 T, x& K' _4 ?1 Y# _/ @  s3 O6 D4 |4 \' {- n. q3 H0 D1 |
& ~1 v/ I/ x4 f5 j" B1 b5 f, V0 r
7 C( e, _$ ~9 f+ d' f" N' v* p" X7 H
EA = 0;

5 o- N; c" k: m5 G5 p; i# O. a2 n4 J9 j2 u
' y! b; \3 H) P% I
if(jiffies <= 0)
2 O9 v! W, n& @! C

1 G) `7 g0 H8 @% s" p$ ^7 p2 B6 J(*callback)();

3 U  A9 Z7 h, B! m) t1 ~3 ]0 ~; i" T

3 ~: [4 q1 M" ^+ y
+ l0 k. ^8 |' Lfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
. |3 Z- ]  l& q$ \1 v. L

" F% c, a9 T7 P, |( f; q. e% eif(ptmp->callback == NULL)
- C7 ~1 J7 I- Y# y

  o3 A& t" d1 u+ k8 b, y9 v0 K! N( dbreak;
6 E  Y3 Z4 g& L/ c9 y
9 ]2 }3 \/ ?0 i0 I8 y
9 [( A% K) N& N( u* O3 L4 `
# d! t6 d) p1 a! f
if(ptmp >= timer_list + TIMER_REQUESTS)

  t+ B4 ]& g" z7 k( r, @) L' k4 n* b
{
+ y& S/ X" q; F# q$ d2 ~0 n
3 D8 p! [9 k2 C3 l/ ^6 m% p
goto EXIT;

  D" X2 e0 \; A9 h8 F; O
" q$ A0 A( i2 T3 d& i) Z}

4 I  Z' C. `- ^# x  g
- W8 a/ P3 B" P/ A' m) f, H( J* W- P5 O: l& A8 d
ptmp->jiffies = jiffies;

) \! y, m# D" S  D9 L
7 A, d- C* b3 |, ~+ H7 s3 @ptmp->callback = callback;

5 h) |# C% x, N" \0 n' H3 R
( j# Z3 O$ T( C4 A# d1 H7 X

, z) k4 \# I, x$ u9 X
$ `) W+ S. g( }2 |1 J* i9 w, _ptmp->next = timer_header;
, x- q- o# O, v' x
% s( q! S# R) V8 c; i* @
timer_header = ptmp;
2 Q" _" v) B2 n: `% w* H

3 S6 X$ B+ ]' n% l' d& a
" s) G' _# O& u4 z//add bellow code to fix linux on timer’s bugs ++
, j4 p/ r' q  I( t: t( }& J
# F5 c5 A/ q1 m- k3 h
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

8 v% ~, {" c- K3 y. K
  \5 R/ {, n8 J% t" W5 |" J{
0 B$ K- n1 J: I# Q* ]; r1 P4 m

9 g6 @6 k7 N8 H) D) nptmp->next->jiffies -= ptmp->jiffies;
* K8 @0 [% H4 b
6 @, l1 c7 `* h& |' ~% U4 L- Q
}//end ++

8 R5 L' ^9 |* R7 J5 s3 b
# g* j5 b* H7 `$ nelse
6 S, p3 m0 P2 G' d7 I! Q) H

' H$ H9 F$ Z* V% t5 K6 j{
. X& M2 Q! R: ^2 [+ I3 p! q
. G& S( b6 d% P; X4 e
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
; t# c( y" x7 z8 e2 w# M
! V" j. F; O8 c' T4 r* M7 q3 a

: U& P" a. H* _- h{
# I$ |2 n' R* s6 h- ]; }

* o# d* b/ a- ^) lptmp->jiffies -= ptmp->next->jiffies;

1 B# o" m, N% Q2 h1 y* R( G" t+ h" }1 P" H7 j$ h+ P( K; O  k
callback = ptmp->callback;

; [! G3 h8 {) t& R
1 n$ h. B% _; d7 `ptmp->callback = ptmp->next->callback;

# {' v! a: i( W3 F/ _$ V+ k, ~
2 U! W) \3 r" W7 @" Zptmp->next->callback = callback;
( |+ S4 Y9 X! b' `7 i* X: N

% G' s& B* F4 N6 e& ]" _0 ojiffies = ptmp->jiffies;

. ]- r0 i" V' ^1 e# h
; M0 R. g: V  l- u  Q* p4 |8 sptmp->jiffies = ptmp->next->jiffies;
6 V; P7 u( v. w- h: \; ]

1 r3 F: M4 E2 N0 n  \  {, Wptmp->next->jiffies = jiffies;
% v' U: [8 @( O3 m3 z- X' e/ P/ g
, a6 h+ J; F, K9 ^# f: u% U
ptmp = ptmp->next;
! `% G) t: {# S% v- e8 E/ R
2 n% Y# _) S0 c
}
; a* o3 g0 ]% Q9 a8 n
9 o7 u3 y; ]" Q6 X
}

  D! ]. |3 P( L% y4 v1 M) R
9 k$ [, }! I, U+ Q* S$ ?" jEXIT:
+ H: |% c0 o0 @7 v, o# _. @1 H1 O% ]. b% v+ ?
EA = 1;
3 w0 ~9 ~$ R: D/ I8 t, f

. C0 E, n$ z5 q) x: ^) Mreturn;

1 \7 D' @' k1 Y4 K1 Y}
9 I" W. t. h3 u; x* Y. |# {' Y) F) u" e. ]- x! S7 O9 f1 q6 r
void do_timer(void)
) p) K. ~" y' S4 H9 J* |{& P, s9 B0 b! {+ W2 \9 U

1 c) u1 d+ @9 f( r* [
$ Y) v# B& z# r3 K8 B! ?while((timer_header != NULL)

; L# h& e7 {" X. z1 r, |
$ F4 Q5 _% V' n( Z6 p
# ^* ^( ~! e3 }+ Y8 o/ |&&(timer_header->callback != NULL)

9 X- {$ O  R) S2 v2 L
! x! C8 t/ _& Q2 u6 h" e! J. x/ ~; m2 C/ o( q: ^0 A& F  e) i" Z
&&(--timer_header->jiffies <= 0))
3 G2 B$ Q0 U, W: `2 n
( d5 ~" ^) \" t8 r6 w
{
" u- }4 J! D. z  y

/ p+ a9 c$ x' P* P! Evoid (*callback_fptr)(void);
6 k( X' d# S9 g! C/ x
- n. \3 q0 Z  a! l, m% W" n4 H( ^  a
0 F* Q( N4 l- H" d% f
callback_fptr = timer_header->callback;

3 k, d! Z) }8 C
! ~  @% F) n5 Ktimer_header->callback = NULL;

8 [6 ~7 x) K4 K& [/ ]
$ [; E: }5 s9 t9 s8 b% F6 Htimer_header = timer_header->next;

5 ^) o% F. Z8 c  i9 D
3 q7 E, z: w  p" `4 [# b; }: d' \(*callback_fptr)();

! i. ~& D+ G! w. |# K' S; Z/ m6 {8 c  ]/ h8 U& W9 ^5 S" M) R
}

: c( t+ z! v7 Q& ^$ f2 [( G% V; {3 e% B
( I  d& }( x6 g
}! e! E% V: m8 T# Y
///////////////////////////////////////////////////
7 n: j4 x1 h: n/ B# `- C
8 V6 g7 _/ ?* R) A

% G8 ~# T! a8 ]+ e上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!- i4 v# \8 W% ~) M

5 T6 i+ W- _) j; r% S野人献曝,博君一笑
2 {  g. V  [; s. C; e( g2 I8 o
& Z6 X% g( u1 K" _Peter; ^- F! b. I# Y' ~( Y0 x
  
4 y9 |# D- ?% L5 F  W7 G4 _2 j$ Z2 V. n- C7 R
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-1-18 21:20 , Processed in 0.085606 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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