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

Smart Timing Mechanism

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

7 Q5 Y9 j) x3 U2 K! m- D; M

' N4 z/ w) u* M: X1. Why need this mechanism' W3 z( F& g6 x
% ~1 b5 t0 v* Z1 u2 m5 y
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
: d3 g: p& E" Z$ f6 W# g' A
5 K; u% F/ D8 Y% \1 w' Q  l% R
2. How to improve it?
( `1 a+ a) x+ D3 p' Y: `$ E
, Q0 p. z9 @2 A5 k  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
5 p- K* c, u* f  R0 @6 w7 l" Z  j8 z. p
//header file
* p  [; T- D8 A2 j- x- k/////////////////////////////////////////////////+ ]! Z. K7 |$ g' y3 O$ Y, j
#ifndef1 _( K2 d% |$ l- Q' G( N
OEM_TIMER_SERVICE__H
; C) P; e0 T2 B
#define
" M6 J* f; F3 F4 s' I1 q* _OEM_TIMER_SERVIEC__H
; ^2 M; ~# X+ x- z0 _% w

7 _6 a0 n1 L, Q, g3 z0 m. e. }: M
6 d; j& n3 I9 B# T5 l7 o# B! Q3 kvoid add_timer(unsigned short7 m6 Q( c# |9 ]! e* ~, w6 y/ p
jiffies,void (*callback)());
  b* U9 [  E6 M' l: y  D
4 O  K3 ^* j' p' t2 R, p  g
void do_timer(void);" H+ [6 M/ ^! U% w5 ]$ e0 F
4 `4 a+ o2 B" s" O% F1 w" U) r. y
#endif- G# b: X% S( E1 [" P  |: K* L! n. L
/////////////////////////////////////////////////8 a6 m% h& n2 u* P( m0 T
/////////////////////////////////////////////////
, s. H+ [. [2 ^0 [; o/ g5 M//impl file! x  x% Q7 |* v! c/ f, n
#include <stdio.h>, _, i  H- i% e
#include "OEMTimerService.H"
$ e; s. }2 N3 x
0 J$ y  U0 ]5 r% j# D; ]- u/ u' u. U
#define- ^5 _' }+ v4 v' n7 m4 L
TIMER_REQUESTS- X1 Y5 h1 `6 t- m
0x30

! S2 X$ U1 g" S/ e
6 Q! I0 ]3 U& A3 M* g. `9 q+ ~struct timer_list $ U6 o7 ]) ?, o! s: e5 N7 x
{
0 ~8 q9 r8 \! t2 G0 B8 r: a% p, u+ @
( o  M+ B) ?3 {  c, I0 C* Istruct timer_list *next;
9 B1 v. C2 K8 ~# g1 o- S
0 R5 f+ ^# |) D& T
unsigned short jiffies;

! i, I$ I& W$ k6 y
/ P9 a3 R9 u' Pvoid (*callback)(void);

# _$ d2 o8 V9 d( C3 F& g! w};/ m  ^" D# r& s9 _
2 s/ X2 y+ p# V' K( L* _3 ^
8 G3 E+ B8 B+ _4 P: W& y2 Q
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};; H4 g, X6 b: P3 Q

; w' O9 {& [) Z1 X; E- S) U3 N* pstruct timer_list *timer_header = NULL;9 w, V; }( ^/ j4 l% c! ?1 V
1 K2 B4 s2 \  ?! h' }
+ A- R4 M4 {0 y, l+ U9 h5 Z/ l
void add_timer(unsigned short6 j$ j4 n( `6 Y6 f' p( G
jiffies,void (*callback)())
+ z3 i0 |) H# G1 \5 L% n) x
{
5 l" x/ r' o1 N5 ?
0 h  s" R, H4 n" Q- j. `" I, Y6 qstruct timer_list *ptmp;

3 D% V, b7 h# D: W6 y- ~8 ^& l  z& A
7 G8 A; J8 A2 o$ s
if(!callback)
$ u- a; A- h4 V+ o1 b9 P3 r' w
/ O4 c9 ^9 s4 q4 D, `
return ;

% s7 r' c) d5 W, y1 y8 x+ C  F+ c7 X# O+ E- @2 a

, [# g1 ~( U) n7 S  \
- |7 H7 ?- x9 |, k0 QEA = 0;

; b" L) m" x/ ~3 G! z
2 z6 F2 K6 w5 t' L& K! ]
/ |. \: f, |3 J: c4 w$ pif(jiffies <= 0)
  |% [) J3 I( @! T/ F$ S+ X

. F$ K. i0 @9 I2 x* r8 A8 K(*callback)();
8 o; r: R) h; y* \" v' e9 g; ^* E
/ P0 u1 R- R3 ?. E* b: ]% H, C

0 F; E4 b9 ^4 K3 E; m! e( ^
7 d" a3 @( G' G% l4 ]' F0 J4 dfor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

- w! |$ M$ B& n' D) z
$ L5 U. k) l. [0 v1 `* H" h/ r& gif(ptmp->callback == NULL)
4 z7 y+ @3 n" Q2 C" D$ m, J
+ j8 }! C& j9 L! c  L% a
break;
$ ?2 {9 \$ {) m9 D* [. k
& m. u6 n$ h$ j) h

% D; H' ?' g( Y5 _$ L4 |3 [3 e, x  D( ~0 W$ R" t; a5 a
if(ptmp >= timer_list + TIMER_REQUESTS)
9 t8 j9 D& Y( V- E; p

/ D) S0 O$ t& K# c& A) I{

9 G! f& V; [5 C' A+ T1 d7 X$ P9 N5 |& D5 r* d
goto EXIT;
( p* \5 K3 O' `' Q

5 E2 C- y, D: ~9 E6 A5 n( v) E) G}
9 M3 b5 |2 O* Q
( T! [+ Q" }$ h( X6 P

$ l9 O2 R) B+ I) K0 T7 _ptmp->jiffies = jiffies;

