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

Smart Timing Mechanism

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

5 L' v4 i7 p6 i/ H; u1 Q. s3 u
0 l& f$ y) o/ G8 s+ |2 \9 w
1. Why need this mechanism( n& b; ~; I3 i# c  G

; ?% t) I! k5 ]
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
7 z4 J, N; M! N3 A

0 t/ Q5 N, w* |) Q' ~" u2. How to improve it?% g6 J# {: f2 E  a

/ y" M, Y2 I7 y# ]7 u; ?6 g  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code4 _1 n- y3 m5 N6 D& G9 o: k/ c

# t& ?3 x$ X6 n4 E; r8 l  ?* ^//header file
0 n' `( m) b9 y% r/////////////////////////////////////////////////1 g0 c% b! t5 H% L( _$ O
#ifndef$ S6 W; j. D1 x, `, P
OEM_TIMER_SERVICE__H

! ^; o' h+ z$ N4 O3 k8 Z6 ^#define
9 ~9 h- @# f# F5 BOEM_TIMER_SERVIEC__H

8 T- ], G  p4 W. |' M; ]' j
% T0 [5 T5 K6 e$ U0 |) K! B4 P. _$ i
void add_timer(unsigned short
# {8 k0 D8 o5 |. _8 H# G0 D* Ljiffies,void (*callback)());

9 i4 A7 F* x! O7 l7 j0 T- O9 P& E+ X, k6 }7 P
void do_timer(void);
& Q9 d8 G6 [5 {& W* I! B0 ]
4 V6 w) ^7 Q6 @% U' @#endif
  t& @; ^) L& A) p0 {/////////////////////////////////////////////////4 |: W% t! l$ I! E
/////////////////////////////////////////////////
  S* V& g- {# l4 V//impl file1 {+ K' [& \; W: r3 V
#include <stdio.h>
0 k. n2 w$ ]4 c% Z2 L: m$ H#include "OEMTimerService.H"; K$ N0 g& r7 o! M0 t  l

: L4 m$ k: m% x$ `5 a3 l
5 M" Q; D  _5 s3 D0 L2 Y#define+ h& T# N- j0 c- m) P
TIMER_REQUESTS# v: G7 G& P' B' G0 r) z5 q, g% @
0x30
& n; {* p5 \+ A7 j& A; Y8 ~

) {: ]# }9 N; y+ l7 \" bstruct timer_list $ O$ U, k1 H% U  N3 x
{; R$ K: Y9 E6 \' o! A; W

( u4 Q% W& i3 y% E8 g; a. ]* ^struct timer_list *next;
0 `9 q+ v+ K  x+ g6 m/ P: ~1 S

2 N" I* L% G3 _6 c# ]" \unsigned short jiffies;
9 D( ]8 U, t- E" G9 }

; I" p! t; X8 _void (*callback)(void);

& C+ u% K3 M. Y- ?; r+ G};* M5 K& I: {  t' l7 R

# n' k: c# G3 }# X" o( U0 J% K1 K# l6 ?
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};7 @8 P5 {) {7 f( P6 {5 P6 t

: K8 W0 `; P4 u3 E$ E; c  istruct timer_list *timer_header = NULL;; P1 |) I: y  Z( `( ]+ ^) f
4 I' a5 P4 e- J6 E, i" f+ j% x! C

- k8 \  V. w0 D, Vvoid add_timer(unsigned short
% o) C% ?' \7 d; w1 r% Q' yjiffies,void (*callback)())

- f3 Z2 o% C$ S2 L; ^. {; c7 W{* j$ \9 K/ T! W# c- S
8 Z/ x: _* i7 Q! Q8 p- n  s# r
struct timer_list *ptmp;

  B4 C% c* {. c6 S7 b) |
& y% E* Z3 z& @8 x* o' Y9 S# N6 [& ^* c: E8 x2 J" P2 X& @
if(!callback)

* k! i9 ]! Y4 @4 {! }5 h# y
2 i3 n% z5 M# b* ~, `: W0 Wreturn ;

: r& S7 ?' a: i5 ]" b+ h8 ^: W) W( Y  R
2 V" w$ d: s9 S7 }
  F( L  P3 d# g& J; k8 \' N
EA = 0;

) b& t5 h) n! ]/ W: T  O1 }5 x* P: N8 S$ L! V( a" R4 _( d

! O' z7 X( T( H1 O9 Q& `if(jiffies <= 0)
' H* }, w' B' ?3 G; C0 D" c& N5 r

; ?0 C. s$ Q+ I7 C- q$ }% x(*callback)();
* F2 M6 t! @6 x3 c. V% o
5 c$ }! P" b0 L6 W) D
' ~% f. R% [) J: q
: |/ ~5 a. K$ r7 v0 f
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
' A' a6 [. k, v! E
* ~& t( R5 j1 d0 b; }0 `4 l9 W
if(ptmp->callback == NULL)

6 v  C5 ^% ?1 s4 ]# Y+ V3 S
3 L+ a: Q) ]& T9 o: tbreak;

1 ~0 B/ o! X; ^7 V2 s- X7 ]6 |6 J
# d1 b9 I8 J* z" i4 d# [+ r/ \4 n& ~! f3 R

. ?% W1 t% _% m$ h% b6 _. L7 dif(ptmp >= timer_list + TIMER_REQUESTS)

( t6 G, U, k# T9 q1 G, {& N
* ]( x6 `3 H/ j9 Q{
. \6 K5 ]7 Z/ L$ F9 n
& `& v$ t1 x, N$ j" E) @
goto EXIT;

* Z, |# y, t7 {' A  P. Y: u9 @+ h. ^! X2 {- ]6 M# H2 T
}

5 Y9 ~) f  {; e9 E  n
0 l( c7 F$ V% s- f2 b6 }" T# T$ ~+ ?8 C; {' t7 X) E4 c
ptmp->jiffies = jiffies;
; Q3 x/ ~- {5 i8 j1 w

% E" C& l8 `8 A6 z3 D' W! l! fptmp->callback = callback;

7 v1 i$ V$ [. @1 Z8 B" S4 s) H7 X" f4 H. a4 O

) f6 j- W5 n4 T
( e4 e; C8 W$ A$ r0 Z! m; v3 Vptmp->next = timer_header;
" m' t& H4 V# w4 v

0 y7 V7 e( Q* I$ ?7 vtimer_header = ptmp;
/ b) x+ J6 w; p4 j
( z5 |. T7 y3 u4 U* g9 [
" H' z2 @( Z+ f+ }0 m* n" d# s
//add bellow code to fix linux on timer’s bugs ++

7 d- O# e" X; T1 ^5 T  x/ ]& d# a- C3 z
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
2 y0 `: I% x7 P, @' x
8 ~7 ?3 U  Q) E0 l
{
1 j! D. T" i5 R
4 W7 m7 ?1 X- q" v
ptmp->next->jiffies -= ptmp->jiffies;

9 k2 W4 v% t" b3 l, v$ T  |# j& o' D) T9 o$ l% q+ j
}//end ++
' r( }: f+ L/ G& d5 m. w

7 _+ z' U9 m$ I+ x! K' u: Welse
( r& i0 w8 w, T- m4 Q0 ?

' e  z7 G- o; H) }' b! K{
2 F; w' x* n8 f7 ]# p! z

0 l& q0 p6 K) N" Owhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))+ W$ L, Y! ?' W- N& C& ^% B# R, ]
5 d+ Y$ P0 Y0 ~0 v
: ^8 |7 b- D5 ]3 u  Z, |1 L
{
4 l7 v8 R- m9 \. F. B& |9 J& T) ?
: G5 C+ e9 {+ b& v
ptmp->jiffies -= ptmp->next->jiffies;

! K6 k5 H5 v* j' [* }. E& g  V& k7 Y# Z! Z+ _! B, c
callback = ptmp->callback;

1 B, r( g% J- W# W' K9 X$ x9 l) _+ D) @
ptmp->callback = ptmp->next->callback;
) q/ q% I- t, I* H# l8 i* D  x5 D. B

$ Y# T. h& r  O  s- n$ N% Eptmp->next->callback = callback;

9 y# p+ @+ w1 K3 C( J
! B/ ]* k; c$ I! [) p7 O9 F; a) tjiffies = ptmp->jiffies;
6 Z$ P9 X: B1 w/ T
% ?: h6 i- y# _. m& ^% W# P! T" C
ptmp->jiffies = ptmp->next->jiffies;

' |0 {. `9 E/ C' t; v- H3 |! t' k7 |$ ?- I. f5 [7 m, ~; o
ptmp->next->jiffies = jiffies;
: B+ S2 l3 s9 k

& M' U$ ?8 w+ E( O3 G, Zptmp = ptmp->next;

# [) \1 z0 e+ L! |5 O
% h/ K3 Q- r  F  g5 w% V9 A$ V& M}
0 e4 L: f* y5 J9 |( |6 t5 F: f+ ]

% b8 C) g0 I6 l5 T0 T9 v* u% y}

. F' I4 O" m: v8 m1 ^1 Q9 G( C) K# Q  z! c5 x
EXIT:+ R/ y  t5 t- |! d

) l7 i$ T) F1 o7 ?% x! }) BEA = 1;

