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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
7 o/ s% z# }7 ?  s6 p  }" ?
4 t3 w+ a' u7 g) r- c2 j& T, y
1. Why need this mechanism) f* K- P9 n$ M5 W  M. U& p
$ I! d: q) L1 \
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
2 s" p& a" t$ Q

7 r' H/ f5 W) {2. How to improve it?* c3 c. A+ s8 t$ |! }2 J
8 i6 k5 }& J1 L. b6 a8 t+ C
  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code9 p4 s+ q/ }: M" k" J8 D
; m. _" g5 b% G1 t" R# ^% ~
//header file4 q% D. I$ p9 }
/////////////////////////////////////////////////: b8 S3 l; W1 p& y1 e6 ^3 q
#ifndef
# r& F" [8 C& S; W% V  K4 V. J& gOEM_TIMER_SERVICE__H
1 W5 ]* q1 n; ?3 F8 r' x2 R( B
#define9 o6 i. o! d3 }! k/ A
OEM_TIMER_SERVIEC__H
0 h) u. h9 b; b3 K7 C) f. \
$ ~4 |/ `. z" R/ E, J/ c2 {+ `% }, \
# V! e2 b; \) |6 S& W2 s
void add_timer(unsigned short  V- l3 D7 h% I% C/ G4 x* Q
jiffies,void (*callback)());

0 c! [8 D$ \" I6 @  A- S  [2 ^; U( u' w" j) n8 ?+ R8 T) W8 G
void do_timer(void);
- O, d% V5 T) Z* |0 [  h
* b8 u3 Z. _3 d; ]+ I1 X- t#endif
' p& p- ]* {) H  o% u9 @8 u/////////////////////////////////////////////////
% y& X( J; F$ I; I/ L/////////////////////////////////////////////////
7 D9 e' q# v* ^5 f5 m" w2 ~//impl file: w1 ?5 e( O& U. {
#include <stdio.h>
/ E6 F0 y9 Z/ |6 A( F, ]+ x/ d#include "OEMTimerService.H"
  G4 l* B6 ?; E6 R/ n$ p3 V5 p
/ n% @  ~. ^# r6 K( U8 y" }
! Z7 b. a2 y' C  Z! [4 A1 i#define
) s$ w' \  h/ i* Q$ {$ Q3 G: k( N3 hTIMER_REQUESTS
$ ]3 \$ q5 _# S# j0x30
+ ]  J) T: l* D8 M

