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

Smart Timing Mechanism

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

6 v/ ^6 ?4 O) n" M* Y8 v

, `) [5 D/ v5 R5 n+ `3 `3 c1. Why need this mechanism
* t% v" q- D6 K9 q0 n0 \5 u* h" n6 s# T* _: f! q& d7 Z8 S
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

' D- I, L7 {; ~2 R4 w
3 @/ e" L5 e- C; C3 t. j3 K6 z2. How to improve it?# r0 T. M, ~2 F: o! k8 ~" x: z
8 W  q) ]0 C8 C8 ?' V9 t" O4 G0 w
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
9 b. h/ Y: Z: q7 t
& R2 L* n7 I# i% j- L4 }0 S8 i//header file
% V7 {6 e+ l! R: @4 i/////////////////////////////////////////////////, O! p2 K, P$ J3 P) V9 V. [; G# f
#ifndef2 b- N1 L$ d7 ^" ?  U* L* B
OEM_TIMER_SERVICE__H

+ d( O  R6 G( l#define7 |+ V* B& T4 V, u2 k
OEM_TIMER_SERVIEC__H

# D/ u/ {2 U6 b, x9 ]# [
4 w3 J* i6 q- P  S9 a* V* \# F2 F$ h5 U, Q" y
void add_timer(unsigned short( T+ O: r* f2 g/ p6 p3 j6 e
jiffies,void (*callback)());

; V  C) X- ]+ n; R2 m
3 N3 f$ }$ P* ?2 kvoid do_timer(void);
6 ^& n4 `1 T5 a8 O
8 ~! O1 m! \; f$ e#endif
% l, p; h) z" E: S/ v- Y/////////////////////////////////////////////////
, {0 q+ a- ?& a& y+ Z/////////////////////////////////////////////////
% N( R: m$ r5 c" R7 a//impl file
7 W4 ?3 H3 \% I% F& a#include <stdio.h>
+ u4 n  }4 C, @#include "OEMTimerService.H") f( {& A2 z8 |! ?
! a/ c5 q2 g$ j: L9 `6 ?' D: H6 a2 S

2 A- s. X3 D3 h#define
' @' q/ K0 s3 Q+ cTIMER_REQUESTS. j/ _1 ?! z. h$ j% U
0x30

( s; _8 Z% q2 v3 o5 y3 g7 v7 }) @" _" }1 X" [) S: r. R) w
struct timer_list 6 A6 m8 s2 ^* N& H2 w, {
{
, N& A7 Z3 P  M/ p" |) t
$ g( y9 O# K# D# sstruct timer_list *next;

) y) V" P3 ?/ i+ Y( F' e/ t4 _5 y  [; G  Q' n+ B% V
unsigned short jiffies;

0 V" P# l+ `* u6 ~' ]5 L- |/ a& Q& x( S* t* R% Q! H
void (*callback)(void);

1 R7 Z4 s! E! U/ g* c" a};
* K2 d: Y; z/ a" A, e3 U* d$ z; a  @# n
  ?! @, h1 N4 v$ x7 N
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
5 `. w( G$ I/ O1 G: p; ]3 Z9 q4 y0 f0 c2 m
struct timer_list *timer_header = NULL;
7 {* @. o! d% ^; \6 ]" @( |
2 W/ \1 D" U- z$ _! z( E: \
, a- r8 F/ l( n: `% G2 ^) }void add_timer(unsigned short
- w  R' L  s' l. u2 Pjiffies,void (*callback)())
: m: ^. p& ?7 H8 l5 p
{
. e. y8 p! X1 u2 X0 Y+ f4 j% t; D
struct timer_list *ptmp;

2 @/ l. G' f! R( L7 R' E3 E( v" L1 {
/ E1 ]+ C5 W- S! L8 E! w- L0 M. ?* }
if(!callback)

9 e. j5 L4 q) Y- n% S$ D. ]& a
& O2 K& C: Y+ u' F7 l6 a2 mreturn ;

