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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
/ g2 C( P- \0 ?9 F/ T0 O& r
2 m# F' P  W2 B5 T" l" t7 z
1. Why need this mechanism
" R) l9 h  `& C5 ]) m; P
5 c, K; r" i+ t: ~2 X* \
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。

$ `5 ]) k) j7 o% p# v- I; i
2 B* s+ o, `' l7 A7 V0 J2. How to improve it?; s# X: _# m9 r2 B

1 P  v7 y6 p! t/ ~# i  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
, J; L9 b: l2 t5 F2 X5 ~9 n. {1 k$ d4 ^0 u
//header file, z! \& X. g. W$ A# m0 }3 D
/////////////////////////////////////////////////
, n2 z- B8 }/ X/ w#ifndef8 D. ]" a" [% l" Q7 X& n
OEM_TIMER_SERVICE__H

+ O4 M( Y* j6 V#define
  S- c* W3 {0 y$ b1 ?0 eOEM_TIMER_SERVIEC__H

4 J  t  V& L9 |1 U5 `; z& g
/ t+ V- @) d5 h$ c) b
0 N; T* q+ |; \; B9 O- ^7 ]- N, cvoid add_timer(unsigned short! d7 e$ }9 }# r: L6 z
jiffies,void (*callback)());
/ [0 t, Y5 R; ~2 Z& }8 G
! J: O, x( B0 T, M4 P
void do_timer(void);
# d7 z7 A5 X/ ]  R  ^& n* F# W5 k# ?4 M3 c
#endif
" N9 W# l1 R% \+ z1 l: l$ y/////////////////////////////////////////////////
: Z! D( k4 P7 ~/ _! `% _) I7 x/////////////////////////////////////////////////, M" `/ A* }+ Z4 s$ ^2 H
//impl file, M2 `% g! J# C+ x. I0 T
#include <stdio.h>0 ]6 a" U9 T  {; @- e& P: t* i; D
#include "OEMTimerService.H": A9 n9 F0 f: m0 k9 p" i7 F  P
; ~4 M9 g/ D8 u3 P- A

  z) ?( X- m/ U0 _: ~! D#define
, U3 U9 b' n  C* K) E& NTIMER_REQUESTS1 B+ o3 W" c# ^0 |9 `) V* |
0x30

/ B& O& ?) R! G$ i
4 p4 G. ]$ v& ?+ Estruct timer_list
- X2 [0 t9 z# c8 `. T{3 f4 A+ E& e. n' a1 \- \' \9 u; G
! Z; B' i+ x0 [" ^
struct timer_list *next;

- C! ?0 M# y: _5 x
. d* g% e4 ?- _5 n% Junsigned short jiffies;
, L. c# Z, R- L5 O% q

2 T4 a% u( j7 h; h, v6 l7 kvoid (*callback)(void);
) o( m+ L! w, A6 G
};3 A% n; G  s1 f. i& g+ W. J/ g, x: @

8 X( [3 T  z/ T8 a3 ~/ o* g6 C" f' M+ c' Y" E- c0 v. K
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};7 f4 F- D8 o; G- v6 _
  u+ L; \: w( z0 v# E4 W
struct timer_list *timer_header = NULL;$ D% m  g2 r' ~7 b1 v0 {! I3 |
2 \  x+ w$ V8 J

, ^) W# j: J) }" ~9 }+ R9 Dvoid add_timer(unsigned short/ d8 |) I9 N, C" }8 a6 B
jiffies,void (*callback)())
, g+ f# B/ I% Y+ ]8 s& r; f: X. f. K' ^
{
, y$ V' b8 ^# S5 W) f2 z7 g9 i
! c! S1 g! h3 _; F. kstruct timer_list *ptmp;
% A/ y/ U/ \( R9 [! ]4 d

  [4 ?: i! w  k! ]9 N. v7 Z9 v$ X5 e
if(!callback)

" [$ ^7 w& s/ g, @" e& w2 Q4 e4 {2 g5 P/ `& A2 r
return ;
# i3 i% `$ X  F) i6 l( C

9 P  m! Y- g( y! k5 m* H1 c! y# z* K
" K: t2 g( u+ _* C( M
* W6 _/ ~/ |5 p; [( ]+ R
EA = 0;

) L; k; f2 P. N# r9 S& [
7 ~" K  n) k" O; t
$ j+ B5 ^6 P& Eif(jiffies <= 0)

; S) R" v5 E; b+ j. G) \: `( ^1 A+ [5 N+ B/ v
(*callback)();
- B9 S9 W. J' ?; a- j

5 d7 ]4 q7 R1 X/ l
6 c+ g, y% s1 w, N+ D+ w
+ X& a5 V' e) `+ a: ?
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)

+ H& }0 I6 W6 ?4 [+ P
$ r: t9 g! `8 w; Q& Xif(ptmp->callback == NULL)

6 V5 {" t$ M( S" e/ N- g) ^8 ~6 g2 g, o' j* X) G9 `! K
break;

3 F2 o( @- i* Z) f
8 z$ T0 X2 T1 x  j9 O+ g: ]9 Z, d5 @; q8 {# p- C- z& d

- T6 M$ j1 Z) S2 M* P, qif(ptmp >= timer_list + TIMER_REQUESTS)
# ^% K1 s: U" T3 E( O3 f$ l
9 v( F$ ~3 n9 k
{
' \' m! |/ S# j0 A6 q* S) y4 }% \

: o; {: A1 g0 D- {goto EXIT;

+ x* n( \7 z3 v- J
. f* r+ B/ Z1 i* X4 f$ D- f}
+ E9 k$ E. X4 ^; K2 s
9 A  a. \3 T! |& U' S; K
9 z& s0 n, j# X* z* }  b  a
ptmp->jiffies = jiffies;

, d3 p3 @. Y& P/ ?4 j
# e" f% y1 X7 v( u" D0 m) F" optmp->callback = callback;
5 k' n: _$ X# k( {+ T

3 |/ ]3 g# g5 P+ M0 k0 G; P1 X
: |4 O7 ~$ z" S/ x; _7 j- H( {% T' \
4 P/ Q* j0 d4 `, {
ptmp->next = timer_header;

- c( K8 {" n0 k- N
% O: R6 @& B- Ftimer_header = ptmp;
$ m. l2 _! q' N6 R- V

, @* L1 o# N' R0 {: ]- G, D$ T% L; @
//add bellow code to fix linux on timer’s bugs ++

6 p7 Y; z( ^: O7 N0 s: q. w9 u% d
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)

# Q! j8 f+ D2 r/ }6 J
4 l9 D5 J/ V6 J3 i8 y{

# R( i0 s; ^& E) F' S& q5 T" [2 ~. ^6 S0 j6 j# k" c" h& A' k
ptmp->next->jiffies -= ptmp->jiffies;
, s; F) y; ~. s2 Z

6 ~5 J+ B! _  U8 [+ u  ?}//end ++
: V( G$ ]3 b. h5 A2 S4 D

1 I5 o2 x( t: }3 W5 W" pelse
4 ~6 A- d# L0 ]& Z
( E# t$ R, ^3 p6 Z* N# L/ z
{

' }( H8 i) o9 H+ B6 Z( e% x2 ?
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
& u$ S9 h/ ^9 z. n8 }6 o) a& P

; Y) |4 @$ Z* s9 L2 Z+ N- m- l+ ~2 E# Y
{
! m& Q" [) o; V. }7 |& `( ]

& u, j: M' f2 v0 e8 yptmp->jiffies -= ptmp->next->jiffies;
' c% i* q6 R# @6 J  f5 [

5 E0 `# P  B& p* M% {8 _- W3 }( vcallback = ptmp->callback;
% {  R, u2 \- J7 a7 d5 n

7 x% U; Z: v* D5 t3 E" o# |. |ptmp->callback = ptmp->next->callback;
% B+ u. n& t- `9 ~4 W4 o6 {

$ ^  C& @3 P% R: Hptmp->next->callback = callback;

$ v7 W2 p+ [4 D& X
% c# e; U$ J+ E9 b) \8 C' Vjiffies = ptmp->jiffies;

2 w% T: `: i+ l2 ?' C( d- u
8 G( N' D9 \; m0 K4 J- ^ptmp->jiffies = ptmp->next->jiffies;
2 {4 }1 C" Y' ~* D

( G- ]4 s0 S1 _! B0 G; ^' pptmp->next->jiffies = jiffies;
6 D& Q/ |6 S9 ^4 R% I3 f' |1 l1 _
1 V* _8 e# H6 J+ U. j
ptmp = ptmp->next;
5 |4 d: Q+ C% N; [
8 V9 x  x- V# G8 M( V! ?
}

( p  z/ p- T! G
. V: @1 S4 d% D) x0 x+ g}
$ a0 R4 Y6 z; J" S
0 W7 G0 ~7 }' N
EXIT:
9 o4 F8 c9 }$ K0 {: a4 ~* D8 [2 Y8 E3 z, J/ B
EA = 1;
! c  ?; q( E9 S) J5 R: c0 u' W9 O3 C( G
' C+ q" [! m# U& A/ C* X% P2 n
return;

  q- Y9 W4 Z! p/ q0 e* u}
/ v; w1 Z3 M( j9 D% t
* a1 g$ @- }0 x( {& Vvoid do_timer(void)
* S7 A7 S) @% E& Z# c{/ ?/ ]8 y; A: r
5 i: O7 J: W% y( R% B) S* X
1 I: `; w+ L8 ^
while((timer_header != NULL)

1 P$ \0 s- c" n$ o" U' D0 D) {8 p, s
! V$ E9 v. Y% ]% s
&&(timer_header->callback != NULL)
# j3 _; }# I! q' g
0 h7 ^; n) ~2 Y/ H

( T$ X6 ^2 z( _& w, R$ Z&&(--timer_header->jiffies <= 0))
+ P5 k2 ^& z0 }. T- c
6 S7 x- U. i: E- E. g* e& u+ j1 F! K1 m
{

8 a6 {& p6 W( R" y' N
: T1 }9 r; f# _, Qvoid (*callback_fptr)(void);

3 {6 q# D, o8 r  L2 K  d0 Y
- q- E# j7 [) ]; h) Y2 v' Y* i1 W1 D( _- X
callback_fptr = timer_header->callback;

" B) x$ z- p# D+ `6 N. M) m
8 ]7 p+ S2 H' O: s4 G" s4 Htimer_header->callback = NULL;
$ c' o; [  s1 b, }8 m& A3 v

, f# Z) V; t1 A3 h1 _% Ytimer_header = timer_header->next;

2 n% x1 ^4 C6 P/ [7 Y6 D# `5 z5 n( L# s3 k& z+ a/ K' a
(*callback_fptr)();
' c' Z8 m- l. W) [; P+ s

" F5 N5 K# a& n/ @  }}

7 N$ e" ?9 G* B( F+ c! }6 m( @+ d8 c; ?

! h) j" c1 n1 L, M$ J/ P}( T. k  l2 L/ P$ e
///////////////////////////////////////////////////
# j) ?' S* d+ P4 I
3 S2 Y6 H" x1 t1 @. Q& r
  Q( [% Z4 E0 F' X7 q
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!
9 V" a- ^% c; e/ J- f8 Y
5 X: e) V' e% ~: `野人献曝,博君一笑
, i/ ]& X2 u; @. T7 a) r
  ~8 L/ n6 G' q. U+ p- kPeter' C! d. I+ {3 U  N7 [  p& W
  / {8 r4 ~: L& x5 C+ ~4 O6 A6 [( A
& d; H1 H& o" L! I) F5 A9 H* F
[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2025-6-17 13:36 , Processed in 0.109146 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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