, D( e$ z) A# A2 ]8 {1 ^0 {) ^, i/ N
ptmp->callback = callback;

) s* z3 V1 C# |* _, O# _1 h
/ J& A( V/ Q. e5 L4 t6 }$ A

6 q% Z3 o4 w2 j
% F+ R% b! X+ |9 Y0 uptmp->next = timer_header;
5 G. [% r+ d" E( w; G/ L

$ X0 S! V& L3 D' q+ ^timer_header = ptmp;
! l3 h4 T# g/ P. O5 P' }% \# H

0 r; a3 K! N" {' ^3 g4 d& X  B: ?# x5 P! y: C4 M* b0 J
//add bellow code to fix linux on timer’s bugs ++
: T- k; m* O  H. G
; x$ g' @& R. }) x, K
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
. [! j3 [- V  o* E

- y' @  [! m0 @' A; U" L5 \7 H{
# U- U. S. w0 |: O/ q1 Z

4 c) N6 m. o: n- Y- ~ptmp->next->jiffies -= ptmp->jiffies;

- b$ L7 S4 H/ l6 j. J9 z! b; L7 c" B6 Y: U5 K
}//end ++
6 V; T7 e- S) `5 g: s! _

- @# W5 p% Y' a1 ^1 ^else
& e$ n" f% l# N! f1 ?6 B4 R1 h6 i& u' a

( @: j, B7 u* A9 S5 G* O{

5 N& h. z: o; e0 T7 K9 h
! u# d& Z" Y7 E, L$ _* I, j% Twhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
9 t7 |' {: E. A( L. k
: Y* D4 u! f( T
% f+ {7 j" h0 e! a2 c
{

: b0 w6 _3 d- X9 g( @3 A" U% Y6 }( g+ x  j5 D( L. l: c
ptmp->jiffies -= ptmp->next->jiffies;

* R/ P, \! x& f7 \4 Q& s6 `: |/ A! |5 V4 U" X5 j+ Z7 t
callback = ptmp->callback;
: c/ z8 ?& P- X* A7 f8 P3 G

! ?, Y9 E7 h" Q$ ~$ {, [ptmp->callback = ptmp->next->callback;

