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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
. z* I/ L8 d) |0 a+ [

; {: l2 Q: t9 T: S* t0 L& a1. Why need this mechanism
6 b! Z2 ~8 C* S% j" _9 z- d/ j$ s: n6 F' I6 e5 G
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
4 o( W! W2 z0 Q
$ N2 |/ n! |7 c! t( v4 e' p) Q
2. How to improve it?3 A$ q4 X' f; E. h' W
7 Q8 l5 @' w: v: r
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
, M- a, Y  i0 p1 h* x1 c" A, i9 b5 H" v7 X
//header file
3 ^& y  R6 U* D, D/////////////////////////////////////////////////
3 J/ ^( j! w. H& w7 \#ifndef! i) M& q0 ]" X% v, T
OEM_TIMER_SERVICE__H
: P# M, e5 z: V+ M1 {( I3 {$ a% \
#define
7 q* F. ]" J" I2 y; wOEM_TIMER_SERVIEC__H
  `& w+ H$ C" h2 Z4 h! U% O
6 F$ H" D8 u9 |6 d) i, s

4 b  v+ \- ^) Z$ c1 ?2 Gvoid add_timer(unsigned short
1 [$ z4 V; }% C! d# _- Zjiffies,void (*callback)());

& n1 A) k$ m+ C6 Q- ~$ w# V0 v( w  c( k7 e2 e
void do_timer(void);
& t  z& Z% V3 r  U$ ]6 {' Z1 X" @# u) W% N* ?! j
#endif, [, U' y+ U- m) ~. t: H# h
/////////////////////////////////////////////////. Q5 a' R2 M9 F: W; c8 F
/////////////////////////////////////////////////. i) L& l" i: N- n
//impl file
' C, I/ S& |9 I3 G" R  }#include <stdio.h>9 [. Z* c- `& n  n3 b& z# e8 j
#include "OEMTimerService.H"& Y: ]9 O3 ~, h! w. s  o. @
0 L9 c- W% G( j- J7 ~0 Z3 [( T

+ ?+ I7 z8 [. x. I#define
: g% M1 z5 l$ g, p$ iTIMER_REQUESTS
7 ^9 e$ e6 U3 }% V, N/ h# t0x30

5 u, |# L4 h- v* ~% a. l1 K" y; X1 [0 ?+ ^, v
struct timer_list
3 X8 h" J! A: ^- k) O; F! y( Q. z{* [# r- T8 F1 M) P  E5 y

+ S' D6 s$ a, K( S& Mstruct timer_list *next;
, B# a& k. n( {& T
3 K) C- ^" @4 l& C& f7 i( {6 i
unsigned short jiffies;
  `& {% n  ^& C: N

' M% q* N. U- g, [, U: ~: q' Wvoid (*callback)(void);
* @. K9 }) n  m# w% N
};
5 G7 c$ y; o3 p! \
9 Z  E' @# X0 v( |. k+ Z6 x  a" R6 N- x& o9 q. k
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};- s- h* N. Y0 x8 E# G) Y

7 _1 G9 r# b* F# p  ustruct timer_list *timer_header = NULL;2 L/ A% J7 t/ q' Z' s3 S" F; O6 x5 ?4 i
$ G2 A& p$ B8 r5 l$ j
4 ~& u$ q, c7 }2 h! W- {( p3 @$ o
void add_timer(unsigned short
9 a# t6 i, u- d. Vjiffies,void (*callback)())

8 t/ b7 @# _2 N1 R7 G+ i- R$ o{
2 ~9 r; k4 a' ~% v2 K, `6 s5 h: Q1 l. f7 O+ ]# }9 h9 {
struct timer_list *ptmp;

2 {; C2 g3 Y( |
, W: |' D- J& h# `4 J# R) n- g% Z: P! }+ I; p/ N8 m+ f
if(!callback)
  M- h: T8 e5 I" C

) A( a3 o3 L/ O! N- X2 a4 Mreturn ;

% k) |" t) x3 K. \2 T9 {5 k7 G  D+ K) P3 F9 l# V
9 M. R7 Q" S; t& s6 s3 m2 U' o6 L1 ?

# a  `; O! R8 r$ d: w$ q* g* j( ZEA = 0;
! O3 r. Z. e  N. K% `& a2 [. T
* F, D- O7 _3 l' ]* j! y' [

' [* B6 X3 x) bif(jiffies <= 0)

( A. U; k$ E5 o/ j7 D1 `. Q- l" k% P: p8 t
(*callback)();

9 Y" F8 _! n" Q4 B6 k7 \- \. p! h3 l# }

$ f* l9 a+ u) x4 v2 c
2 B/ l4 y6 k( F7 ufor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

" T- p$ m7 w8 m6 T
5 ~6 N, L. {7 N, V" Bif(ptmp->callback == NULL)

1 I; `9 L2 a! @7 S" C! k2 l. Z1 T# V$ n8 m5 ~0 q$ j
break;

2 ]3 F5 G5 f, K3 i4 Z$ L
  f9 c$ y3 t8 H/ ?, q9 Z2 z
: C( e9 Q* q! C- R1 {3 W: |# ?( o- `6 u
if(ptmp >= timer_list + TIMER_REQUESTS)

7 e: P3 E, r; z0 c) M+ i  z1 W7 a; C% p4 g- b" l
{
: m! ?: n* A7 b, d
3 [# y& \7 w7 |8 X4 {# C
goto EXIT;
( E9 x; \- q3 F0 S9 n2 a/ G
; W) y# R$ D0 v. k9 |
}

% N( r( n9 G+ B6 |, y$ ?  y  C6 Q
8 d3 {8 O3 Q+ @+ F
! Z9 D) H7 C. @! F5 h+ Y; Uptmp->jiffies = jiffies;

, V# u4 B. o/ }# |
# R* |3 M. L* z& @! y/ B7 rptmp->callback = callback;
' r7 C  i& `' l/ a
$ l: q7 O- o2 o2 y& p7 Y/ C( Z/ P

; x% L8 V2 [; U. `$ n6 P- l, H
1 L7 ~5 n$ D5 b+ J1 s+ Sptmp->next = timer_header;

( P7 x8 n  P) W9 y4 x) s
$ Z+ j" Q' l, R6 ytimer_header = ptmp;

! [: I8 I) m  c7 {8 s, }8 c( \
! e% W# @( m) Y7 {; P
* Y8 j8 P( T! t0 z" v- \+ W//add bellow code to fix linux on timer’s bugs ++

* {3 M- h4 D( N0 \; x: q, {
' `& r" p5 Z5 f( y- R: ]* p  |if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
: L# T% @  o" x# f/ S4 o, t
& J& Y7 q' l; }6 p
{
5 J; C6 b) Q+ D. C% Z
4 ]& m4 S7 C6 V% v& E& P8 u
ptmp->next->jiffies -= ptmp->jiffies;
  F5 ?: i: J. E+ z/ G" ~1 A- b

" Z, z$ F6 D: X% r" F. _}//end ++
( @" h; p7 x# c) j) q, ^# {
0 A0 s& t" v7 W
else

. @) ]( a$ i! C' Y( B2 P8 m
4 H+ K$ Y; S9 w, Q{

! p: O4 m. r; v9 ]9 b% W
: t5 f" m' Z7 r9 x$ w+ d/ Z# Jwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))) H& V$ z7 F* |# {

! d- w4 [, T: n2 ]. e4 F; q$ [% M* Y4 d% @3 v) P* J6 s+ s* j3 }' Y4 ^
{

' K. u+ p1 ?8 V
. D% d9 z$ v1 _* V( E* rptmp->jiffies -= ptmp->next->jiffies;
# A$ J5 {/ a9 [0 B! X+ f4 Q+ p* S9 k
8 Q+ G# f" _( z9 L
callback = ptmp->callback;

$ @! _6 U+ K/ P* F2 K) j5 A; W3 D5 G! v  ^" Z- j* `. j9 e
ptmp->callback = ptmp->next->callback;
" P; t2 e: U0 G6 t: |. |
4 o, k, P, f( O' m& \. X, j# l$ G
ptmp->next->callback = callback;

: N- [4 v% n4 Z' P  c& M$ v( r- z: ?8 O9 r9 @
jiffies = ptmp->jiffies;

# x' `: `! r9 Z$ [% v# Z# n7 G9 z) X$ i
ptmp->jiffies = ptmp->next->jiffies;
2 Z  F' }- ^2 N

% s% N" t! \; ~- C8 Z. `; x, mptmp->next->jiffies = jiffies;

' O/ j; n& L, o4 u, D8 |3 M7 h4 \2 v! }* Z* ]
ptmp = ptmp->next;
- ]6 n# h# ]! e: t$ [& v( y8 y

( L+ Q- `! P, m5 w}

& R" I2 g* R: y$ l9 o- L- X7 r9 K- Y5 h
}
0 a$ x2 M6 J' u
- L/ g2 {9 d3 K8 l+ b
EXIT:
/ a% A( m  s. M; {2 I- d; b2 W
EA = 1;

& X# N2 F1 ]5 N& J, K3 {/ {- Y, c" a, S9 {5 N9 ?( J3 ~. x8 G: D* P7 K
return;
8 C9 w, S9 a  s. B
}, E. `$ c1 J, y; x& @# i
' x* h- s& w- D" S
void do_timer(void)2 l( U' g; ~% e4 G% ]0 S
{+ G) R% b4 k( j+ X! y5 p" M6 T) m

4 [, }: s* ~4 A: @$ h! l. N5 @$ E7 [; h: c
while((timer_header != NULL)
7 @; O, j0 n; X1 K
5 ~, {2 D/ j7 z: B; p' u

( @/ G! c* S1 s2 l6 }& c! W&&(timer_header->callback != NULL)
$ O- |% k4 O" g+ R8 Y
" d) y' o/ }1 z4 C& n% o" J, `* |9 u
; V" G5 R1 l% V7 t9 u8 t* M0 ]
&&(--timer_header->jiffies <= 0))

& u- S4 D4 D9 ^& K+ A. C- J9 n5 M$ F5 X  z# s2 d0 R* y
{
/ ]: r% R6 ~- n9 x) q& \0 K% L

- O: n' m. H# q- W* t" d( X, Z# Uvoid (*callback_fptr)(void);
2 V/ \3 ?( E  s2 j4 b

& k; f* c8 v1 {
; `; l/ M' a' L! H; h7 N& [. ~, zcallback_fptr = timer_header->callback;
2 @" B0 r7 `. G' p* u

7 K: x% t/ o7 qtimer_header->callback = NULL;

" U; M; A$ C4 @1 |: o" o6 p+ y7 D
timer_header = timer_header->next;

6 v7 C6 E4 R4 u3 t2 k
" t8 `- P! J5 N9 U3 B) `7 C+ Z(*callback_fptr)();
: e( }% k. A0 g2 [( v! p. a+ ~1 u

* B8 g2 v# \+ V* b. Y( Y0 Q' Z}

- i% Q4 a) \+ Q# m+ L+ E
- E; L' I! h, v& L* a. ^
2 w5 R1 d/ E( ]! a
}
( o! E1 }4 N: l* R% r% \///////////////////////////////////////////////////+ n9 ~+ |" U3 Q1 ], F
( N  S9 C) |: G" \

8 B/ k- Q/ R" q  k) q6 J上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
" \! j3 @/ z1 K' P; B! [
3 F: a. Z- l0 }- K5 H: C- c野人献曝,博君一笑+ u( {9 L  b$ O) A# B' D$ i2 R" D
' J+ F  J* F7 \
Peter
' [4 X' h6 {1 K% o  
; k% C6 J7 f3 U8 _
# k4 v+ s" R2 x/ J[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-5-2 05:50 , Processed in 0.031134 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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