/ b1 f/ s4 G1 ?; [$ Hstruct timer_list
; q4 E; L! r9 V1 ~6 m{, m" n/ g- N. V1 E% q* K
5 h4 V7 k  w( p2 l
struct timer_list *next;
, X' {7 i# z8 s+ F+ H
+ h. {- _* [- F1 C
unsigned short jiffies;

0 w- R) |9 Q% y# I6 O+ j
( n) s7 o/ z5 Avoid (*callback)(void);

3 x7 D" Q. n* U7 i};
3 c% n3 f- U3 q& V( E# p& k  U) }! }' r4 {6 W1 l
* K) ?" u( E: E5 Y0 P
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};8 s& F3 x* B4 ~5 J' f

6 S- D: U+ P4 Y8 j. S. h, Mstruct timer_list *timer_header = NULL;
7 d, D4 I8 e! U% Z# l. M9 @- C9 h' R: \( O1 ^  W
4 r' @; p! t' l, W$ {" x
void add_timer(unsigned short8 k" k1 @7 R7 O: t! ]
jiffies,void (*callback)())
/ ]6 U8 \- d( A) x
{
6 c4 H' E, |8 H- ]8 s8 g4 f
7 y3 o, L3 k3 p$ |3 ^6 Gstruct timer_list *ptmp;
' l* k" L  T  @) w
# W3 M4 R6 s* g

3 {4 x8 r. z% S+ ?- `% L+ kif(!callback)
& Z9 j, h8 {5 z# v' e

$ b7 i) R9 N2 a: w. ]0 V: l  A  n6 r8 greturn ;

& s8 f7 F7 v' {* U
3 v0 ?0 Y. U, D7 C/ d; Q
/ f+ V# e# E( ^' F

) Y1 r2 S/ a4 n7 K* @6 @3 kEA = 0;

3 z4 H& w; M$ C$ k" j% B9 N8 c! o; p2 e
+ [% c' W0 j- _
if(jiffies <= 0)

7 V6 s7 s. c" s5 A" z  \9 D& P* B- q; _8 g' @
(*callback)();
# @# O. n: ~8 K
4 r/ C7 i/ i8 S6 m' a

3 [' h1 V  u8 Z- N8 F. @# |4 }8 o9 O5 _/ [0 R
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

- i' O( o7 f& v; n# O# d. q3 h3 O  ~9 z/ \& X& n6 d/ |9 W& ^
if(ptmp->callback == NULL)
' _+ v; U6 X* I0 n3 r
- |7 d' k3 y1 n- H. C9 ~6 n
break;

+ e5 G. M( Q! }0 G& D
0 H. z3 y4 U" v' v1 P4 c
+ O. X( F5 m* u/ V8 j7 z9 G
3 {  X2 s0 U$ [7 e/ Uif(ptmp >= timer_list + TIMER_REQUESTS)
, z* J/ L) R! ^! ?* W

3 s( a" `  O* y( V. ^' w; L1 x{
& f! M7 B6 E( t  q

0 l  {  K& d% |7 B/ v  d4 Lgoto EXIT;
4 h0 O# `, \5 M+ J: Q% p

9 L( U$ u4 z5 }+ k: u}
9 `& ?0 y0 S4 H1 v8 u. I3 I

4 Q8 G8 d8 v: b2 Y( n% _) u6 |( K. O. J8 o
ptmp->jiffies = jiffies;

3 [2 v/ m# j& |' o9 z+ v8 f
4 W$ M) ~+ m/ d# S, ?. x1 z% L  ^ptmp->callback = callback;
& j$ q8 z+ \1 W' t+ h' ?

. [4 ?9 N" i0 \0 f

' C% R, _3 T, m* R. M( Y4 a
) J, P' v0 V2 ?: d* s" ~- [* Kptmp->next = timer_header;

; F7 G9 o' h3 l/ ^4 n; c" n8 ]/ F: |3 h2 X0 s; n2 C
timer_header = ptmp;

! b, A, c, D3 }5 p2 \8 p' L0 O, G1 q

! j! M6 T4 s0 k2 F& v. c( Y1 f//add bellow code to fix linux on timer’s bugs ++
2 A/ Z9 D& {) V/ p

" R5 ^8 u1 _( l! R  F6 X( bif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
- }( N2 E; `, L/ D- `. K' a1 s; A" l

. G& w& b( m$ _( ]3 i' ]9 ?{

; t5 I! i( b( j9 k& \( ~* @4 e& m
. L/ w* |3 O. h9 `: \0 y) U% hptmp->next->jiffies -= ptmp->jiffies;
0 K" _2 j; n: \0 h! {5 @

+ j/ t. q1 N) e4 Z4 n: O6 V}//end ++
0 x" E* g+ V; K0 A  H* O
$ `" }: e9 [" w+ c
else

! d1 u- o( l& R" P. W7 g- c' ?9 p! n+ }. j) s5 W$ e
{

9 H* c5 ~/ K+ ?- m8 x
* b7 g0 P9 k" d4 m2 ~/ xwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
* J; x; {6 u* Y

/ w* J2 [. Y& i3 R6 ^( B/ l9 x0 D7 G; Y. v. N' P
{
) Q' {" p% D" J/ f! K7 D  `

3 M0 j0 X) C9 L( U% q; o" u% {ptmp->jiffies -= ptmp->next->jiffies;

* {3 s% m/ X1 [' m' o
& Y! n. W7 `8 K. Tcallback = ptmp->callback;
+ b5 w5 I9 p6 C0 H7 R( d' O
. D1 g$ r8 O$ ~! f' {5 C
ptmp->callback = ptmp->next->callback;
0 Y* R6 h* Q7 B$ `" |
9 F* Q& v4 l: @9 a* |0 O
ptmp->next->callback = callback;
" ?" Z3 P4 u0 h- r4 D

3 v! {& ^- g2 m& ujiffies = ptmp->jiffies;

$ r/ m. [4 h( t9 q+ W
$ ~% S% `$ ?' |- h$ _1 z- ?ptmp->jiffies = ptmp->next->jiffies;
" s' s, _* U8 J. o% ^) b8 i/ E

& X- S' e# @! Xptmp->next->jiffies = jiffies;
- S$ R8 J6 ~/ c; S
2 g4 F9 `! C  y
ptmp = ptmp->next;

0 q" j) S5 ^; T' Q4 B( F# \& B1 }- F" }  O- m1 r7 u' f
}
: |& I8 v; `1 J0 [) i
5 b7 P; J: N# w9 {
}
$ i3 L# R7 O- O) c4 V+ d

" n/ `1 `' Y( B7 W! _& h3 M6 i9 HEXIT:
% j1 b! @! G, D' J6 S1 S2 k# j9 `# [$ t& ?* y5 j
EA = 1;
2 g: R3 r  q9 H

8 o! f- H- `# h1 creturn;
- l$ _, _# o# y$ E
}1 u+ ~0 l& W/ `- N6 ^# t7 K' M7 f# F3 {
3 P1 ~- u) L; ]6 ]
void do_timer(void). ^+ D% h  `0 O
{
- |3 b1 d$ ~6 |

5 W& Y6 g; d; [5 D
# C' F$ `, C$ {# r, gwhile((timer_header != NULL)
! w0 B+ X7 K; Q( s" t( q
, J% E; E0 n3 h" d+ A; \6 ^6 q: M

' [0 v+ ?2 D. i, j, x+ N&&(timer_header->callback != NULL)

( s1 q7 ^& y* X5 j
" I4 X4 T# d1 K, n
1 L2 ~2 a. n8 ~6 ~&&(--timer_header->jiffies <= 0))

! E8 K7 {1 E! ^1 N! M- Y; b
+ n6 i8 D5 ]2 N7 Z! k/ ^1 X  }' F{

4 R2 U! o  V4 s3 D1 v8 i$ q  B4 L5 c" v2 [3 F
void (*callback_fptr)(void);
* p- M& A$ C, [0 z# A3 W. a4 a( O

/ p6 e  y! u# M1 m% Y
  L: B4 |" `% I' B/ c4 u5 F& Fcallback_fptr = timer_header->callback;

3 ~; H- h& e. f, A0 A) Y* }0 U; u/ Z$ Y9 V5 L
timer_header->callback = NULL;

0 i' u; v7 I, A" e* S6 j
( |/ J( e1 c, n( z, M! B( qtimer_header = timer_header->next;

4 x( _9 U1 Z( ^# ^$ S. B
0 _% W* y  X% D; I/ @: O5 X(*callback_fptr)();
9 x' B+ d; K6 T

2 k& f5 U6 G! o7 ]% g: i, C}
9 }0 U- W: W* k; |4 |8 d
1 x/ l) i9 [8 r# a0 J% P2 g+ J. v- r

2 v+ e2 e3 M) b6 ~}8 m3 V0 `/ w4 Y
///////////////////////////////////////////////////
. U$ e. [4 |* k. p. a* Q5 ?% W8 ^6 l" W2 w" F" z5 y
" _/ o) N+ S4 P  f
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
$ v% [. F* r' y( {% h- v7 v& O* @# A5 n2 @& W8 a4 J$ w
野人献曝,博君一笑: `9 ~! q. a+ U' v

8 B+ z. C" @' B* h& KPeter( J9 i" X. Q$ H9 }. N( I8 u# ]
  / z- Q* n% D" b# E4 A! Q

+ J- j9 Z" N% N) q' k0 K! y[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-20 01:37 , Processed in 0.082795 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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