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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
* ^* W' F+ N+ Y& H/ o' w

. p9 M4 I7 m4 y  j7 w4 s1. Why need this mechanism5 d/ u6 Q/ B, I+ f+ A

6 Y. _8 q5 H' f2 j6 U' E3 A
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
& }. l. H( F/ W+ `+ C) z3 [( |2 T
9 R# v% x# Z8 z* K7 Y% _
2. How to improve it?
: D! K  Y$ P9 G% Z4 J# E  V1 t9 J2 ^( _1 G* K  @
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code% e! Z" B4 y! H- C; n& }& g
( C/ Z$ d% v+ v- Q0 {# ]
//header file8 x7 H% x# h0 M3 u
/////////////////////////////////////////////////
- s$ c; y! E. ^( Q. J#ifndef
, C4 l; G: b4 A3 }7 Y7 mOEM_TIMER_SERVICE__H
* ]2 H: W" c1 K+ X- p# A8 Q
#define
' f8 R( ]( F! `6 R1 y- J  fOEM_TIMER_SERVIEC__H

3 m- s& d- C6 X
' q7 f4 \: I. L$ V) z2 L! g( m2 S: Q3 T% C8 x
void add_timer(unsigned short2 K0 P1 A1 w! m) l4 N6 q8 G- N
jiffies,void (*callback)());

9 S2 b1 P& t7 H* m! N6 r
* Z6 ?, t3 Q& R& A& Z% c, xvoid do_timer(void);
% p9 }. f& D3 m
2 q4 K: o# ]. i. n. m; Y& `#endif( E4 F  y1 z' W; T- I2 x2 l# U
/////////////////////////////////////////////////2 Z) \# \4 H6 H; q' \  f
/////////////////////////////////////////////////6 @8 a0 l6 ]% q6 v# q* O
//impl file
7 z6 a" z8 d$ n- `3 H2 [#include <stdio.h>; U  I2 ~; @- T4 M4 c: w* ^1 T
#include "OEMTimerService.H"
$ Q! E7 M  a. r/ W- ?2 B& B8 m5 t' y% j# p
& x1 o/ ?$ M/ v
#define
$ }9 A, Q6 f. _! C" E; g8 c* uTIMER_REQUESTS
$ S) H$ ?5 i: x0x30
  x9 p* D" K3 g* X" e. f( m
3 Y+ M, @6 E4 n
struct timer_list
6 f/ }6 c% x. y! L- D& h" @{
5 a- U4 [' r: C' E7 u; d; B1 o; |5 r" U5 y9 O2 _
struct timer_list *next;
+ y# i0 j. v* s: ]$ n* i0 P1 d4 ^
  E9 P' L! x0 r1 D
unsigned short jiffies;
- k- g& S$ {) k2 j" d: l

6 Z& L# w( Z- X; H* P3 ovoid (*callback)(void);

/ r: V; @6 {) g  \};( _& q$ s5 A  r; E- d4 X8 x

, ^) b. g1 w2 h3 l( Z3 O
0 H# [% U! A( ^, M9 Vstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};# A5 U$ w( L* g! h, z) l

7 D* r1 @& ]7 A7 pstruct timer_list *timer_header = NULL;/ B  Z7 E: A6 @% c

