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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
/ c+ p3 D+ T& W/ r7 ?# z

& q' n( {/ C8 m5 d( f) R' R% u1. Why need this mechanism
! R8 @5 D0 G+ B
. i' B+ @( v+ g$ _( Z
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
- _2 n/ Q( \5 y7 C4 D; [" d

5 C! c; t% O8 d- s* p. t/ Y0 o2. How to improve it?* \- W9 T4 U& @  [; j0 g: @- K
" m, U, Y' q  B
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
" [: N$ {6 _" l* S
- |2 e  c- w! ~, h, C3 U//header file
) e, s, C% \( |2 `! R. e0 ]! |! y  P/////////////////////////////////////////////////
5 f: y! m  u4 Z+ R  v#ifndef7 y, h2 h. k! E3 b" P2 X
OEM_TIMER_SERVICE__H

/ e: T  Z9 t3 {" n3 [#define
# s$ C( r% |' r# k$ a+ b# J  yOEM_TIMER_SERVIEC__H

( ]+ g+ q3 P! U# v- W
: C) F/ a3 Z% o) `1 A  o/ U
+ C. f8 h4 |" E3 x4 z4 p3 ]0 Evoid add_timer(unsigned short4 v, i5 s8 w' ?
jiffies,void (*callback)());
% G* B  M, k' I3 Z
: S3 v- a2 j$ z4 r6 S
void do_timer(void);
! v" s4 {/ Q. b3 v' J' O( O/ J/ n. S  {4 Y
#endif. {( e9 Q, Q/ j# @
/////////////////////////////////////////////////+ n; p" B" }# D, U9 a& e7 P# L
/////////////////////////////////////////////////0 P7 a5 X9 S, b/ r1 x
//impl file
; W& o5 p4 u4 a' U  X#include <stdio.h>
0 N6 f1 C$ ~! V2 Y# X#include "OEMTimerService.H"* z! W; b9 l$ I$ Q4 \7 Y
- Z& u4 [5 s0 _" m, \' |- K

. g2 j& A: j" P2 @/ J#define
. A: z) E9 M* b3 C3 e- W: O, Z0 cTIMER_REQUESTS4 y" O1 i$ d/ K( y8 s6 T( b" u* }
0x30

# `8 X0 [" {" y, ]- @  s1 r# K( s4 h# @. Z) ^, r5 p; z1 f8 g
struct timer_list $ }2 }+ ]3 b. I
{
- V* Z5 L% K& O0 u0 }  B( e
+ r# X/ Y, S" U) n/ i5 Kstruct timer_list *next;
- V7 H" P1 M/ \) |* @# }7 }
$ `; z9 a* z; V7 z" S1 w  Y
unsigned short jiffies;

# s2 {( j- x5 k" n6 A0 w- Z
  G2 X2 P! i9 u6 X8 \void (*callback)(void);
( G+ }: q4 k& T0 B  y
};. G* r& o% C1 H" }. i4 l+ W
& L' |( L7 q5 o# q
  m1 J8 V1 F# n+ |- B
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
& Z- `3 F' k: P$ v
: _8 {1 Z) Z* H2 ?3 u6 _/ {# |" bstruct timer_list *timer_header = NULL;6 d& ^, Z0 A) U4 N# x( L
8 w, C2 s: D, X9 f, v

* i! G2 M: `2 x- ivoid add_timer(unsigned short
8 J; }# ?3 U. V( R* P4 |' q9 wjiffies,void (*callback)())

- W: W1 r0 l& ]& W9 {3 m{& t; ^. E& u9 X: m
  v2 D! _  v/ m" _" j+ r' m
struct timer_list *ptmp;

$ Z$ L* z! z! t$ L/ Q
9 v! F4 N2 K3 C+ C; O" {5 x1 L  f: k" M& S* A- Z: g; J9 b+ q: J1 T
if(!callback)

3 n$ N7 O* b( \2 M; B$ Q
8 d4 P+ k5 ]0 D* S+ Nreturn ;
+ }8 \6 ]9 k; k! X' D
6 |3 \7 c3 s) R. e7 y1 S" O# Q2 S
/ z; X9 B1 d# I) }8 \
2 G2 p. N& t: R" j# E: I
EA = 0;
1 x- S( w9 w9 O7 z0 D2 f8 M/ o; ]
( Q' ~* N# Y1 o. p& R* B
/ y* B- o; I2 @  g( v& z
if(jiffies <= 0)
0 v0 o* U& B# g+ ]( ?6 h

( \% v( n; Y" n4 h4 a  @(*callback)();
$ J- ]/ g# W7 @! ?. N6 t

; {' i8 @+ V5 H7 k
+ c1 n+ u# A4 |* N  v* l% g+ U7 ~$ a

( @/ L$ R* p0 z' v+ g4 L8 V8 Ufor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

. q# Y2 ?6 ]: O6 {! x& m# c8 n; ]8 Y/ @
if(ptmp->callback == NULL)
' c3 d2 V& x. _! v

# ~; \& F6 Q- E/ N) Vbreak;
6 p( Y, ^8 u: U! z3 I% b! ]
0 n  M5 C) V) T8 {0 Y; K

( |5 E% O8 J/ E0 v: m) y
7 b; m. C% I9 q3 Z$ @if(ptmp >= timer_list + TIMER_REQUESTS)
: H0 {1 V# o( `/ h. D8 ~
! R( o. C: E  A
{
4 G8 ?2 A! H( S6 o

0 {- ~4 _$ I- P0 n7 Cgoto EXIT;

6 O) {/ ?1 E+ T: e# \$ w
  k2 d8 O/ h% r% ^2 C}

9 T2 \3 e$ Y, z6 N" c$ V
2 B( q; c; M) d. M( T  F* W
7 Y+ @- f5 P* h! uptmp->jiffies = jiffies;
$ X- J) z, w: K5 o9 w$ m1 }2 b

7 @8 e; }% M4 n3 Mptmp->callback = callback;
5 P1 i# ], y9 `: ?

0 |" O. i- K7 d3 z, N' |$ O

/ y5 |  C% K& F# E9 i5 n; ~5 s/ k+ n" P# o" S. f
ptmp->next = timer_header;

0 l! k2 L& G; x* S/ G
" U1 T) p9 [* ^7 r- L3 ?, _& ^* z% a: qtimer_header = ptmp;
- z, ?8 \& g1 y. c3 C  u. m3 R1 C3 z

( w  x3 y1 l+ O& n7 h
/ i# k$ X2 K& g/ F7 d# p//add bellow code to fix linux on timer’s bugs ++

: }# g0 F  \) J; w* H
6 X% A& F  A2 @: P% F" }if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

7 R" S) y1 n4 v
, Z# g  P8 n: `3 M5 j{
! D7 [/ _) y5 A) W$ N  i

/ S! L& S1 b! Z. nptmp->next->jiffies -= ptmp->jiffies;
& M8 V! l; z" Q: `3 X9 ?* O
& D9 o) G  l4 N5 P$ S, N
}//end ++