6 E1 W0 `# V3 y" R! n; x% Y- ~; F/ P4 C1 F' l: H9 {/ @3 Q
ptmp->next->callback = callback;
% _# R& j; g. D( K
6 ^& x  p0 a3 z' ^3 ^& M: i
jiffies = ptmp->jiffies;
1 J& v, T) @( u0 l# A; D  z2 h, m  S/ F
  N7 C5 c  J) O( P/ g; \
ptmp->jiffies = ptmp->next->jiffies;

* n2 x. h- T+ z0 l) q: I. J% ?* _
4 v, E% K, x+ H* v' S9 G8 n. kptmp->next->jiffies = jiffies;
3 d* Z! f. l3 S3 M* E+ f+ U
0 y1 \% V! V. Z4 F4 ]( ~" N0 h* n
ptmp = ptmp->next;

7 z# g: W, C7 ~5 ]4 Q/ z" \, a7 k6 |3 z, M4 i2 w
}
" ^# v; _* P8 L' }2 H' W3 u

1 C: k% ]3 o9 B8 ]$ V* p9 l}
6 x# Z  k" j. t" S- T' G" R2 p

6 i2 i1 x5 z% k, x$ k1 a8 YEXIT:/ [8 p- t' }" u0 E

5 u$ k2 Y; m; L8 A" t9 FEA = 1;

0 d: P1 K5 k7 w! ]$ x  F' x, [( N6 d  J' u- z
return;
/ ^6 g7 l1 S+ u, h6 x
}
- a' L/ E' r( p% }
5 X! P% i, w7 Q  Z( F& zvoid do_timer(void)
. q# M1 q# m( x' D5 Y8 w  s. y4 r{
; x* f9 A! I: A
. J2 c/ T" s9 m7 F* w! ^+ S$ H
- |4 {; q) p$ _3 h8 t" V5 c
while((timer_header != NULL)
) Z: ^# D0 T- ~1 W9 Z

$ [( h5 X0 ~2 C. o8 U5 @0 `% `; G+ i8 [* H+ a3 f3 m
&&(timer_header->callback != NULL)
3 E( M8 ?% P  H* j' A0 o
" _. D5 `, ~$ F( U9 L* {& x
# v' u4 A3 q- X0 y" d% u* @- C
&&(--timer_header->jiffies <= 0))
' d) d# z; t& ?" N( P( Q

9 \# A9 r4 Z# j% B& u- ^$ M. V" b{

6 ]9 A) M" N( N# U
! x( ]% E" j! C$ k0 y# X; |3 @void (*callback_fptr)(void);
0 P9 j- d6 C3 Z: u
  B1 L- g/ w; u* v7 C$ r

* d: v' p' g6 B3 b8 q2 b2 N' Ycallback_fptr = timer_header->callback;
/ g! K' y" d  y

3 D5 B4 S  y5 @) i' jtimer_header->callback = NULL;

$ l' d" C6 t+ r( @
* }( B% K, v3 M0 C7 Etimer_header = timer_header->next;
$ U/ q3 v! o( I6 o8 _" @% `# _
  M- ?) ^$ R9 Z1 D) s! l- A
(*callback_fptr)();
, e8 a6 L4 y  L2 v

5 d/ g- e. ^4 r. v0 W}

- n3 b0 E& E9 F3 p4 c
$ E8 h) Y% m$ q6 P" ?
3 E- P2 q. X9 Q+ n  ^' y& H; c; K
}+ g& |5 g' m0 e$ u0 O( @
///////////////////////////////////////////////////
8 I6 S1 e- r# h; x" \5 e4 c& D/ d- S  M9 k& T

9 ~: o9 a! {, O, k上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!  o2 ^" c" a0 f6 d
3 r% z. W! e) E0 c3 [
野人献曝,博君一笑! R: `4 f# v: K  p7 ^' p4 s

/ |' ~; I7 ?* O( i1 ePeter, s$ Y  }1 N6 ^$ z: ~: K1 c
  
, m8 V* r2 L2 v) d' k
# Y+ M9 N3 Y; O+ p[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-8 08:22 , Processed in 1.696610 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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