( g( F+ I3 L# m, O9 O) K3 W9 C' G- f9 U  N# \5 E$ Q" l
void add_timer(unsigned short
: j( d, r# W  [6 M- e9 {jiffies,void (*callback)())
+ Q  F, |3 ?+ k# m5 q. s
{; z+ M" v0 G; \  V5 _
7 `- f) ?* R, S! T5 P6 E% @
struct timer_list *ptmp;
# U0 m1 t' E! f2 z$ D2 D

% L+ v* N' j3 a1 P( v7 A9 \, Z  Q' Z* |+ V, K8 ?$ T& M
if(!callback)

7 V+ [% J' S, q) j' e, O* k' Q1 X7 j
return ;

& s% Y6 y# q% X- {9 D; p1 h
% T" o0 E/ W1 G) j1 P1 W; ?
1 r! m# g, f9 ~: r. [6 c
6 ^& L; Y8 L: o! K' b+ V( a
EA = 0;
  L$ @4 T- x! M

8 |9 G* A5 p7 n9 X- v% _: S* i
4 a4 K: J' M0 |+ Z1 m, w( u* ^if(jiffies <= 0)

- J* }7 c- v' ]4 F1 r
4 b, O: n% o) `(*callback)();
5 g4 x, o3 ~2 P5 _5 }2 T5 T+ `3 A

' v, v* ~6 [* E$ e& }! A

- @; d8 G+ A6 u) ^- [) i/ y0 m' y, k3 {/ F# h# O+ A
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

% V- M9 T: l) y- L) n
; k& z, q" u7 [: Pif(ptmp->callback == NULL)

2 a9 y2 z+ P3 ?, i4 I/ _/ B+ ~, R; c  D9 x5 S, b7 f* Q1 y
break;

0 h& x: c7 z8 v5 [; u1 U
7 {, w! E- I& t* D) Z3 b# A3 v: K4 a
; j6 {! U( c- c- F. y2 g
if(ptmp >= timer_list + TIMER_REQUESTS)
  i' C( }' ?' o, q9 w3 V3 h

" V6 M6 ?) x) p5 i) P: n{

% {7 c# W+ w! i. o8 C2 W/ c$ r- f4 Y* F# V$ K; C7 o, b
goto EXIT;

" i# R8 v$ t: j( `8 c4 y/ ]/ q
}
* c: i  E/ x2 x9 N9 p2 a

& E2 o+ U2 ^4 D  m3 a% S/ c8 A
, I# `$ b2 X2 T) U1 optmp->jiffies = jiffies;
8 D6 D8 {! ]( m/ m

; K  S1 T2 a' M- _ptmp->callback = callback;
+ m1 j; a+ D. @

% ~3 J. v3 U) e  f
0 V) \) u7 P0 s

- ?4 `3 c. w7 x2 {+ d. ~ptmp->next = timer_header;

7 r, b' C. E& h
5 A1 b  _7 O' h* Ktimer_header = ptmp;

, {2 _5 ?  V- L& U* s" Y4 k. ^2 I+ l
; G, D7 _4 H  Y( a# K4 o8 S+ |
//add bellow code to fix linux on timer’s bugs ++
  O& L/ i) ?5 c7 ]' `
) T) {) Y: v) I" m/ D, z0 Y
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
2 s* |  L/ M* X9 v9 `5 R
* j" s1 g; j8 Z/ Y
{

9 D* z# {: q) k7 H. r7 m' W' g5 R5 z
ptmp->next->jiffies -= ptmp->jiffies;
; R) U6 g; W8 C# h' D* ]
/ |# K  v; {: N1 d) @9 V
}//end ++
/ u8 ]: Y$ S: y
& h" H. M! A: D5 [9 O) p9 q0 a7 n- f
else

* g  \& g2 L& H* w+ ?. r+ W4 X; C+ j6 F
{

+ L6 ^! ^% J/ w+ E) }* `" s: D' ^( [. {" L# w( L6 g7 V: s
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))- y% A, L9 b, X, p  e

9 G$ E6 J+ [) k, m# i4 V  _8 D7 ~
{
5 z8 e/ A3 x7 F/ l% V

, M. y* R: ^; Z0 B8 o- Optmp->jiffies -= ptmp->next->jiffies;

  f  f) _: p- N& E; X
# Y+ ]: q  G, ]* ~4 F( mcallback = ptmp->callback;

