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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
/ L  V0 t: S) N  F8 \

( C1 l. |/ A" [. k1 S8 [/ u4 e1. Why need this mechanism$ q- ?" i; M2 \8 {& f$ b: B
3 P; ~/ g9 l, O$ B1 `: r
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
* `# y$ r7 f  P

; m5 r+ U$ Y% A% t4 J2. How to improve it?9 p0 \, ~( @, [, A8 Y6 C0 c7 ^

* T% V. w7 W" |$ K. x" {  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code1 O8 ?# L5 I+ @1 Z# m

9 n& ~3 w  w: s5 l' ]0 l//header file, m; c2 ~: L2 B  k& Y4 F
/////////////////////////////////////////////////1 X0 K* r1 s8 g% c$ @! v( _: A+ z
#ifndef4 U, @, n8 _" N8 M1 ^4 x
OEM_TIMER_SERVICE__H

( U; J/ ]0 U# h  e#define2 d' y  R, v: K$ |3 B6 h
OEM_TIMER_SERVIEC__H
: I3 R0 P8 v/ Z8 |
% d  U* u6 R- `9 P  L# A. r# O% S  |
8 q, t9 W7 I& J) X! b
void add_timer(unsigned short6 |) g* ]9 b! {2 ~
jiffies,void (*callback)());

5 R! m2 K/ Z1 e& P, m; [+ `% G! n/ E# s8 X' B% h
void do_timer(void);
, ]) r. V" L6 Z! K# I% C. i. {2 D: y; \& I7 l, V  }5 g6 W4 K
#endif
) k6 b+ b% c$ U, d/////////////////////////////////////////////////
0 {4 V( C$ V- n5 x( H/ r/////////////////////////////////////////////////
: t4 ]* i8 F3 c9 Z7 d" P8 ^//impl file
$ h* b/ b$ s- E6 o: r. G" D8 o" R' }#include <stdio.h>
+ g% N- T; m8 ]" q5 k#include "OEMTimerService.H"; |, X0 v2 t- w6 u! Z$ d
$ ^' R- `  X) T6 p# H, ]0 B5 Y

" B- p6 \6 f5 _8 P& P* k1 T& o#define
  }$ `0 n! L3 |+ Z' n) \TIMER_REQUESTS
" i4 H7 j$ V( Z& b5 `( T0x30
( c+ J+ _3 r7 L1 o) u& R
1 X$ L. m4 v6 |) n7 ?; {3 l! O
struct timer_list % b% T# \# G$ z6 b: P! z
{  |7 y+ E  ^# n% i* q
* p; _( e& K/ v% }4 V
struct timer_list *next;

7 {% K% e) x* K5 d7 g/ ?; G
; S) G6 u3 A" ^0 B6 Q3 }/ ~# ^7 R* }unsigned short jiffies;
7 u8 h; i/ F: M
; |$ Z8 v5 P9 i" i+ a
void (*callback)(void);

4 w) S/ B! @& E' g; s* k};
! z% z1 m( P: J# Q9 Y8 t7 a6 {+ J, L8 o; G

% H7 S, ~% g8 Y5 w: h! s- Sstruct timer_list timer_list[TIMER_REQUESTS] = {NULL};
2 I4 [& }& ~7 X; @) X% ^( M9 c# N5 K8 _; ~$ g% K- w
struct timer_list *timer_header = NULL;; q4 t4 I6 W# \
) z; ^0 u1 @+ \' X- n$ V
7 d. M8 V8 @' F. C
void add_timer(unsigned short
! a) Q5 {( R# h( p. [) x1 xjiffies,void (*callback)())

0 ~+ M, c# b2 T{
. P! y+ A' l% p! P5 s/ }9 y4 n" r4 W* f$ T( Z
struct timer_list *ptmp;
, g5 u4 v& ]+ B

+ b+ `1 a+ \; o0 Y9 A% l  X* Y/ N3 Q: x/ r! \' \, O& v) A
if(!callback)
' t4 `! s; A8 a; @: [$ V

3 @- X: m/ V" l: U9 Vreturn ;

9 D( f9 @$ i0 `9 f7 W& @8 ^7 P4 A) B2 w9 Y
- N$ s% d# q( e) F4 {/ ]
% n% e4 P* s, p6 q, c! g
9 F$ \! I: C5 B$ T% C! W
EA = 0;
$ L- ^- A" t7 f% M: h

" O: G+ F8 g! ^4 R; q$ P0 \$ ?9 k/ f/ C. X3 G/ M. F1 ~
if(jiffies <= 0)
( ^* p7 M, g) `
& S) w* \0 a* Y- G/ C
(*callback)();

! H# {  K% {! h/ G" j! D9 W2 L  A& r7 w8 n

8 }; A( j1 G7 _" p( Y
  \# U2 X3 E5 |7 u' v' I: _for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
( F8 ?2 S! I: U# g) z5 G
! x: f2 ^2 I" Z; J" S: S
if(ptmp->callback == NULL)

5 P2 N: o, o7 p! y4 o7 c/ f9 ]# K# J8 s! U2 |7 e! A
break;
2 ?( u! W- q9 \/ \) @
$ s$ @  L/ j) t

- [3 Q2 ?( F/ R( A2 B7 x, r6 s
- c1 {& Y0 v+ oif(ptmp >= timer_list + TIMER_REQUESTS)

+ W3 b5 E) J9 O0 ]0 |+ u" d8 b3 q& u4 h/ E6 ?$ u1 C
{
  E) ^! P  |) v

( e2 }& j6 a* Q% \/ Y3 \9 h6 _goto EXIT;

4 j  b( e9 A9 k! Z. |; ?+ v- H. r
$ A) m$ Y! [; y9 L9 W9 s$ U) G- k}

+ d' \% y( x4 F( q( l: l5 o# j5 B, ]1 V. S

- ]& P8 l2 R7 I  Wptmp->jiffies = jiffies;
2 m2 _3 `8 h3 l+ c) U3 d
4 N* Z0 N) j0 H6 f5 g+ _
ptmp->callback = callback;
' X4 P3 G( g, b
! t! M: N( ~- d: U' e( H( Z! Z

. T. k5 Q- t6 ]$ U* r1 h5 d: Y1 k1 ]' |3 e1 G! ^
ptmp->next = timer_header;

4 l7 e/ O$ s8 p3 Q% |3 q0 ?
5 q6 T4 V: J, I0 j' @  R: ptimer_header = ptmp;

0 E% t$ a- G. g, b3 u# r6 M' s& R* l
$ O! \* {2 e; W6 l! r- m, e
7 g+ P, b' H  L2 Y* o//add bellow code to fix linux on timer’s bugs ++

3 h* e' M4 B" a" Y1 q9 x4 e
8 p% i  B) l, m( S& j2 [if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
8 a5 I8 T0 U5 |1 [* n. y/ `

- O# f0 t$ `4 o' l; U5 k3 f/ e' R. G{

  e7 R* ^. }' W( J; Q* z
- N5 i7 T' ^0 z( U$ }ptmp->next->jiffies -= ptmp->jiffies;
) [8 ^( |, `2 c% L3 H8 e% C

: D9 f2 A1 T( [( I' [* ]}//end ++
6 c3 z+ }, U2 V0 w9 V; f# }, V
/ T& Y- E  R) s1 {0 T) U
else
8 \9 i/ F9 f/ u& L6 }* u

! x# F, w7 l: U{

' H9 G7 n7 Y( \; v/ }3 Q: H- r0 Z9 V7 k8 e. J# C% Y' B
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))8 h& D* S- f4 J, z7 K

* b8 n, ^1 |$ j: R7 e
4 O9 g  u4 t! w{

: U# K! k+ w% N0 o% n/ Z; A7 r' E" G+ H0 u# @0 Y
ptmp->jiffies -= ptmp->next->jiffies;
5 `5 f( P8 `: n$ t4 m
& X5 k4 m/ Q% @
callback = ptmp->callback;

9 b: K# R/ a; F/ m9 ]0 X/ C2 K8 P. I/ L, W1 b
ptmp->callback = ptmp->next->callback;

1 x, h- ~  l9 D' A$ ?% q
( o0 B) h8 G) D$ h+ o( H" N& N- Bptmp->next->callback = callback;

  D( T% f3 a4 X
  c& B8 ^' l7 z. b( m! \jiffies = ptmp->jiffies;
+ P6 [( W# J: N+ w7 g. M
8 `( l6 z! h) D" b0 T1 z
ptmp->jiffies = ptmp->next->jiffies;

$ d7 X  S1 W: t  ]  S4 z2 r' Y' q2 }; r, W& n. p" e% M% P
ptmp->next->jiffies = jiffies;
! p$ Y0 _5 |4 U. d2 \& g( u
2 I. b. b% g9 }# O9 e4 f4 v
ptmp = ptmp->next;
6 |) e( X1 G3 G+ E; e, r* j

- X5 O7 _# J3 B, U/ b) B}

$ B# {- N- C: N/ l0 z" x* e9 ~: Y+ g! U3 N
}
' D. [6 `1 q" ]6 ?- M