& o4 U+ k' T; P
& ^& e% o. P3 x& n3 G2 }) D
+ R% c/ \  Y- b7 \6 ^, }/ j+ S. g# m
. C3 w1 C$ Y% P6 N$ {
EA = 0;
; L$ f' H# T" G9 ~5 i: I

7 _. x: F; Q1 P: ^5 H$ _: N- k3 j, [! T
if(jiffies <= 0)
$ f' v  j; J( \/ E9 f! j; w7 t) N

- z1 R+ l5 L( ?4 @) T(*callback)();
5 s. s" i9 x' r

$ U+ [$ d) M8 U2 [& h

% M8 _$ @8 a$ h/ b2 b( w$ x; a8 A% v! W' y
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
1 O4 q2 o$ z' X* \2 @

' C! N( W# t" l( L5 P$ Iif(ptmp->callback == NULL)
( M2 _! R5 K! T; |0 l" i- y
6 T) n7 E- e! ]3 g! m
break;
% j9 h( \$ L. f; M# E6 r

) P, ?4 M5 |) k# {- y7 G1 b" b2 X8 s& Z/ l/ J' W% ~
$ e2 c# M4 t' [9 S
if(ptmp >= timer_list + TIMER_REQUESTS)
! N$ p' n& [' x- E# h! N
0 {, F7 K0 B2 G3 u% ?! t
{
  T4 I/ D, G0 P

: x/ R5 ^5 g3 Ygoto EXIT;

) S+ x9 b' n9 w# ~2 N
' L7 h" Q$ F/ B& W7 }2 n}

( x5 Y! d  S+ c& F. \9 Y" D' ?8 K$ q* D; _3 P2 u2 N- f5 W1 m8 Q
) m# u9 ^+ R( i& D4 o% Z& P' Q/ x
ptmp->jiffies = jiffies;

# ^$ P8 r% a. b/ @4 T" [0 u1 L7 Q5 s$ j8 z9 K. x! w; B& |
ptmp->callback = callback;

% Y, X4 ^' x3 D) e2 D/ D3 R9 f
2 m% Z* ~$ w- ?& b" d1 l

7 V9 o" _$ a) q0 s$ z7 \2 \2 l' ?7 x% L
ptmp->next = timer_header;

" y+ p! ?! V2 h$ ^9 \( d  H1 W5 ~3 Y% A' t% l9 L# ^
timer_header = ptmp;

: W; z4 ]& F1 Z' J9 e, N% [' y) _; G
( n; ~% _! h5 M' f3 i
//add bellow code to fix linux on timer’s bugs ++

! W: z6 p! F/ ], d$ M1 O( r
& `' E4 p4 J# ^, g" o  Y1 |: jif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
4 j' \# `5 i8 y' A* k

7 N' [; E: c" r: T" C{

/ f, J, Y; ]) [% ^5 W& n& x' q' f* h* u/ p$ t9 {
ptmp->next->jiffies -= ptmp->jiffies;

, F' {/ g6 H3 u# ~  x7 M
& s1 S- y$ E2 `# ~4 ]6 q2 y}//end ++

' R6 k/ n/ D0 F, P9 Z$ g( g' w# }
  T# N' `. G' ~( U% Z! d4 l% Felse

5 H5 G4 U! M5 L8 o* E. E2 h
* Y# e! f/ z: N) P8 \! P{
. v1 g6 t( V/ P  @+ d
0 f% {% d5 q, ^* U3 q
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
6 @( r7 W$ v- U! y- {. y6 y; {( }
" W' Y) o( O; O" d' J
$ A' M% Y9 G( ~9 g$ [) i
{

' l/ ^4 E% M& L/ t; m; O% Q) j3 W8 ~
' p9 X  o( }# h: ]4 nptmp->jiffies -= ptmp->next->jiffies;

% R' {8 N, d. \! a" k
1 `- l# s9 U, Z) acallback = ptmp->callback;

& d0 I, t8 |: k0 b) U, P" s; q! t4 f. }3 s/ A- `
ptmp->callback = ptmp->next->callback;
9 F* x* a+ G/ R0 m
! j/ m: R' Z9 n9 M
ptmp->next->callback = callback;

3 F$ a- @1 J5 H3 F2 z8 h5 N: v  n5 ?) O+ e& a9 d! W- V
jiffies = ptmp->jiffies;
5 I5 [* y! T- U+ V- G

3 K$ F5 ^. G8 ~% C, Pptmp->jiffies = ptmp->next->jiffies;

* V" E# C; Q- n  P
' ~" T, ]) [4 ?! P& dptmp->next->jiffies = jiffies;

: H. E# w$ s6 c( P* ]% J- |3 M/ m; w( t, q9 F0 l; T1 s! F
ptmp = ptmp->next;
1 @4 j0 V  w7 F' Q

/ j1 a/ x9 Q# ~9 ?, ?}

& @- ]- D' h/ ], N/ A* V' E. V  b; L
}

& `8 z+ {! [# }5 r0 h3 \6 h
" m1 A: C4 @1 X+ v5 K( w" mEXIT:
$ h8 V( i; A- g. k$ B& u# j& b! q/ l3 f% v& ]
EA = 1;
' L6 P0 P6 C; Q3 d4 {. p

$ f& K' d- o2 k% ~% Ereturn;

! M. x) E* g* W6 `5 o}
- J) g3 @% d) G. V+ ~4 H7 d7 K
4 m) ^$ z* Z7 vvoid do_timer(void)' ^) E1 d* I$ {8 j& T5 D8 ~
{: ?7 I: }, B( C

& g# a3 Y" X, v) k' G; ~$ i" _, R& r
( b0 n. n* b8 ewhile((timer_header != NULL)

/ x2 ]6 H0 w# u9 e2 S4 f6 U2 F
; w" e8 F2 ~' a4 C2 J- U
3 w; f4 C9 X9 K( n, f&&(timer_header->callback != NULL)

' x3 s1 p/ V6 f( T
, w8 L$ p6 f4 ?7 Q& @$ s, p' r( Y7 u; G% {% P3 |' x
&&(--timer_header->jiffies <= 0))
6 j/ @: j+ m. W+ h
7 v7 x' r9 m- G
{
/ t' q& [! z, U& P# f& ?; C

( e6 T5 I' j; \void (*callback_fptr)(void);

- E* k+ h, ~0 L4 E* L2 G; ^5 _  m1 I2 E

+ V# @! q# a) D4 S! {6 Q9 W- lcallback_fptr = timer_header->callback;

; N% Y, [* N: v2 e+ I# s' Q: t1 _+ G  M* M" X# m, X
timer_header->callback = NULL;

2 ^; b/ U5 g4 W, }. S/ w
" o( @8 @5 h5 x( E. Vtimer_header = timer_header->next;

0 D0 z" M4 B2 Q  h& u5 b% x4 A* n, R* ?1 H7 q
(*callback_fptr)();
* _" s4 V$ K; n6 S. b( u2 n! T, Q

* V. h, y. U0 p' L' E( k9 N}
" V: x9 y6 P/ K4 n! {! F) O+ m
# D3 @5 U! V: M2 l/ U% Y9 \
" l8 R8 g+ J1 y$ E- c
}
  C$ Q; _# z3 T: K% a8 h///////////////////////////////////////////////////1 M% @/ H: Q& L& {8 ?  K3 K
* ^: s/ v; ~) K/ W* E/ n# |
; ?; N3 z: P1 S8 j9 P
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
3 B6 b$ O# T/ M* _! J, a2 f0 D# J: t+ u, ^8 S6 R  n
野人献曝,博君一笑
3 P. m9 s' i& ~: n3 I
; T* K/ d1 ~. c, {8 ^, b! ~Peter' s* i5 C6 l9 C+ g0 K& N4 ]
  ( c! \5 o" j% d2 g2 j0 n
1 V/ S* Q, R8 e$ k
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-3-15 06:46 , Processed in 2.776529 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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