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

Smart Timing Mechanism

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

# {3 ^* ^. W9 v0 `. \  V
0 }& d$ T  p- z& F
1. Why need this mechanism' f' L- ]/ N) {% s

0 n' A6 U! z/ }3 F3 T! O5 O2 T# r
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

" K+ a+ X) |. }: S/ n: A2 x3 p1 ^4 }# {0 b3 z0 H0 t3 A2 u
2. How to improve it?4 c& {. V0 i* y. j! r( I- Z

- f% p( ^! ~7 F8 G! M+ v1 l) k  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
6 [8 @7 c0 w( U+ A/ e, s/ N+ _, ^  d/ ~' H9 \$ C0 W
//header file
9 G1 R: c( J' d% k" G/ z/////////////////////////////////////////////////9 S$ T3 Q- ~! O5 e# b! O$ {
#ifndef" X% P) f9 F3 {' n, k7 i2 [
OEM_TIMER_SERVICE__H
1 @8 M6 V* i6 F$ ~
#define; g: v5 S! I' d6 S1 \6 Z, F# J
OEM_TIMER_SERVIEC__H
$ [, \( R, J  P+ J7 p3 D3 n7 y

" |0 o- a4 w: K, ^: X' j- {
/ T0 u+ N8 U& i9 h% Svoid add_timer(unsigned short
1 W) ~1 e" {  y$ P0 D  u0 ]jiffies,void (*callback)());

! z; h2 `4 C9 l/ p- ^& F5 g0 L: e) x2 `4 z
void do_timer(void);
) N9 E  X. J: {& e: \- ^* h2 `; i+ y  r6 [6 H0 A' @( K
#endif% A$ }9 Z9 d! l4 N: }
/////////////////////////////////////////////////) C3 P- ~" A& @3 x: O5 C* [9 C
/////////////////////////////////////////////////$ B; \; @4 z+ e7 l) _% O
//impl file
, a: j+ I5 C3 q6 z$ \! i#include <stdio.h>1 J0 b8 O9 C: S
#include "OEMTimerService.H"
0 h( L, C: n2 {8 i% U8 L0 q. r' B) J0 j1 U' A% D
$ r6 z' v6 P( ?: J2 |( E
#define6 W/ p) d( j+ E4 n' |  S2 u" k
TIMER_REQUESTS; R5 U+ T* v8 P  U, o7 y4 D: l
0x30

4 y& p4 i% J4 }6 ^6 G. h! n+ A! c7 ?+ v+ j
struct timer_list ' T- D# y! [: J' d
{
9 d- h- l" Q7 U" V5 `2 w8 L& J, a: c1 S3 k4 s$ u4 E$ W
struct timer_list *next;
4 p3 r: W  O/ w) v
+ Q+ z% i7 F2 Z* y2 y7 k6 m, q7 O
unsigned short jiffies;
; I  _' R! `6 T; y

& G& t! G9 k$ ]void (*callback)(void);

! U  P8 F! w! u0 H0 z3 E) V6 F) `& h};# H) @( q% O; j& L+ A/ X6 @
8 O" u5 h1 r, \# S$ j

7 x: [4 P5 i, c+ f# b" O  tstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};5 s. f; z: I1 z. K1 `9 @2 W9 H  A  c

1 Q' O  B1 x# Z( t4 }struct timer_list *timer_header = NULL;2 \2 C9 S+ L# D+ R
: r7 O& z# X, o9 ~0 G
. K3 v- c" q0 \0 x- ~9 M+ K
void add_timer(unsigned short
/ P4 P- k8 q7 I, x! q0 A- ?jiffies,void (*callback)())

3 ~, `1 z) j( p- p- W" A{
3 Z8 f' ~9 U  p- o/ q' n! E: h- r* {. t7 R( B0 F
struct timer_list *ptmp;
6 Q# O# K2 w; |: ?

) ^2 r  D( u1 C3 z
2 s5 n/ e" A4 ]if(!callback)
0 `% a+ B! Q$ H, H0 `! u4 O. r
* k9 a. B2 f5 ~5 m, h/ b3 [( q
return ;
6 e: `; X5 ^; q2 p
5 s" n6 \; ~+ a5 F8 k5 @4 q1 T1 l

- K0 j, H2 E& F: B: ]; o  y  ^; E$ o: {) y
EA = 0;
, L: o3 C2 g% m5 H# y* s+ s
  B: c& w) Z5 B

" y* }* M: Q4 V* R- H1 Kif(jiffies <= 0)

. z" k; ^; {- J- k6 g% B$ A5 s! U& u9 _- Y' k8 g1 ?/ V7 Q
(*callback)();
: m  a% v1 A) U/ L  F

/ U8 a( q6 J8 @$ e6 M
/ S+ k) Q, p* u- i# W6 U( e2 H

: \( s: J. ?  y' {3 f  Xfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

1 o- I4 ^4 b1 T: C* i
" B1 D* X! h. }- j5 Oif(ptmp->callback == NULL)

& G: _9 ~- r! _) _* G+ H& h4 C: g: t/ X0 U8 [2 J2 V: R. @
break;

7 V) M4 y- B4 O% m, ^& s9 S
$ {8 f: v3 ]/ Q  W% z/ O  i: @* c$ A8 O# u

) Y$ v" L$ H0 {  J/ \$ p- O  H/ Eif(ptmp >= timer_list + TIMER_REQUESTS)
" e5 k  ^9 c; F# z
: k2 K+ S5 |5 u$ a& t- _0 W: H
{
9 {4 q  f% d1 j% J0 C' L
5 u% ?$ ^7 v7 ]2 y0 m6 e$ Q
goto EXIT;

' G3 y5 m/ K, v# A) Q0 {; q  @  C5 ?( t% f
}
! r7 |, u% r$ Q  T/ b) A) D& G