/ w7 l6 T9 J0 ]3 v
+ O) c  {  A9 i3 E1 C# \8 Zelse

) A+ U3 {* C( K; l8 o+ {9 m$ U* J: ]0 h4 Q9 H: |
{
( \& x+ N" Y+ F, ]% o
, c0 M: h" y$ B1 _: H8 s
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
3 A7 s) y/ ]. A$ f2 o
2 y2 m4 Z- \' P, ~

% C3 |# H2 \8 b/ k{
2 c. u# m/ ^* @+ i

; H8 t& W; b, k/ B+ Z& o# sptmp->jiffies -= ptmp->next->jiffies;
, G: n" E5 ]0 Q+ O6 g0 B% ~" p

2 g$ L0 Q2 ]# E! P9 X. A: @# tcallback = ptmp->callback;

% v, i& X! l: Q% @' ~9 s7 g" a" v6 i' R; O* n
ptmp->callback = ptmp->next->callback;
9 `) z& L- X( R/ I! f* J6 S
$ m9 i, d0 M) W7 H# d
ptmp->next->callback = callback;
) }' C5 D5 K& V, T; `

! U& z8 x+ k4 d# Y, Y0 bjiffies = ptmp->jiffies;
/ Z4 @2 W. I. E7 S( w( q
* s3 h& w2 \) ~5 M
ptmp->jiffies = ptmp->next->jiffies;

9 l* C/ Q3 `7 }2 b& S" p1 a: x& G( C
ptmp->next->jiffies = jiffies;

( [8 X; O& U8 N+ m
! P3 @. V4 p2 b7 j1 @ptmp = ptmp->next;

' V2 q- B) s7 s* t2 I6 U2 B0 t9 C( u0 ?+ I
}
  l  i& G$ u; d- n
* d3 N6 S* e( i1 v0 r5 A
}
  K2 B, Z  k+ S" K; K9 y+ Y1 x

* R" D" T) q7 b/ ^7 m1 bEXIT:
* W9 p, E1 P, k4 Z/ s8 }8 O
: b8 H+ P$ m( l2 p3 T0 f; B7 WEA = 1;
0 I. q( R* b: q+ }+ l- q

) |2 p$ \3 {) X  b  e- ]return;

  z5 C( G: I7 \$ j$ H}
  y% F; Y  @1 X% J0 H* X; T$ u/ \. }6 V2 x- H3 H
void do_timer(void)
1 _3 ~8 |& p! O" n{( Q/ ^( C2 N1 Y# v$ l/ P
" G6 Z+ c) V9 V: l2 q0 }

$ Y( K1 M% v( x) A6 h: z; u/ Uwhile((timer_header != NULL)
) s9 m/ G  B- E7 y5 P7 k

( m( E% s. `# E; a
8 W# \" x5 @1 k2 y&&(timer_header->callback != NULL)
1 M& P4 O: r/ _, l4 v( [

  e4 k; ]1 P( |9 E8 i- K6 D* g' U7 D- ]& X4 \/ r
&&(--timer_header->jiffies <= 0))

6 L! d2 J9 s# T5 t0 Z# ?3 ~& x% `$ i# m: \  l1 d: e1 s
{
* Q4 b. y8 p) I

7 U. z) J) Q* @8 B$ X# Jvoid (*callback_fptr)(void);

' x; p) @) T) m0 P
0 {* ]( u' w- w6 i! ^7 T* t1 i' z7 E& ^6 B# o6 {# J& @, ~# P
callback_fptr = timer_header->callback;
/ \6 \2 d5 R5 K7 |5 h& b

3 E! v  I1 B' e& v8 R; l  Ltimer_header->callback = NULL;
; a$ @1 s- \9 C/ h. s2 l
9 _. r/ }2 V' X# o
timer_header = timer_header->next;
& h4 d! F! U& S( M. a
' ]* g1 T4 z1 B. _, _
(*callback_fptr)();

9 ~* g" P& m7 s4 X" L- m# O: A$ j
4 \) ^, @* K( B( d, Q8 C}
% i/ N8 J, K% n. M& C
' \) o9 B( o$ ~' e. l# O+ P9 |8 m

) I  H7 g* ]4 F, N3 Y}
( Y! j# \' c8 x8 u& }/ M6 {8 f# U+ n. R///////////////////////////////////////////////////
: t; E7 }, c+ ?# f1 @* f( K5 }- S

  s8 S! T; X0 a1 N) N) ?上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!- q- }; u$ U+ F' n
  m$ v6 _; k' o: B% Z! J5 _
野人献曝,博君一笑" v- b/ s$ E7 H/ V( ]5 w

. _0 f: P# p% p) R' P1 l4 kPeter1 }& n  A1 N  }7 ?3 z' m
  
+ c: q9 g, B" @/ D3 X0 M+ w( _* B  e2 [
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-9-4 15:47 , Processed in 0.057230 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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