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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
  V, l8 s+ e' ?2 P8 q: v9 j) l

3 I! u1 r- O' {  {( ]- M1. Why need this mechanism) s+ `# V  h" N
8 o7 l# s5 F% o" [9 r3 v5 T; N
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
1 f4 U6 ~0 F+ y: d: T
4 P  v! J' Y$ s+ J
2. How to improve it?
! w5 f' q6 |2 N9 s8 W5 ^+ d
- T9 J* Z' `  q* |, Q" X/ [+ \6 z2 N; M  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code  c3 e8 }) H' y0 q

' p7 w; X% H8 m4 h! A//header file
2 Y+ |: z3 s* q+ |, B9 W% Y. K& H/////////////////////////////////////////////////
# t3 y- U4 y; n. p; k#ifndef% [, L+ n2 U4 u+ T6 d& e: J, j
OEM_TIMER_SERVICE__H

* \. S8 c9 m  [9 I3 F# c6 |#define
3 X3 m9 Z$ E# C" o: t) NOEM_TIMER_SERVIEC__H
5 }* H8 p. l. j4 |, V

2 r2 C6 R  Y. B/ w& t" r! h$ R. X# y% A3 J- d
void add_timer(unsigned short
: X, e/ x# |' M3 f4 j9 @% j# Qjiffies,void (*callback)());

# y- ?& V& d( }2 U6 p9 J$ c/ x$ D% t' {3 M6 i' q" M# Q4 D, Z- m
void do_timer(void);
4 |6 }( z. c/ t# M8 a: u' A
. O9 `6 i9 s4 D4 c' O1 g2 J#endif8 ^7 e7 J( t- `: ~
/////////////////////////////////////////////////( A) i1 H3 ]6 ?$ J
/////////////////////////////////////////////////0 u9 `7 E7 j: d! U. e* g
//impl file
& |- r2 _; r# `8 w& o#include <stdio.h>
8 Q7 T7 a" Y) ]- @( x, G( q#include "OEMTimerService.H") ?% V# d, l8 q

: X% N, @! n7 S' k7 @) k* S5 g) o: t: E& Z, u3 U( }
#define
/ {( ]# q+ S* P- \. O/ PTIMER_REQUESTS$ J8 x7 ~, I5 S: q/ [
0x30

3 K; H4 z, Y3 N
- g, h8 ]: q) ~8 o, Sstruct timer_list
! Z7 j# p, Z6 a! s# x{
5 w0 b8 k1 n6 @
- v3 ^% q+ O. R& sstruct timer_list *next;
2 d+ A* Z- M4 C; K: I0 ?' N! u; r

. S! O" B5 G0 uunsigned short jiffies;
* ]% _' P5 b6 a
/ K6 o$ Z% n- D- m; Y
void (*callback)(void);
" I$ _8 A, Q- F2 M, x5 I: x
};. \2 T1 a9 A8 J. c

2 F0 u$ j! a( _# [" E0 H$ S' x0 G1 m5 m  U/ t
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
6 k8 S4 L% Z: }: o2 V/ j7 d
6 H) d! d" v. x" kstruct timer_list *timer_header = NULL;
0 W) u5 i/ t2 R/ w7 E4 G) ?  I: h" v  E3 Y+ c: F
' ~* c& K& R5 F3 s* z
void add_timer(unsigned short% u% w$ H- J2 n* K( k
jiffies,void (*callback)())

+ x2 J7 K# ~, |$ I9 l0 s{0 Q3 l5 N' U3 t1 r5 _- D4 H

+ s! s% g3 N% I* jstruct timer_list *ptmp;
, v3 M+ p7 M8 c6 Q" {( G
6 m6 F, J6 }- n' p: o% W+ {
" w& q+ H: c# [* q: ?1 C1 k
if(!callback)

1 E; Y, }3 q3 l/ [5 i' |8 z+ d8 O& [9 u1 P' U5 M% J. l
return ;

+ j' Q4 C. X6 V$ K
6 I8 U: |% R9 q+ ^7 O
$ r) z. l3 E1 x1 i

