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

Smart Timing Mechanism

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

! f; `3 A+ o, C0 s( U3 {
8 b/ V; N5 h8 `  x3 ^3 w
1. Why need this mechanism4 B( {, i' R3 n5 F( Q+ {) A

  O4 b$ C8 P9 I& n4 S) U
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
0 V0 a: E2 L/ S  f
8 q0 _; F# p% s5 e, W) r
2. How to improve it?
, F9 v5 \; f* Y% S0 ~! Q" j7 {6 h9 h$ o# u0 d
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code5 Z% t" ?8 }: K( m4 m  q; j

, Y! w3 u+ I0 x//header file
' r% A" I0 R6 P. A; I/////////////////////////////////////////////////9 o; j( H1 h+ [* |
#ifndef$ W8 r' I' y! Y+ w+ Z+ v# N# l) ]
OEM_TIMER_SERVICE__H
1 y- T0 P) g. [8 ^1 x0 u, T( s
#define" C; ]) {/ i$ |6 w- @; z, O
OEM_TIMER_SERVIEC__H

5 Z, m2 h! a  ^: l( @8 N5 @1 `5 T
6 s; [' B7 D# ]) V2 [" e6 m
- G% P" E' U1 `( t( }void add_timer(unsigned short3 X- S( l- I& u
jiffies,void (*callback)());

! Z" K; N2 ?& ^* T
1 E' H4 y* k( S, Q* C2 nvoid do_timer(void);
, Z! M& T8 G- S/ O* Z- l: }2 h, _$ l& ]) y$ ^- b3 _$ T
#endif6 a" u' p, n8 a) a& A& Q8 {
/////////////////////////////////////////////////
  [: S& V# Y. S/////////////////////////////////////////////////& F$ u/ Z' J3 q0 {
//impl file/ ]/ k  f4 H- N/ a" L' {
#include <stdio.h>
6 O! ]2 s1 ^- z0 C#include "OEMTimerService.H") ]0 B: R# F( _$ n( x9 c: G
* L, y4 d' U8 u! N7 F
5 c- K( T9 p; y1 Z5 G0 Z$ P
#define
& w6 W9 J% y) W6 X1 tTIMER_REQUESTS) h' B. @6 \0 S
0x30

9 n8 j+ @9 X+ V7 L: F  s7 E- F0 q  \! k
struct timer_list 0 s6 [: y$ z8 a$ ~- z
{
) R1 _) [1 E0 q. x5 Q- n/ }' ?) q! t% a, f% Q9 E
struct timer_list *next;
) z/ Y( }. Y8 o5 A1 E: g6 `

9 q& r5 ~( t4 f8 yunsigned short jiffies;
; B- A5 O; J" t& N
( p, D( ?% i# X
void (*callback)(void);
: |- v) q9 k! y5 @
};
8 ]. j8 ]4 [) D* Y2 Z
6 S% j# \$ z: a  s+ l
, [5 z0 t# Z6 ~( Tstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};: }3 @* M. x4 O" g( ~! N

: E6 d& d+ M8 k! Mstruct timer_list *timer_header = NULL;
! s6 k7 h7 F$ b0 Z' V* l  p3 ~: f4 P- r  e+ o# ?

8 y! q9 {* M) x8 Evoid add_timer(unsigned short
3 p' T9 g$ a) j' w) f" mjiffies,void (*callback)())
7 f" B9 N3 @; r/ z& e4 i
{
& a8 a% |5 G/ K  e0 _+ k9 T6 K* F- v- X1 e
struct timer_list *ptmp;

$ }4 p7 ?6 A1 P& V2 M
. X. Y/ d3 ^5 }" f: m, U8 m# S# @7 a8 A& Y/ W, o: G
if(!callback)
9 C. \5 ^, w4 r( q2 {; |

$ E; w7 f6 b  Z: e/ d5 S! u+ Ireturn ;
) _7 t& g' j2 g5 N& H1 j* n& K
$ U0 {$ C# `$ {/ O% b

: j0 k- J- j9 U$ N  f0 v
$ Y  S; Y' I0 C2 a# G, V, l* w0 t  _% uEA = 0;

  [, G% \# X& I% u8 _( D  D9 A# t6 D1 ?1 U
+ J8 a7 K7 I) y) m6 L
if(jiffies <= 0)

) Y8 [% H' l, H+ ~0 |
% e6 V- u! T. \' Z4 x(*callback)();

1 R) G: J8 P# Z
' A; U0 }) c2 u$ K5 U, K- x4 z
5 ~$ h" M" p8 E+ j8 F

