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

Smart Timing Mechanism

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

- `' ~; `: p, V7 E0 ?8 _' Z

8 [- @! x; |' f% G$ [! Q7 l5 J1. Why need this mechanism
' b0 Z  y+ @$ b$ e( E. A- l
2 x: v8 M# O. ~' u
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

) t, _9 e$ e9 Y. D/ U/ S
4 v8 }* C& v6 F2 f7 u) Y* z7 u9 z2. How to improve it?6 d* W9 a5 V$ t: }: s' d

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

5 Q5 T, a( Y; O2 w//header file
* \& |, E" F) [/////////////////////////////////////////////////
3 {( Q" y8 D. Y1 O9 ?( k#ifndef- A+ S4 Z% S' q
OEM_TIMER_SERVICE__H

( ?, b* ^7 l7 ~* ]#define6 t% Z& y% x. i+ J* {1 n" X
OEM_TIMER_SERVIEC__H
3 \5 }2 V$ Z8 r7 _5 Z( U
8 h( g1 o9 E/ T- b: v5 i. b! q2 T
& k1 w) t* C7 y9 k$ O
void add_timer(unsigned short8 H1 s( o) C+ k6 p0 C( }- M3 U
jiffies,void (*callback)());
; I+ Y! P7 [4 L. i! a5 j+ r+ G4 f

" F9 h* x0 E% o9 d' tvoid do_timer(void);
/ \+ l' ~, Y/ I0 J0 Q2 J7 q6 q# ~- x4 ?
#endif
. F9 o4 w# u9 h: F' r- G/////////////////////////////////////////////////' s- Z+ ]9 {: u* ^" ~& M" \5 O
/////////////////////////////////////////////////, b; o+ x  Y8 t& Q4 R! d3 U  N
//impl file" _# C2 C2 c8 w4 k# G7 \& S# v
#include <stdio.h>7 p7 u5 s" m' A. z( [1 _
#include "OEMTimerService.H"
4 `& }# N% F' u3 I% V8 N0 I0 \$ N1 x$ [+ d+ `% j$ ~
5 F: e/ `! u( _- F4 C) i
#define
4 _1 e  y4 j+ L" q% ITIMER_REQUESTS
0 }% F5 J$ l& y0x30
# e, x+ e+ n/ ]- a5 v
& K/ f0 C# ?3 z7 c' w0 z
struct timer_list $ b, Z3 m* I$ S; X9 ?
{
0 r6 G/ W* N. v7 g6 L3 @
$ S* Y* h; |8 k( U7 b( D; Y7 e5 kstruct timer_list *next;

2 z: A0 O, i. d6 C  y0 X
8 ?- H+ h) d6 q$ }unsigned short jiffies;
6 h1 A" p* k* g% H- {

4 s* i- p3 ^4 c( m; {7 o) ^5 zvoid (*callback)(void);
7 ?' M# E) f$ _$ s2 H; E; G
};
& A  D! V1 w3 v, {6 Q7 G! I! d/ p2 F: N% i, a

& S% n/ S) j# H4 b" @* lstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
8 E$ B7 w' j, M$ x* p" z
/ L0 v( }$ c" P" rstruct timer_list *timer_header = NULL;
6 i0 ^1 b2 P, r% X; e) m
9 K& N- L1 ]) d. X0 ~5 J$ |- E* T% g& J! D4 X6 N0 ~
void add_timer(unsigned short5 L, f: x7 \: a8 ~
jiffies,void (*callback)())

: t1 _/ Q6 c7 a& H& |7 J2 C{. U6 y, E+ J! \. {
4 J& K* c# W( W  L% q
struct timer_list *ptmp;
9 U# _" q1 N" b3 {! Q, e* Q! Y: h
8 C. [% z$ L  H) D* |0 Z

$ f0 Z# v3 f& Z& X6 ?; J. fif(!callback)
( e- n" h- E5 c& w& g" K& `' }& d5 N

( |5 C+ _8 w2 Ireturn ;

- d, u2 g6 Q+ |2 S; d
6 p/ y+ n. g! w+ A7 `2 `6 q
. g8 j/ Q" u; c- p7 z

  g) M0 |2 c# Y; a  K9 s. vEA = 0;
: N; R% L, T# x
0 B& C8 j0 a2 ^, L

( x. p# [: U8 rif(jiffies <= 0)

0 f6 @8 U: ~! u+ a6 z6 q; K. _* |! O5 S" y2 y
(*callback)();

5 u$ K6 B- ?6 o( b; D: ]
. p2 o; h; G% U2 b9 W

% [9 K, q% v. r$ z! k9 W, ~2 f* I  M) V
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

$ \* e: E& `4 ?5 k8 P2 ]) r/ \: B6 U
if(ptmp->callback == NULL)
" F  J. v3 K; Z, O+ ]  S0 m

7 ]  Z% A& }1 N# d- y. Cbreak;

# b9 {, H" m9 j: B/ X8 U% D4 g, Y  l" }/ q  w# g

$ G1 r) z8 \. J3 L3 Z; U7 F& x
  ~  y; A7 y9 b+ U) z5 Gif(ptmp >= timer_list + TIMER_REQUESTS)

4 [) y% D. t$ s8 T! K7 B
: G/ Q9 Y' ?  R{
( X& \7 _+ `! |8 M- ^. A5 q$ t6 r
2 |6 H+ ^+ |9 ^2 ]% ^# B6 {, I# G
goto EXIT;
7 ?& Q. A) X# q4 y' D9 @' z  K

( [: `  T! N3 h8 k9 Z}
: _, c3 h% R  o) ]/ ~. u% l

/ g4 x* B$ Y: w/ ^
& A) X7 ~  I$ e; Iptmp->jiffies = jiffies;

$ J$ ]5 i" e& G1 F/ n0 ]9 b
) K, w4 ~  X' C5 R9 g9 b2 O, k9 gptmp->callback = callback;

/ b  v; Q  @  {) U* U1 ]" O+ R+ H( S7 U. g" l# |
0 X9 ]7 n# V/ H/ \7 b: ]

. @4 P1 ?8 K( S, x! eptmp->next = timer_header;
4 r1 V3 W+ `. w

* ^. q4 |) P$ L! A# btimer_header = ptmp;

( Y5 e# _; |1 r+ b7 M/ r5 y
/ v3 R; I. ~' S$ k" a; W9 I" y8 f
//add bellow code to fix linux on timer’s bugs ++

: b& D$ l- I# o& k7 L& v/ w. F( m! b" r! j; ]
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
6 d6 v4 h9 J4 E: F# r7 A
  H- A/ |/ z! j
{
( }2 L, V- M5 d! {7 A& S
0 u8 \* W7 f4 N# l% z5 i$ \5 D
ptmp->next->jiffies -= ptmp->jiffies;
+ e. f$ {& ^, b( y  L; }
, F6 `# Q9 D" T# S! O4 T
}//end ++
3 X- @5 \9 X) |( x
+ f# T2 @" u, N1 j- s) I7 A
else
& H5 x& |) @- n% h1 p: G0 u9 q7 o

* V  ]; H: Z$ W! ~{

. K5 B5 W! b! l$ M+ i6 z% g0 x- {# L( f9 K7 U5 J
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
2 l0 k3 ]# L7 ~4 X& K$ l

% c: a6 N5 j1 l! J$ d) O! o9 S: ]( g4 N3 m# [* e4 A* I
{

4 ]$ q/ a0 G+ w$ I
, o. h( T7 t# E/ I- u# F2 ?ptmp->jiffies -= ptmp->next->jiffies;

+ l; K2 f* J7 _/ X0 ^/ w/ a2 F0 }4 ]6 d: f9 g/ w' u: B0 Y; c1 v
callback = ptmp->callback;
1 `3 z, r9 x# f, N" Y% w
9 ?) `" {' p3 t' B. Q  W1 _6 {  H
ptmp->callback = ptmp->next->callback;

6 r# Y. \7 V: P  g  k
: M$ G4 m4 G/ p" D& s0 ?+ Nptmp->next->callback = callback;
: ~6 ?8 u3 e5 R' [) m
+ s+ r) d- w  K9 H1 ]( e
jiffies = ptmp->jiffies;

3 t- B+ U& |5 |  D% L; x/ j$ Z% }) p9 U' J9 q& {$ H
ptmp->jiffies = ptmp->next->jiffies;
$ \' {+ n, Y& u$ @8 l& I+ r
  `( a7 f6 v4 k7 w) K5 w; y
ptmp->next->jiffies = jiffies;
* b! q1 _0 \: _. g0 I- C9 E/ b

& s- E: \% p! P, u6 ?. t5 pptmp = ptmp->next;
0 [, n! p  F0 n

( ^/ g2 y& F" |' Q}

8 e- y) f% }2 Z$ H3 X1 w2 }* s1 B1 [/ r- ^# K# d9 @4 u
}
* g5 K5 q9 ~+ N6 _  Q9 `, y& `
+ V7 e/ E3 u3 H2 l. N9 a
EXIT:) N" s# B+ y4 N' c/ V1 R

; K! R# ~4 k6 K! D3 F" v& L7 tEA = 1;

0 E- h! j) H# w% W3 c/ X$ K# d( F1 S& E: T7 n- e4 y& U
return;
1 y; C, M4 M9 }3 r# ^$ K) g
}
( c+ q0 K( r, B& c1 Y1 u
# v7 Z& [9 r0 s. Yvoid do_timer(void)
3 q5 g! ]/ U: |. Z8 U{
, p. o0 j. @/ o/ G+ m5 l7 [3 h

2 s0 h7 M* e+ x, ^- Q$ R
! ~$ N6 P7 H& j7 x, _  vwhile((timer_header != NULL)

8 X1 u; T2 W6 o0 s8 r2 i+ m: p7 Q" l9 n2 Y
( A. L' j9 h* ^0 k/ _# v" S
&&(timer_header->callback != NULL)
; x0 O# F+ R' [6 `2 U
7 {" f2 Z( y% z: r

' F6 [$ D3 `0 t6 f- ^&&(--timer_header->jiffies <= 0))
" V; n6 o; P) f- J: N
% N* P& [" }1 c
{
) |* \: N$ M4 ]5 F
- O  B% s2 R% ^3 S2 A& A
void (*callback_fptr)(void);
9 s" b. X' t& Z% c- W

$ M1 i  V* T9 S! M. f) {- o2 _" {2 p- R. k, |; b0 i
callback_fptr = timer_header->callback;
. G  e& W' t5 [! v
1 n4 r3 a% M6 f: m) U
timer_header->callback = NULL;
: Q/ u3 m5 P  @
# [0 h2 e4 o3 C2 C2 y. Q
timer_header = timer_header->next;
% f) Y. Z7 ~# b7 R; T% S
3 n% O: B5 o7 I+ p0 u8 o
(*callback_fptr)();

4 A0 k0 `, c0 D
9 u- [% Q( N0 D) j% a}

& L' y5 s. H3 {3 }2 i* g: ?4 U4 h" U
1 K  D: o$ l6 }0 a" n: V
}7 C9 J: y& Y) |
///////////////////////////////////////////////////8 Z. j" W; d* c
* w" i& e" r3 J; D% _: X, p
6 D3 `5 [* S6 G5 Y0 Y
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
& O) g' m6 `: T* v; ^; b4 ^0 m  b; O5 N
野人献曝,博君一笑- ]. u8 |' S' t4 u, t7 p5 x
* G9 e- G4 }$ x* b1 c! D, Z
Peter
3 E# c% Q1 v2 j0 X* h  u, H7 L2 B  & ~* E* m+ n1 T

/ D" J, t) F0 H  H& X& A9 ?[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-29 04:07 , Processed in 2.022854 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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