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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
+ T7 R$ K; a. o; o7 o; e
3 k; U, w2 n: `1 U
1. Why need this mechanism& b$ d7 e$ Y' V. R, ?: V- ]

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

1 D% e/ y, X* d4 {
4 c9 X% d/ c( K$ `2. How to improve it?8 C$ V4 r6 Y- h
  P5 R/ R/ _5 p! u; A1 m
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code/ i' w9 ?- w# o, q8 ~/ s0 d

* V) O$ X! T& k( w  L# s//header file+ j2 |" z% Z2 {1 b) V
/////////////////////////////////////////////////) J  K1 ^  y; I. u: ^8 i, @6 t
#ifndef( ]) t/ _/ B& k- }: F+ d# u; h
OEM_TIMER_SERVICE__H

( C$ ~& t" ]" G1 a' A: j#define  J7 t+ q& u+ p. O) V
OEM_TIMER_SERVIEC__H

' [) U& o2 s! J; T# `# q
( ?7 M' w% P2 j
+ e: u3 w) g6 a' N% _3 p, M' Z8 `$ fvoid add_timer(unsigned short
6 m! P( ]! }, G& e$ tjiffies,void (*callback)());

6 H1 Q: E: _" D, L
$ H# j* b" L$ Wvoid do_timer(void);0 K" p+ \( N. f8 b( C9 M
) G( P; Y/ e, i7 Y0 N
#endif
, W! S8 P$ O( E% {5 y/////////////////////////////////////////////////
! a, w, q" s+ n# L) `/////////////////////////////////////////////////
! s% G) ?# J' W7 v, U7 Q& F//impl file
4 q' Q8 y% w7 J) `#include <stdio.h>
2 l0 @3 J6 B! i; H0 K* z#include "OEMTimerService.H"5 q# U0 u7 K3 b3 P
- v" X" ?. `7 g4 _  K0 m
, d, }5 h  c  F) W+ P6 j0 Q7 C3 v
#define
& ^( C; q$ }$ k% A/ z: Y. nTIMER_REQUESTS
! d5 U; m! c2 @0x30
  I9 p$ N; E4 Z8 s/ [8 g

" m# S; P' A% K* Q  tstruct timer_list
8 Z( ^1 u+ X1 A" i{# `8 `( j# P* ?- _

6 W& ^7 l+ ]9 I3 _. s, ^- a3 istruct timer_list *next;

+ X1 Y  _! _' L+ l' w! i
+ @7 X% U$ o: q2 \: @4 Punsigned short jiffies;
4 H, g" j  p7 d; r. \6 i

7 C0 F2 X* ^$ _  y1 Z7 Rvoid (*callback)(void);

* \* M  r7 b1 b  @! y};; s! l8 ^; X# s8 z" |
, f" V' t# m$ n4 q" a
! P: z$ G( @* A7 Z6 r/ Y/ i  D- {
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
; x  z( v1 S6 R4 U" P0 s! J# K6 W2 s2 N! l, a9 u4 f. n( V4 t
struct timer_list *timer_header = NULL;
6 q' f  u, Y8 x8 f0 B: q5 ~1 a
4 L  ^! C% z/ R; g, n/ R4 Q, Q' t& @& C* ^6 f  s7 D$ ?( k
void add_timer(unsigned short
% N" k. h$ I( x5 P+ T) \jiffies,void (*callback)())

5 A) a; e- p4 y) K- j{
5 j' n4 ^6 c( w( X! J# o, r* r: R# h# V7 u/ V
struct timer_list *ptmp;

: f; G& c2 A( T$ j! J- O7 y) G0 a

2 D4 U1 s8 C$ I; R* ~' S& j% Rif(!callback)
% t" I1 F+ w# `3 N: K
+ p0 \9 z7 z) F8 d3 p; {
return ;
) ?% o; o7 o( w" f9 K

. y2 E; U7 ^' {8 n3 k  y

: I8 d9 k! ^* b! Q0 [4 {1 p9 S  u9 J6 J0 j) Y; b  B$ J% T8 Y
EA = 0;

8 l; x0 j9 Y- i3 z) J# I6 B6 f/ X5 `* k; u3 L0 e/ e. h5 p( J' d+ A3 d# [

, @! n" i, t9 Z, o+ A/ gif(jiffies <= 0)
& z4 y/ }  E6 P3 v% `9 i

! {: ^3 c" P' Q2 }& J/ H+ O(*callback)();
5 A$ }3 {: T% \+ T

% d: a+ _9 U8 m! N, w
3 e2 v2 N- O( y
) H5 d0 c% @2 Q9 l3 @
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

! [2 O) ^# r1 p! A/ x3 ^3 Y- d" Y( u; t; n
if(ptmp->callback == NULL)

" e1 ^" h' v4 ]7 S# Q
. N( u, N( D2 u8 p* lbreak;
3 v( I+ M7 J( S# r4 k0 a4 _
& X1 E* H& e( e

0 Y( B8 r5 t2 i& P7 {& I" P* G' p1 @  }- T6 T+ e) r; z
if(ptmp >= timer_list + TIMER_REQUESTS)
9 O$ `. g2 {1 L' U1 F! K

- d& Z( f7 i3 a{
$ n. k% O3 Q+ u" [. Y9 v7 m' D5 G0 o
9 U0 B" w) `$ a$ n
goto EXIT;
/ E7 l* B5 c" l. P
" \- S* C! R& c5 O$ L7 k  D, x
}
* g" c" i% N/ {, N% C# a
* n: g3 F: v  G+ Y
: P1 j. x: V' v
ptmp->jiffies = jiffies;
( h+ U$ y7 H" a; J( P1 I
; Y7 d8 [) b' K' k" o( O" R4 O
ptmp->callback = callback;
2 L, H( x: k( k; f0 \9 f
  t# v) g6 L& c3 t, y
# Q5 u5 Y& y0 u% w* `7 n# }

5 J- B% Q: ]& H7 tptmp->next = timer_header;

0 \% J: f* `7 o: e8 v6 w/ v6 l* \2 P* {; q+ I, e1 T& Y
timer_header = ptmp;
) m. F  d; s3 F
: T7 M3 [9 {" s, Z! l: H
9 Y& c& t4 I( @, u2 m# L- {5 k
//add bellow code to fix linux on timer’s bugs ++
7 J% J2 h6 g" ]4 B' |0 x: j

- x- P- y3 I+ p0 O" I8 L, C; mif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

; J; w7 Z% N* u$ }0 x. I
5 {0 d" k0 G8 U{
+ G! o8 V" _4 D9 N3 X

+ U' A; @  l# \) e7 sptmp->next->jiffies -= ptmp->jiffies;
2 S# b# L/ n5 Z
- k2 \  w2 ^: p; v
}//end ++
' e. [2 r% |1 m& C

5 T) r# C! A, ?7 Belse
% C" E6 S% N& c; U+ s% N' w# k0 C
* @! o$ U: P* [; [* V  w+ Q4 B
{
  ?7 T: D6 {. ?+ R$ N- q$ w

# Z. {3 s4 ]1 u4 `0 bwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
) J' P0 o4 o9 p" ]9 r! m. {

" H) N3 M9 y9 }0 ]/ T4 g$ I8 m0 E. z
/ j) n2 M! P% _7 B8 \{

; M( j0 Z- I8 t; l) u% i5 S) B' O
7 A  e0 ^2 g6 S) U: v" ^ptmp->jiffies -= ptmp->next->jiffies;

( P- V$ M$ I3 ?5 V) u# W
* c+ r0 U6 Y7 e& ~5 Q8 Ycallback = ptmp->callback;
+ i3 ?: U+ [. ?6 Y0 A: P

; Q5 Q0 x- k# L; \ptmp->callback = ptmp->next->callback;

7 X& G1 I5 \  I0 J* s( G0 A( U, n1 L. w9 M2 S/ ^
ptmp->next->callback = callback;

) `% b1 b4 k+ D
6 j4 f* |6 {. t& h2 pjiffies = ptmp->jiffies;

3 Q( p1 H1 Y* z: j# t  {: H7 b) f$ c) a
ptmp->jiffies = ptmp->next->jiffies;

! h* ~9 L7 J/ v4 o1 g4 ~/ f3 N& J; _0 d) z# c* M9 x
ptmp->next->jiffies = jiffies;

; Q9 _8 ?2 i$ t* Q
, j$ n* B! n9 [ptmp = ptmp->next;

$ u, z9 o3 v" P" q1 ^; S7 y/ R! W$ k4 Q& c! k+ A5 T3 N
}
7 E2 T4 S+ Y# o" N; V
5 N& Y' E0 Z0 |0 k& |" I; [. e
}

& X. i) r$ q) B
$ _- v9 j; a6 e5 W: Z$ jEXIT:
' p/ Y2 L$ q$ v1 F% m  K
" W7 |0 M% f! I( R# D* SEA = 1;

* ~* ~& X8 a6 \$ ~7 N2 b
# f- H' ^* q1 ^4 m5 b% K8 Treturn;
$ S2 M  v' {5 g, b) F% l: W4 f- b
}9 M: L+ l0 s( W1 T
) y8 z( V7 a; q. Z1 b5 _) D. P6 t6 y
void do_timer(void)
; z- j# G9 w# P5 o1 f' a{- o1 ?8 C7 {0 ~5 s

4 a& y( w- ]( w0 q1 N; A3 R
, d+ ?# |' F" N; a9 jwhile((timer_header != NULL)

4 k% _% |6 u) O. K; a6 w/ w
) ~5 a1 v( a) v- p- K# i" Y' z& c5 w% s- H3 B# a6 K4 N/ v
&&(timer_header->callback != NULL)
$ O! q  a" Q1 b

' ^  h$ H3 W6 i+ F
+ I; F1 |1 _! O! k: f2 E&&(--timer_header->jiffies <= 0))

: E4 N$ Q1 M8 r7 y( }- u7 Z+ G- M+ e9 R+ I
{
) V8 i+ K( B0 F& ^

' ^  a, c* r% |- L* n3 s% {void (*callback_fptr)(void);

4 ]) m: n4 n/ [7 D9 b& g5 M) d
$ b+ ?8 J" [* b* D+ C0 p- w" M7 g2 F0 N; t& e, d
callback_fptr = timer_header->callback;

6 E1 E! [! f$ l* j  F' ^/ S# p) F+ b4 \1 d! L
timer_header->callback = NULL;

' S% H7 k' e3 R' C. \* w% W/ L
6 B$ a0 E5 Q4 l8 e/ [- h* X5 ^timer_header = timer_header->next;

/ l5 l1 u0 ~" P0 ?8 @, j# d# ~
3 n$ t) @/ p+ l2 ?7 J9 R& f(*callback_fptr)();

* B$ D3 o/ C/ K$ U" ~! }& l) q+ D& _% M/ {
}

$ |* o9 M' O% i0 D9 f# L# w- k
, t4 Y4 Y& M9 J3 Y0 v" Q1 z
( [6 \1 n# v" P* M6 m
}  I. c/ U; V. B
///////////////////////////////////////////////////8 a! |+ W$ b. l9 F" q' {

8 W1 F. x) ~1 ^5 F/ r, p, P
) n2 u: |1 M5 @$ b
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!7 L2 ?) k& l+ f

" E( a0 [; E: `: \  q  R野人献曝,博君一笑
7 M5 c5 V) F& y. J( F0 E% c: e) H; d" h/ x8 ?( i" ^9 ]
Peter6 V- u% W& b4 X$ k+ J& R
  
, i8 k$ P' a# ]) y6 V$ r
( Z( P% h0 K5 F# r. W; g[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-2-1 05:35 , Processed in 0.116981 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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