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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
! o5 U! F; t( ]6 Z8 e/ G
1 j$ u5 s! L& ~& `- r2 X. T& G
1. Why need this mechanism
, P$ E2 D$ H. Q5 C+ j) ?; n7 ^
0 A1 Y  Q; f/ x- i4 C" o
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
0 d! _% m+ y$ k2 b! w# |9 [$ C
0 n& k( ]+ f& c& t5 n+ ?7 K
2. How to improve it?
( q; ]# F' x/ A( Z) I7 k9 p, b8 `
! U% a8 U, w. `% H  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
. Z4 \* J- V7 i- Y# d, H$ ]7 u& ?' |2 C5 g/ |+ u$ B
//header file: E. Q" c+ x; |+ ]- H
/////////////////////////////////////////////////4 ?, h  o+ Y8 J4 Z9 L
#ifndef0 @0 w' G+ s, S4 k% b  l
OEM_TIMER_SERVICE__H

5 w# F- V8 x* U0 o#define
. W, Y1 E7 _4 }5 `/ _9 e0 [OEM_TIMER_SERVIEC__H
7 Y5 o% R( K5 r
$ `3 A( {) |7 A* u, ]( H
/ n' \; x9 h9 F) h% k8 L
void add_timer(unsigned short
: m. v3 t& p; t+ o  S% yjiffies,void (*callback)());

2 F; l) V$ D/ M" L' Z7 Z( o. s  s2 \4 y
void do_timer(void);
3 U1 Y4 p" H" U  r, z% ?. x
0 H2 w! `. W4 P; y9 w7 U! i4 v  _#endif/ y1 R) r/ E( |- c, U/ _
/////////////////////////////////////////////////# j! R; [% E8 j/ D6 F! b3 D
/////////////////////////////////////////////////' Q/ m9 q1 g" o. H
//impl file
# O, }% K) D+ \3 w& E#include <stdio.h>$ c/ e4 @6 D7 c, v& {) B
#include "OEMTimerService.H"
- `' F" Y* l, Q% k% M& m& e4 k; D% \* D" Q& q
* ^4 [" W) i$ _) j6 v- m" \3 x
#define4 m  F. o, T8 {! Y# U6 O9 i
TIMER_REQUESTS
) m" v7 E6 s  g9 N! C! ]- L  [" w0x30

' E3 Z" r7 s3 \  S' g
3 p4 x* A- b9 z0 L. Kstruct timer_list
6 B4 T7 i/ P, o  m{0 g9 O& A1 ]6 J( @/ g
3 T1 Z. A/ p0 x6 y* v* u+ H  `
struct timer_list *next;

0 ~8 u9 t$ [# F6 s% A2 u' g* b8 [& d2 K! E" {" N: J
unsigned short jiffies;

- U6 A$ z7 [1 v! l1 ~
$ j* r# X. [- f6 Mvoid (*callback)(void);
  X8 N5 s. w1 X+ U
};
( J4 s. w" g# _* z% E1 ]4 K  V9 Q- _! U" ]+ W$ w' a' b

7 c( M6 Y9 \# r7 J# V4 G! Vstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
: Y/ r+ @  N" X: q! ^) i0 M! p6 G" j3 S4 w
struct timer_list *timer_header = NULL;
* O( z- |: S6 W: v" Y9 G
7 K$ p( ?1 z" V6 @$ d( |
4 f& d: M  V5 {void add_timer(unsigned short
8 V1 w5 V6 X( v) D" `jiffies,void (*callback)())
$ T% \2 m+ l% h9 A$ r
{
) s" i8 |# @- W, {) C9 Q- Q: ]0 I, ~* b! u
struct timer_list *ptmp;
. Y8 |% Q3 _" G8 e" u

' \  |" a$ A( c4 m, |+ n" I0 x- X, j1 G4 \$ ~5 A6 g
if(!callback)

' b2 i7 V) \6 t' p- V1 H# X  s% I5 N& `- e) S  z- s
return ;

; h8 ]" |! u  p) B/ q* [7 N5 h7 A/ d, j
: T) q3 H5 t; h- x' h3 {: X# `
# d; B) Y2 _; Z) P' E
7 F4 P- E/ Y! \( y$ l
EA = 0;
# o9 q! f' ]' x+ q' ?
  _) r, d2 H; u1 Y2 B7 T$ M

  q& h  k. q$ y7 Q+ Kif(jiffies <= 0)

) e6 v! [- B' r8 ^  W8 c/ Y# U& j2 P; e
(*callback)();
2 H% J8 a5 @  S5 v+ @8 J; \

7 q+ J7 z- c9 t8 u" I1 D  z; K

+ _$ F; G+ r5 y
) P8 u1 a, C0 }. u# y" d* N2 Ofor(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

+ k4 k& ^. F. i+ K9 e! k, G
4 D5 x1 O7 A0 h1 d+ X$ x5 W+ `9 Rif(ptmp->callback == NULL)
" k$ w- q4 X' p8 i- A  R. n

  D5 a( B( O" ]! j0 ~+ Zbreak;

) X+ y5 O( Q8 D; I: _8 ?# w* k3 h4 C3 T1 f2 W

5 E$ f# D) ?& i  j7 e7 C
+ o: {0 |3 s8 K- b  Vif(ptmp >= timer_list + TIMER_REQUESTS)
: ]! N* E' U, l% V' B& i

2 ]2 {* K) A1 a4 X  d1 y. `% _% U. J{
2 U1 n* \4 {: I

3 F5 x9 `8 j/ y- U/ `- O- K& Lgoto EXIT;
3 f. z8 `* }3 H

; h" s7 d2 l* s' q# X- T2 C0 d2 y}

+ M3 ~! F- M$ U/ K% N/ t4 N# P4 h5 T* i% x
3 S: {; q" X+ d+ I1 u
ptmp->jiffies = jiffies;
: ~+ o$ P! ?5 A/ P3 F

5 X- g3 z# }) ~3 v* Qptmp->callback = callback;

6 x( A' y4 m8 v' v5 F2 Q; l
4 B; v* R4 b/ ?' m) n% f* R* ]

. D3 Q# ]" w5 n9 {9 J; d& M8 j3 H- J+ y5 w2 T4 A( K6 p) ~& f
ptmp->next = timer_header;

! `$ m. q' a; Y# |( K! {# h* B3 }6 h  }# q* I% P3 ~, L( ?
timer_header = ptmp;

# H1 y6 m+ o+ b  I! K: _5 h
9 K4 s* n. l: [- U3 R5 k- K2 ]" ~) `: o3 v% S
//add bellow code to fix linux on timer’s bugs ++

# G4 Y. G$ E, Q/ K' H% _( p; F: q
6 \% y. B3 e* r. [/ U  Wif(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
! }2 t: e- q6 y5 m  J8 ^# s

8 k4 C: }! @0 H' i9 t9 q# h{
  `) Y  _! Q) Y& I( H1 j1 _: N0 [

" m; H" W; y0 i- Wptmp->next->jiffies -= ptmp->jiffies;

6 X6 @( e+ l4 p6 R  K5 k: U3 `3 a$ c7 I2 X1 {* E. V
}//end ++
5 z  m% o, e1 e1 d

7 \& N! C$ A2 U7 G$ S1 f0 kelse

5 a# ^, h! N9 |. `: u$ T, M' `5 s2 O: r5 _* o
{

* H; B! a2 Y7 m/ v- j4 O
+ R0 \1 X, x" X6 \5 B& y# nwhile(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies)), k+ Q) [1 @. y! W1 h
2 u2 S" \8 p+ D) D0 _' v
# D! c  T" D8 D* L9 J0 b# v
{

& {  R1 x5 X3 X' B2 X' D# Q3 b2 M' l( B, q8 I
ptmp->jiffies -= ptmp->next->jiffies;
) g3 {6 R/ S/ L; g: Y

' f1 x1 ?- x( B8 ~+ z  Ycallback = ptmp->callback;

, w( _% k- ?* O/ |2 A" N! {' ^: L/ i
0 u$ n+ g2 J7 v7 N! n4 U# lptmp->callback = ptmp->next->callback;
9 }2 i6 O5 v8 \+ _

9 r1 R" x! v- Q3 g# iptmp->next->callback = callback;

! y! q4 R5 A$ p2 A& ]
# y1 M& c. D" v# Cjiffies = ptmp->jiffies;

3 g" D( e" O' a  |! B+ Q
9 u! Z2 t! V. l8 V7 }6 m5 qptmp->jiffies = ptmp->next->jiffies;
) n8 A+ S# V! u7 e

+ C. G4 s8 g' v# u8 }2 F7 Z5 uptmp->next->jiffies = jiffies;
  s' [  \) N6 _" b% k. t

/ N* S9 }) T0 k  C9 ]9 `ptmp = ptmp->next;
- i0 o2 a5 Y5 I! d

: o2 x1 ^5 r" t+ G}

) @; B- L4 K1 }; y6 c* e7 t. d9 x5 Q' M# z' a
}
  q6 h& y( r# g
1 i. R8 ^/ d4 I
EXIT:
. N$ x1 ?8 x4 ]
) d6 @$ A. v: s4 z! SEA = 1;
) j- _' n1 ]9 Q& U

& Z# Z4 {, I( {return;
7 U& t5 Z$ z# A' M5 @0 [
}
5 x- ?. |# e7 C. |/ U7 n; I& M% W7 b, F* L( v/ k7 g
void do_timer(void)
/ s% }5 d5 V7 k4 S2 s{, [6 j6 X# J3 U0 y7 x8 y

; ~  B$ n8 u5 ^/ j' f, D4 e# C2 n  \0 |
while((timer_header != NULL)

5 ~, U; k; q7 t( M) F8 _  m7 `+ X6 M" f. [2 I9 u( {
, f1 o2 [: |" o$ X; O8 n8 P
&&(timer_header->callback != NULL)

6 @: @2 M: g$ Q/ D) M0 P5 h! s, T+ A2 z+ b
* s- d( X2 s. Q2 S
&&(--timer_header->jiffies <= 0))

' H. X) N  A$ Z% f8 Z2 x; a# E- |/ H( w# q9 i- M( X1 O+ y+ ?7 F3 K
{

! ]; v# b1 U  E8 h2 P8 o- g1 C+ t3 d3 o3 D. V0 A# K; P
void (*callback_fptr)(void);

5 R; c- y8 x; y  q, R) I( M- H( m% o3 |* {! ~

; c& ?( l5 W" o9 Dcallback_fptr = timer_header->callback;
: j) \8 ]# p; R8 a6 L, _
/ j. E/ w, n) M) v9 u
timer_header->callback = NULL;
! c' O8 [  Q* p# ~4 A% c6 Q

7 G. _3 O5 B! ?% V1 u" `% x0 k6 btimer_header = timer_header->next;
7 S* P  F5 o2 a5 N8 x5 D
1 V- g/ B8 @- e7 l
(*callback_fptr)();
  W' r; h6 T9 u+ v/ z8 S  |! B; `
; A. g1 i; R; |0 U8 K
}
$ W/ ^: s. v6 G! u
4 V2 s( A$ _# g* _/ x

, n5 l3 K- Z# h1 x# D}9 b0 N) L; M& }4 X
///////////////////////////////////////////////////9 D7 i8 q0 z/ w* B# R* q/ w

& A; a# f9 w0 c5 f, E  y

) K# m" a% d; r( \7 G- m) p& I上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
. }0 `3 y2 C( d7 o# a4 W- R$ J4 {  j& N- f( }
野人献曝,博君一笑. y& n: e# o: C1 @- m

0 g  \4 g0 S" F6 l+ R% I/ f* z2 XPeter  C4 {' `5 J) s) r+ Y1 @" Q
  
) x; E, V7 a! ^# @! v& B- z
7 I; ~2 r0 }( H) P) E' W[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-1-18 22:31 , Processed in 0.072181 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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