7 p: n) k8 i% |; E! l4 I, XEXIT:
: R" v+ ^2 F: C( V; o) i/ D0 H- f$ W5 h# Q+ u
EA = 1;
! {+ Q' E, _: D

3 Q9 F, N  g; t: [) ?. i9 g& t$ breturn;
2 ?0 n+ v! D1 s# J2 ~
}
' S6 Y- d7 C2 b1 a. j# U7 C  v% f; n, A' Y; ^
void do_timer(void)
0 H0 B( B/ T# b2 y; b+ z( J5 P9 ]{  L* ^+ L$ {& [; `- U

7 l& B/ g1 c1 C* G9 S0 E$ P8 z# I
2 |- h8 J1 r* B! uwhile((timer_header != NULL)

+ c" @- ~. ~: G: V$ T; Y& _+ I# B) m& v% h

3 I7 p2 A7 E* v. ~& \$ r&&(timer_header->callback != NULL)

7 X& L2 b) F! S" I% H/ T* e. i; q6 E4 s. Z" M1 ?
$ j/ y1 X) [% K6 M; {
&&(--timer_header->jiffies <= 0))
* x" L0 X/ \0 w7 d5 ^
; r4 @: k8 F$ h
{
( M" [3 I& s5 G3 v, `
: f; O" `& v9 W8 ?
void (*callback_fptr)(void);

1 g4 x: h( B5 v7 X5 z7 z; d( k7 [( E/ u* |9 s) |5 _  ]

: T) q6 n: y. m" p$ Scallback_fptr = timer_header->callback;

2 D% ~; G/ M9 y  s8 \" O4 [
, E% |5 @  |# K( L3 }( Ttimer_header->callback = NULL;

: b' ]0 {1 L# |7 T7 ?6 W% ~; H) D, Q9 F
timer_header = timer_header->next;
% c1 E$ U" z6 ]2 X+ s0 W7 E
; z7 Z/ n1 I( H4 I$ A9 o- p& X) i1 _
(*callback_fptr)();

& q" J( `$ ]" t) u9 ?! i5 O2 ]2 \- K5 K7 E
}

/ O) c; e+ r' Y* O6 A( y6 _( Y- ?4 U* B, V0 D
% @" X/ M0 y7 m" N
}2 T( u: z2 [6 ]/ A5 |
///////////////////////////////////////////////////! y  @  N, ^7 [, v& ~
0 N! m1 B) e9 D7 m; ^

( I1 ?& j0 ?$ Q2 n5 Z3 [4 ]0 o上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!# y2 L  ?0 I; A3 g6 m
: h+ [# ?1 P2 e. }
野人献曝,博君一笑% p  |4 q* p6 c1 A" w
7 N/ X8 f$ D6 n7 x
Peter1 A/ g) H' M" z8 q
  
( _3 `2 W8 G9 [: w. b0 g- [' N1 `; ~1 {$ e. z, o% P& [+ E
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-4-19 23:50 , Processed in 0.108510 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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