" q2 ]! Q- Q( v8 c- q
, I1 O+ {! l0 P6 vptmp->jiffies = jiffies;
: a, n. V: S& N# j2 @& x

% Y' [' B" h8 c( E2 G9 U! Sptmp->callback = callback;

% ^( z% q, P3 s, ?# }, M1 u2 G0 n8 Z! c& B. O
- l2 t- s$ n4 T+ @7 ~- z; x
; G' |* s9 Z3 L( P
ptmp->next = timer_header;
5 L: p; u! N3 b2 F; A  p: ^; f
' j( x) ?: H/ G
timer_header = ptmp;

) W6 O0 t  s' y0 E. F# g
8 Y) I# U& X$ w( ]6 K
* `! `; Z4 F$ f//add bellow code to fix linux on timer’s bugs ++

2 w3 r  W! @/ x; `) {1 u9 [9 C6 u" r8 j  L. k. T+ O. F1 P+ ^5 h
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

6 w4 p" |1 w5 M+ r( T
/ H6 I& _+ r& T: r{

, u5 I* Y+ j5 Q, b5 p4 G& I" S( ], l+ T0 O, ]. x3 i) n, V
ptmp->next->jiffies -= ptmp->jiffies;
+ j- ~! W! Q& X/ \
' W8 g; \# z! S: L8 B, d
}//end ++
+ m3 P* {  g4 T7 q$ V' K9 U

3 m0 _8 u' E# ]+ j' e, Uelse

7 r0 [- V, p+ n  |. j
* i  o7 p: _! N0 m. c{
( N% I2 E. s, S7 r: Z
0 Y' p9 ?4 a- b
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))  N* F' @" J: Y9 P

+ r4 W# P0 {- }. v! Q  ?' l5 q4 t4 D: `+ K0 C
{
2 }; ~# H2 I  a# f. Y: T# J
1 p9 P1 b  ^( W4 V
ptmp->jiffies -= ptmp->next->jiffies;
: s5 M5 k9 N: B# J  _  P" D0 K8 h5 J9 D
5 ]' \1 N. W! ]( R: @4 y6 P6 B
callback = ptmp->callback;

' _5 Q* @* c" j# m2 c0 O3 b* L, U4 B" P0 L+ a# f
ptmp->callback = ptmp->next->callback;
! k' |7 W* |. P' ?# V) p
  \2 e9 d9 o3 {7 d) }. J- S  j  A6 l