% k# s; v; `- V2 ~" N0 NEA = 0;

! j3 t7 e$ z  N% b- r: q+ j' h6 `9 D% T* F1 w$ ]
) \0 X( T4 r2 @+ o- J1 |1 S
if(jiffies <= 0)
7 C( v) H, h( t) d

+ r5 |9 [; }# F(*callback)();
  w' i( S( h9 s0 T2 C
7 k; C8 i. d5 ~* h' C
: K* G, P& E5 f
' X6 w* Z/ X7 t8 g* k! g
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
1 [4 ?0 y6 S- d+ E5 ]4 Z

! N) Q" R/ M4 z6 i8 W, w( \if(ptmp->callback == NULL)
( O+ V2 Q1 p9 Q* \9 n3 D
% Z5 \+ U. a/ s7 k" O4 \. a
break;
( O2 O4 t" R. [6 w
! Q# p  z6 F+ r2 y3 ~5 O" R8 O% j4 s
' a( H2 u9 [/ T) Y" ]/ |5 R1 c

* q3 E, B% P$ Oif(ptmp >= timer_list + TIMER_REQUESTS)
1 S  {% a3 U. r  ^8 p2 V

- d. n  d- U& a$ b' r$ n) y) k{
5 `. i5 K0 p3 Y& I
* C% e, O! U% W2 \! l
goto EXIT;

* S8 \, c7 D( W! F, c* X
! n2 E3 `% \7 l3 c  _. @' L  I}
+ C' S) F; \9 p+ ~
% T. Y8 I0 H  H: B! m
8 R/ `! w! `( E9 |+ J- z( G3 B
ptmp->jiffies = jiffies;

  W0 }& v( x6 k
  {( v# `1 P  c: k8 dptmp->callback = callback;
0 B' |  Z2 q8 |; C
( C+ W/ x+ g& O+ D; y
' j' {$ V# r- H! B& {. p

: w  @4 a4 W8 x5 g+ ?+ N+ Y( L+ Yptmp->next = timer_header;

# O; N6 Q& D; \* E4 H9 i# Q
' O: k4 e$ a# }' [; etimer_header = ptmp;
9 q' k2 ^, Q: h+ o4 N# L

8 {7 a; V1 \" ]/ [* G4 T9 E2 ^
; W0 _! Y9 ?! t( y//add bellow code to fix linux on timer’s bugs ++

: y/ {* Y: y; o
  K* v8 v+ `0 B5 W  J; P1 e" [  Lif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
8 p* p& h  `6 `1 W1 |

" H6 e, Q, d$ \{
$ E4 S* n' h$ e: I7 E! ?! s
2 ~. Q) O1 Y9 \8 h6 k1 e
ptmp->next->jiffies -= ptmp->jiffies;
  {6 b, K  G+ ]: i- A7 q
$ j, N- c( a: h
}//end ++

+ X9 [8 y8 N' ]$ S1 |; y) M( i* a- j5 l* C9 [# r
else

; A. T- ]+ X- B4 r6 Z1 V8 a  s$ ~7 T4 L6 [/ h0 k5 G
{
# m$ z. G! C4 K. ?% `3 g( k

1 k- f/ S4 P. J7 P6 \0 Gwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
! i  L" y! {9 _9 @7 D$ j
* z/ i% s: |: j5 o4 [8 X

# W/ P( J+ C/ F& V% t{
1 b, O) g8 [4 u, E- M
. ~& a. E2 s; O! P' O3 r
ptmp->jiffies -= ptmp->next->jiffies;

8 z. i/ B$ P$ K( ~6 R  a2 {, U, Q& e
, w  o8 E0 @9 f; @callback = ptmp->callback;

& A7 c* q' }. F0 ]0 d
) @+ A1 L4 w3 l) {ptmp->callback = ptmp->next->callback;
! K7 f8 j. Q6 R) ^! ^. o) X" w

4 d) H# @8 I( u9 f6 c8 ?, ~ptmp->next->callback = callback;

- O5 n- P& O, O8 w2 S/ g( W2 J+ b) Y  Y; L+ l! q/ T5 O( d' q' D$ ]
jiffies = ptmp->jiffies;
9 M& ?" A- N3 e9 u3 ^, q2 ]0 C. y

" `* j- C4 k, u8 sptmp->jiffies = ptmp->next->jiffies;
3 g4 z0 V6 I7 ^6 i% i

! ]- ?% x0 c' Q* _ptmp->next->jiffies = jiffies;
& B6 l; |' `- @& P2 l: A- g

# ^0 w7 g1 y; R  Zptmp = ptmp->next;
4 b: x/ z0 @7 c  g9 j$ n" V! x, m6 R+ T7 K
6 @/ u0 k$ w' l0 T
}

* M2 ?* m* t: S% \
3 g: ]4 q1 q: r$ W$ U( g8 ?0 N- j}

' _, h: o% }! {6 r  p: _5 a9 }& i9 ^  t% t2 r; _" R
EXIT:/ |( o/ ^- M" b* ?  t
2 M5 W4 B: P7 ^! Q6 `
EA = 1;
# H# \1 v+ L& I. y0 R& |

7 y4 W, Z) Q7 h2 p  }; Ireturn;

* t  k8 Y( h- y" l5 {+ y}) P* d# ?9 R% f+ L( K3 ~+ z9 V
0 `% R7 ]/ c. R$ L9 k; \4 [8 k
void do_timer(void)
  Q! B" [$ u( T' [  Y{. C% |! a  O7 j8 F

5 U) \# n2 {; m0 G& a  d* d6 X, ?! l0 f( w+ O
while((timer_header != NULL)

/ g* z4 d+ J8 n2 A9 f- i
" D& k7 ]: [1 ?0 @2 e, Z
3 Y) p3 m# S* E% y: t3 R&&(timer_header->callback != NULL)

  a8 V! w" x; M. O% t# W$ c! C* @; D8 s
% Z* L! l) f# l
&&(--timer_header->jiffies <= 0))
% f6 [9 h! V- y) Q

6 ?. F( d! t; c9 Z2 g1 ]; w: b{

! A" [2 F$ q9 M* |
, `2 x8 A* c5 R, g+ yvoid (*callback_fptr)(void);

7 N2 w6 I9 k$ X5 Y- n
0 k, C9 a) }% f; ~
# E  [0 T# M' ~  Ucallback_fptr = timer_header->callback;

6 @$ `3 N- Y; W% ]" d: k7 _7 v% I9 y/ O0 m5 b
timer_header->callback = NULL;
( T: P( R3 a9 y* m' x
0 w3 J6 R  Q- z" L: a
timer_header = timer_header->next;
( _/ A; b4 V5 u) n; W
! w: P' x) y  `; Y- Q) y! |/ C
(*callback_fptr)();

* k' Z2 P6 |% c# @( f9 S( E+ f1 K6 y7 V
}

7 v9 ?. m, S0 D# Y: j2 N5 U8 w/ @' u; N7 C* }  `

+ c' h1 z  Y* X# M' Y/ d4 g}) A2 T' i/ L9 k& _8 p5 D$ k4 W
///////////////////////////////////////////////////- X1 u: B0 ~' j3 i3 M
0 V9 D2 S: m) K2 E" X/ H/ V
, a) f, X9 m; k8 S
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!1 n  O4 P% O) {/ \
( c- G+ p2 p6 W1 H* H
野人献曝,博君一笑# X. M- m4 e1 c' q7 o* }. y% H
* n) ?1 m# |- a% I% z
Peter
. r6 t" I  m% t* L' y; \  
8 g9 I  h7 ^% |$ N& ^4 e& z
! x- |: J& O) Z- ~  |[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-21 17:23 , Processed in 0.042210 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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