& b. l$ z/ j6 g
" o! r' x3 j1 k/ nreturn;

' ~& a: U+ R& M# ]9 Y, ^" R; Q* {}
& o0 P. y% U. o
: c; N% @+ [) S8 a" L4 fvoid do_timer(void): R- E5 V  g0 I* _/ ~
{
  z5 x  `1 t1 y7 u" Q3 U3 V

$ ?( c+ b, V1 X. H( a+ d( U* V4 B) ?, z% I
while((timer_header != NULL)
5 d1 `6 ]# ?9 `

' h' P/ u( T1 A0 i/ ~& J
3 e9 Q$ p1 m/ I: {9 m% Q' W% x&&(timer_header->callback != NULL)
9 `- X$ G3 m1 E3 \# @& z) r

6 e1 Y, y' K* y7 N: P: n! ?0 K$ J, O& Q' C
&&(--timer_header->jiffies <= 0))

; M/ \6 m$ b" n9 d* y: Z, q+ w
" b( q; z( c7 L2 a  f9 O. q{
6 d; ?' s" g, ^% U

- M" s6 L+ h5 r# N5 \void (*callback_fptr)(void);

! I0 z! Q8 d1 ?- W( B5 ?& B
9 Q/ Y6 Y" `  L% J  }9 m  P4 v6 `. d# O3 a
callback_fptr = timer_header->callback;
/ U- W  a" H; R8 T) ^9 R7 ~
5 \1 ?: q) _  O6 b) k
timer_header->callback = NULL;

& d) e7 w) T& i% S& Z& ~' P+ B+ u& Z- W! f8 b6 i9 M% y4 t
timer_header = timer_header->next;
: Q' H+ Y7 H" G& e
6 O- }5 ]: w, _+ ?5 w# z* c
(*callback_fptr)();

( z* o2 p- Y0 j3 E6 f; ?' Y; L
( K2 v5 Q; I# u}

* j7 x5 e: d: M  y
: S. J# `" k1 }6 V5 J& H
# {( p3 t6 |) G$ V& {5 F
}; p8 G4 s# ~* S/ r' {
///////////////////////////////////////////////////
' p' X3 {) ?* ?
, A6 Y" @  |  u6 ^9 D5 R4 o  g+ h

( e* W- U: T2 S" d0 f6 e' N3 j上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!6 a* U  N9 T/ ^, M* t6 l; O
6 ~! N* g; C) i( c0 G- T9 l
野人献曝,博君一笑# K) b* h0 v! q3 o( u2 n
% o. o" ]4 h; h; D* x
Peter
8 l: Y; V. z1 J2 X5 ?& o! m( B  
! ^* V& y  ^* {( w/ \  i9 n) _
7 Q* l: n( S" {% b$ H8 ?[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-11-23 23:05 , Processed in 0.032874 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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