ptmp->next->callback = callback;

5 \3 S' ~" p- V; U& U/ ~, w9 l& ~
: Z- Q/ v. ]+ djiffies = ptmp->jiffies;

& |* T" E- N$ ^' e; I) {4 ~% D+ `# n' ^
ptmp->jiffies = ptmp->next->jiffies;

4 S. A% }, u; W. u* ~7 Y  f5 A+ b$ e1 i# E
ptmp->next->jiffies = jiffies;

- I3 r* r0 [" b( q  e) Q1 b: i2 w" V$ z3 ]  X/ V2 b* m! G/ N3 f4 R
ptmp = ptmp->next;
% p: k4 ~) a$ q" p9 h5 C
9 G0 `! W5 i1 d8 q0 c- j
}

- O) m) q" B9 k4 R  d0 a
+ c) T$ ?( j8 d2 i, v}
) o$ X% K7 Y3 w6 {8 q3 ]

8 u% x, j0 ]% q  [* x7 K6 G  z% [0 eEXIT:# a" ^/ D5 ?& c6 P. J! P2 B& K
  s: e" x# f8 u8 {, a/ ~7 F
EA = 1;

1 Y" V: Y8 C9 ?: f3 q3 y5 q, Q: U. p. z- J6 o
return;

; n; B1 \; R- s" @2 ]3 e" u}! o" g: r, ], N/ ^

' D' K6 O" L4 q9 J' Y  lvoid do_timer(void)
; v1 b) d. {' U* v+ j{$ e7 i9 J  x6 a9 ~7 f) ]
) u6 |6 k! b6 L0 b) B3 f: n( g
* @# O: h2 t' u  [5 n7 v# f
while((timer_header != NULL)
9 b6 M; h6 u# P. ]5 O

9 {* N2 E9 d: X3 W8 \  }: N; s8 e9 i2 y  D. n% @4 p7 M3 r, P
&&(timer_header->callback != NULL)
2 C$ _9 T, b' W
  ^4 c) j+ Q; z/ k; K$ G; e3 ]

2 X% m- ~3 E$ n+ x# C8 V+ ?" F&&(--timer_header->jiffies <= 0))
! y* E3 a2 E, a" {0 `1 }3 f
/ {# r6 A* I1 Z
{

+ G: h' @5 F% g. P
# \. o" }* M  Y6 y: ?1 evoid (*callback_fptr)(void);

% C% f/ [+ P! x! w7 N- u# M; T% \7 d1 Z' i, F* U

, q/ L" N$ N: D* N1 Tcallback_fptr = timer_header->callback;

$ ~. ^8 [) |! ^, X$ J. y5 a4 x# ]/ K* q: ?' W8 y
timer_header->callback = NULL;

; u1 i$ c2 ^6 P. d; }) f& B$ N0 f9 t4 ^; O
timer_header = timer_header->next;
$ A# ]4 |5 n% }
$ H+ l9 e# S, ?% ^! T
(*callback_fptr)();

8 z( _1 \; C& ^1 l8 Y4 K4 i& ]) W8 X& z+ U7 ?' j4 t4 X
}

! p3 W" L$ [8 y8 ?' \6 s% ?7 B  W' Y
2 i9 t0 v6 T6 e! Y8 [
}
& r1 O! ^7 Q, s7 |$ K///////////////////////////////////////////////////
( P6 P! |; d* S+ t! F- L) [) q- U! y& J+ B. s% f8 |

) Y* V0 ~/ \  Z6 [3 x$ o; M上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!# p0 J) x: m) S
" y. J, F- n5 }
野人献曝,博君一笑
! l2 }' J/ Q# b. r0 c9 E/ n3 Z, w/ w
: e" l0 o+ n) MPeter
' r: Z/ l9 M' C0 `0 ~$ i- r1 ?  
, c. B% p* v# {) r; G* k
( N% ]( f8 i% N/ d$ B: o[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-2-19 05:57 , Processed in 0.096888 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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