9 Z! R; q! @( o; M( P2 Y9 ]$ v% N- G& |for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
0 Q* E9 A+ Y: m, ~# N) e! Q! [0 z
; c* I) K2 x6 {' D
if(ptmp->callback == NULL)
5 U; t  {( v: l

" q( [; V8 Y3 ^+ qbreak;
& Q2 q8 A7 P4 o

8 t. t" w% v3 _* `6 g; }# n
7 T$ ^0 @" C* x+ j2 u/ \3 B) X6 K5 T% w9 J0 \/ v) T
if(ptmp >= timer_list + TIMER_REQUESTS)
# ?6 t4 u# @; Q; t/ N

2 B1 E1 b7 _0 c{

1 h2 }( ^8 G% I
- F* R0 K: Z. l( S. Dgoto EXIT;
4 y! T& c2 e$ x' J% F0 [$ q

4 z: k( v( s* ?  k1 e}

; C% p# k" K  z& ^/ ]2 _
. ^! u: G% N* S% ]6 p, F7 r' y" m
+ O4 V# k" X" G4 t+ Kptmp->jiffies = jiffies;

2 o$ Z( e7 y5 |
" ?3 A, N% Q" c' _: `. c) jptmp->callback = callback;
2 o- N3 ^1 ]8 z2 |5 `* n4 W
/ Z- X) J9 ~4 a+ G" R7 ^

2 q% i! w. F9 s* L; T5 d  W
) w5 E3 f2 E- E5 ?4 S- w! l# qptmp->next = timer_header;

9 A, B6 v: ~  M, S+ {  Z
- S" Z# R% m5 k! Z8 y# A: Ktimer_header = ptmp;

3 A/ ^  a" b% Z" t3 v/ e! k, g9 E" A7 E, P6 O

4 V* R+ k& R; Y! g# L/ ~//add bellow code to fix linux on timer’s bugs ++

8 l' T; g. T; X) H) i- b  a0 Z
; p% I/ d% |+ ]3 m* p6 ~: mif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
" ]! U9 n1 d! ]/ U

0 m7 B, I1 p: }{

- |" \* r( M; n+ `. |
. K: D" q7 i/ m- f/ h2 xptmp->next->jiffies -= ptmp->jiffies;

2 i4 E2 S4 F& n0 S& n- p$ M. H' z1 ^
" Q5 @" z3 e5 B& _}//end ++
- H' Y- Y) b6 x" H
/ i, ]% ~: z- T1 x: L2 z
else

( S' `" C; S" o
, x8 d: |6 B2 {5 M) t. m) e, o{
' |" [: d+ `8 O! t3 Q+ j
: i" r1 |5 S  s
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
8 d( @' ^" F/ q" p  }$ ]; u
# {2 E" N  R& v$ i4 l
8 j3 x1 f4 a! t/ r8 J6 v$ y( X
{

1 Z7 c, u; y* K9 R7 A7 D& k- c0 {# F3 {7 {; U* X& e
ptmp->jiffies -= ptmp->next->jiffies;
6 V: e5 m8 G( I1 B
5 j1 Q6 w, C3 k% Z( K
callback = ptmp->callback;
$ K( V+ s3 _! B0 m1 ^  ?2 l
. [7 q5 x" T5 z' S  _+ d
ptmp->callback = ptmp->next->callback;

+ L( f0 Z8 w/ \! f" u6 j7 P% d! o1 j- j1 V- Z" y9 `+ p+ c
ptmp->next->callback = callback;

' j/ v7 i$ X6 L( r  x' r% `: \
. s: @6 o7 b$ u4 u; Z9 L5 i2 G; \jiffies = ptmp->jiffies;

+ g6 y* r0 c) @9 _( s- Y2 I$ f: z8 b, k
ptmp->jiffies = ptmp->next->jiffies;
6 J4 f8 O! H! w( H
( W" {9 |7 r4 G4 N
ptmp->next->jiffies = jiffies;

! \+ M# F; w! u2 N2 G: W4 X- ^* A, E7 R& H; Y: L) V) P
ptmp = ptmp->next;

$ _4 @3 c3 F  m
  j* [: w' m0 n& b" l}

" n6 ^- G# ~/ w; K3 C
6 {8 G/ s& k; }. f}

! n! D4 _6 |9 f9 U7 C; I8 Y% U9 A0 X" ~
EXIT:
& I0 V% c8 u/ t9 `, J6 K9 ]" J7 s. G
EA = 1;

/ a4 ?9 D# w6 m# ?/ l4 K% t' M2 s/ ?6 m/ w& m4 `. O9 f2 U
return;

2 C- c4 f2 Q7 e+ `6 r}3 D% h: w. m. X

$ t* {- @% J+ v5 E$ X2 y: p7 u8 zvoid do_timer(void)
8 f. r% n, i% }/ \+ j: R  ^{
- R+ c! N. v! [" l
- p; n' q; M  {+ ^& U

5 m! S* I: Q" C: C; _) ?+ twhile((timer_header != NULL)
  p# u' z8 i3 m* K  ~

. {+ u, H+ M  w, C* P3 V2 |5 J: z0 W
&&(timer_header->callback != NULL)
5 `+ c8 E+ K4 k0 O( C& J

) K, B  H$ h4 l5 V
8 m, q! N7 ?' ?& R&&(--timer_header->jiffies <= 0))

3 N7 `% o( @; O4 o/ S
  s/ ]! V8 M  s" w3 r' f{
& O3 l3 b* B, i" @- @1 J$ E2 ^: X
, F8 \2 {: r2 H
void (*callback_fptr)(void);

& G( W, D  W+ W1 u) z' R0 Y4 j, D& J9 }2 F, B! q
% R+ M7 m7 Q3 h
callback_fptr = timer_header->callback;

8 Z& z# B- W% {: a' D5 i0 @. y( V% a6 G% o6 m; `- H. j
timer_header->callback = NULL;

, ~' g. K: S' p  ?
! d- c) x, p, s# \timer_header = timer_header->next;
) A3 i' W8 I! t( e

0 p9 n" L  V" Z' l8 y(*callback_fptr)();

' h2 @, q( P0 n5 ^! S% L0 F0 ^0 }9 z! r8 o( h! C
}

+ W4 o& w. R  q) N7 D, e/ r
1 u( E  O3 E  d8 Y, o
$ ?$ B0 S8 z) t0 K+ z$ i" \7 z
}) t) z  ?& w. ^1 Q. [
///////////////////////////////////////////////////; L" R- V" i# \8 X
% `5 @6 A( M; Y& O; \

  `( K. r+ Z$ ~# N5 z$ y/ i上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
$ I8 D  @/ H2 q( X) d- V$ E' k9 b" i5 X6 B2 x2 X
野人献曝,博君一笑% A# s, ~& Q, v0 g$ K* p# o+ ]' D

& b7 a% V) X4 sPeter5 ?6 h7 u! t6 ^# ]7 @' K- b% M
  
/ I6 L9 @& f& ?; @
# B  a# M# \, ?8 m[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2024-5-20 10:35 , Processed in 0.021780 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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