! t; L1 K: K0 r) O3 b; [; g  @0 ]! I3 C9 |( B! M2 r# ]- ^( j
ptmp->callback = ptmp->next->callback;

  e: z' o: m7 u  j' X! g! t7 p
2 E4 r  R+ {1 Aptmp->next->callback = callback;

! f+ Z% \' g+ I2 V8 f
5 {5 v/ H1 L" t0 `jiffies = ptmp->jiffies;
, N/ ]& ]6 E7 Z  ]6 a
. M4 ^! q) \9 x8 `: T
ptmp->jiffies = ptmp->next->jiffies;
' \/ s% d8 d1 Y/ p# B
, {" t& S. E/ L
ptmp->next->jiffies = jiffies;

5 @4 u8 u- W* I2 \* \8 x3 u5 Z
+ j2 j% Y5 O; A9 Eptmp = ptmp->next;
- W+ L$ A3 O/ n- S# h, D
9 ?/ f" W3 e* t
}
. S6 n3 y  T7 q

& u, Q. f8 i3 K: s6 d- j" B6 ^}
( F! n5 H# h- a

) t6 C, R. s1 K* v: f0 FEXIT:
# f" J. Q$ j1 [
9 S& K0 x! f5 K9 d# r$ kEA = 1;
( w9 a4 d! O6 m4 h+ C

6 e/ u! S! }' Nreturn;
7 H% t" o: [( f+ h* q
}
3 K: {7 V. I- N: ]6 R5 i
! J+ Q# L3 f- U7 evoid do_timer(void): g: N1 N7 X2 v. u* |) m% x; S* c1 w  d
{; v7 l2 Z6 |  m# y4 K
. y( {% j  V, t1 ?
6 [% |. z9 O" q3 \; a3 n4 g
while((timer_header != NULL)
4 O1 M* G* H( d3 `8 P* H# i' H
( s+ H3 a# x. `+ j! E; h

2 ]( s, f9 @' ^+ G0 p" w9 P&&(timer_header->callback != NULL)

/ D, }! [, O1 f0 Y5 }! }! v8 ?9 t+ H5 G
7 M6 ?& _6 D1 K$ p) J
&&(--timer_header->jiffies <= 0))
! w* v( U) E8 p5 j% O

$ o# o- s$ l0 m- L0 l4 l{

6 f7 K/ O% J- H/ }/ {& U/ t% ~% e: O2 G7 s7 `
void (*callback_fptr)(void);
6 T, Q) K9 v+ \3 Y% q+ A

6 \  m# R9 Y4 _; q. |7 F1 |9 z  O9 u! K0 f; c
callback_fptr = timer_header->callback;

: w( o5 x2 Z8 Z4 U' C" R8 `* ~! P7 L, l  ]/ m% z
timer_header->callback = NULL;
+ z. ~: E: j; {. Y
: U% C( h" G3 s$ v; \; F# H
timer_header = timer_header->next;

0 s3 x# v+ l' h$ ^3 s: b) L
; o8 B- u! N) Z. J$ |" k7 A( m(*callback_fptr)();
5 A6 s$ Q2 Q+ y, t
0 a) T' Y4 t; ~1 ]
}

. X, Y# _% [  i3 l) y  O) y7 p! Z9 T0 r  ?- N- ~, K

$ ]2 t3 p" [; d* M$ W}, |$ u; [* `/ c' c  t  S) e
///////////////////////////////////////////////////
8 G: k, y5 a: w$ U9 M3 d( k: }/ r$ T, N; X& a7 w

4 T# e/ h9 j8 ]/ S8 g% l0 W* @7 P5 }上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!4 B: ]$ {% H& r! O& s

& w6 k5 k4 J8 F$ a) a0 ?5 Q野人献曝,博君一笑
9 q% o5 ^% E9 u5 E; S3 n/ d! Y' j7 J$ X0 ?" M
Peter
( ]' i+ X( a" k8 U  
1 g5 i; Q! L3 G) s- \
6 ^# r* a( o- B% I' W* g* F2 i[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-6-4 19:03 , Processed in 0.479739 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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