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

Smart Timing Mechanism

[复制链接]
发表于 2009-4-20 09:50:13 | 显示全部楼层 |阅读模式
Smart Timing Mechanism
5 g' z. k* Q2 {# t6 q+ S# v: }
: B- S6 ~9 [5 C. b
1. Why need this mechanism
; P# M# D7 c$ M0 V9 a/ m: h) N. ]0 c( A1 f# r' g, s7 T
   最近在跑一个超薄NB专案,这个专案的power sequence比较奇怪,很多地方需要很多的定时一段时间然后再去调整某一部分的时序。我真是受够了code base中的定时方式。每次定时都要定义一个变量,需要使用时给它赋值,然后再8051的定时器中断到来时,再计数累加。一个函数非常的长,而且充斥着乱七八糟的变量。经过这么多年的发展,代码里到处都是坏味道,看的我非常不爽,于是就产生了改造这个机制的想法。
/ D  v: B2 c# X! ~6 q$ o

# L) w( ^8 q; l2 @) p; m3 P, n2. How to improve it?& \( O4 V; P3 R0 \

5 ~# L+ ?8 {. t1 T& \/ ^. U  既然决定了那么就行动吧! 打开google 大神进入code search,看看有没有什么好东西(J我不想重新造轮子,如果有好的代码那么就拿来参考)搜来搜去,发现linux 2.6内核中的定时机制很酷,可是不适合我的环境,它太大了,光这个机制就能把我的EC搞爆了L。然后再狂搜!果然不负我一番苦心,我发现linux 0.95内核中的定时机制挺适合。可是仔细阅读之后发现这个机制有些缺陷,它只处理了插入结点时间比头结点时间长的情况,而没有处理插入结点时间比链表头结点短的状况。下面就是我修改后的source code
& r! V! {) V4 o0 ^6 k  o. @2 ]1 E. }* a' X, R
//header file# k% L8 Z6 H- V/ U$ E0 _
/////////////////////////////////////////////////
* f$ I) V! I4 J# G/ Q0 ^) M1 w. }#ifndef
. e, d  \0 b+ ^8 o, N0 oOEM_TIMER_SERVICE__H

' K  I( v) i# k$ s* P6 ^7 }#define
6 \* P- n- I4 o# v# IOEM_TIMER_SERVIEC__H

8 }/ {0 E- {2 R2 e4 p( T+ l
; t- K7 g$ b/ u3 p9 Q. c1 g3 ~& `. x* h5 y. h9 c
void add_timer(unsigned short0 R+ h5 }5 L! m3 m
jiffies,void (*callback)());
; F; H4 A; D7 k  D7 M1 M  Y
. `3 o' f+ i0 A1 n! N9 W
void do_timer(void);
: W6 A+ T% n! U
) K. A% l2 r/ l! X#endif
* u. Z: D8 I- M3 B" k* {9 E# Q/////////////////////////////////////////////////! f5 j+ i- I( [2 c9 E" e
/////////////////////////////////////////////////
2 {8 Z  f, c( A) M5 l//impl file
  k/ H* i9 L) d" C; s1 i/ q#include <stdio.h>
* s. p4 O' c8 u; L" t#include "OEMTimerService.H": Y$ {5 K7 q$ t
: R' X0 q7 e; ~4 _1 O

2 X3 [2 e* l7 z6 b. b; i1 |0 F; b* j& t#define) J/ x( n3 a3 C$ ^
TIMER_REQUESTS
# ?- R5 X  {/ T0 C0 j& O0x30

7 c4 g2 x( e! i, v' I4 t; w( F. V( w: |2 G7 q
struct timer_list ' ^# [( v6 g+ T- I9 P" |  X
{
9 K) i5 H5 b3 b6 z1 `2 m# @6 j5 M6 w: @% b2 f! B0 U
struct timer_list *next;
8 f9 j8 V" B  e8 b; \
% }9 Y6 E+ A! q1 a* x: b( T
unsigned short jiffies;
, }. n* D  U+ ]% R/ \

8 R) G* t% U2 r9 e; v, y/ U* bvoid (*callback)(void);
2 B# t, t8 @9 |! t1 R$ R: D
};- T: y" j: Z$ ^+ A* m
# z( h; x& ]- V. V2 x
$ _4 r4 m$ \- E. k' y
struct timer_list timer_list[TIMER_REQUESTS] = {NULL};
( s- ]6 k" |* f, O6 d2 J4 O# O  r8 a4 D+ q% {  t
struct timer_list *timer_header = NULL;) n1 |& E0 q) O7 [: @1 B: V8 t

8 e! C4 U3 l) w# I
# b$ ], }' w5 H! n4 a1 B' Mvoid add_timer(unsigned short) e: J0 G0 I# l- @$ F/ s
jiffies,void (*callback)())
9 F8 F+ G$ c! c; V* L
{/ v* N! r9 \3 H3 \: l! C* O
" x" G( ^2 V6 N
struct timer_list *ptmp;

6 q" Y! v4 ^1 ?. E' W, X$ |; ^4 b: |
1 _0 }+ S. H4 {9 Y- v
if(!callback)
+ l, [+ B6 K  ?( [
$ D% p" O$ s; j/ E  ?+ n
return ;

$ u& I+ K, i9 g; D
$ U% Z' Q9 z, H) ^1 U4 Y- \4 Z2 \
9 \5 s' g. ?+ Q/ W0 ?
0 s) V, f, L; d, C4 X& A
EA = 0;
, W" j3 q. F# V2 L5 a! P: s! B
: a2 v! h, c! z6 l; Q, t

6 p, Q! O) w3 l. Bif(jiffies <= 0)
5 y$ ]1 o# z$ b" m
) b2 Y) B1 z4 U3 D0 @$ k% I# ?
(*callback)();
, K$ X2 P7 D) w* V
- P1 x4 V& B7 d. K8 r

- {2 J! }$ F6 W: t( |+ k1 \' j- I6 l9 R# o8 f2 F8 E
for(ptmp = timer_list; ptmp < timer_list + TIMER_REQUESTS; ptmp++)
# o" \: d, {. Y! I

  A( Z/ {: K5 O$ `if(ptmp->callback == NULL)
9 k6 V4 V9 s* z2 c
% p6 [, H" Z9 n# p
break;
2 E$ F5 N4 f' a- p" I( D' m, o
4 t' Y% M) q, G; m& b) V" `% z
* ?8 F: D' O5 y% l& {
$ W6 R: i) c/ Y9 V" H& G
if(ptmp >= timer_list + TIMER_REQUESTS)
; u5 j( W8 X+ O2 F3 C6 j5 J' @/ w
1 @" G9 t$ x" I
{
4 R; \7 p) `6 S* q% J
/ M7 V) H; ~, H7 w- R  t
goto EXIT;

3 ?" [) c0 K6 ~  n5 G' p& q8 S0 c: C. C, y, Z, H: ~5 M4 m5 a
}
( i) C0 C4 c2 S7 e. |* X( U- t

( g. o; {1 e( C) ~5 B& h" K& X- ]4 k, m) {. H, b2 z, w# v; }1 _
ptmp->jiffies = jiffies;

8 r% m6 J" _- ^* d4 `- Q$ M! U. f% F* [; \; k/ k& s6 B) }% u
ptmp->callback = callback;

3 c5 I6 P' E1 A/ Y8 t% E
! n* z9 {) ^3 Z/ u* [
# i& q# @3 O1 o

  Y1 Y3 H9 r9 f" tptmp->next = timer_header;
: x# N( R6 G7 A& m* I1 J
% G+ G: Y5 p4 a) d- Y+ l; c$ j) G
timer_header = ptmp;

% N  V6 N  B# t3 U! ]8 g  k6 M4 b$ Y; }( X

/ Q7 e# ~: t4 V8 D4 t% O, a  U//add bellow code to fix linux on timer’s bugs ++
( b$ ]( S4 F$ q  U! H* e! e& Z2 }
, v, l9 E' M" J% y/ _
if(ptmp->next && ptmp->next->jiffies > ptmp->jiffies)
/ e9 U  `6 H/ b. @, `3 }
7 H  v/ b$ O' S3 U2 L% J2 _. ?2 f
{
5 M# @, _- C. U0 L' `  z1 t
2 A* H/ n/ x; F& L9 k
ptmp->next->jiffies -= ptmp->jiffies;

  {& p2 k  x6 {& T
( ?4 l7 `3 m+ |' |. Z! a- _* c}//end ++

3 E( }" T2 y0 l" E0 n- _/ M
* m3 h8 u" |9 _3 L" Kelse
) p5 c  {, w- }0 L& b, j9 _
3 e/ M4 Z% F7 o  f0 \
{
2 w# m% b7 V6 i! I% U! P) f1 ~
+ G$ n- h8 {. k% o* i
while(ptmp->next && (ptmp->next->jiffies < ptmp->jiffies))
! r1 W: k) e- G& B9 v4 R. e) {

0 _2 q8 @  V, s0 F+ z! V( K) a: h, V7 i' I+ |* P7 d
{
  I4 y4 c9 [$ y8 ~3 k" }: ~

. M8 T% Q0 b% s3 z. ~ptmp->jiffies -= ptmp->next->jiffies;
& Q/ k4 h& ?  ^  L' ~* ~1 @4 Z
$ o3 S# Z" q; _; O1 ]9 b4 E
callback = ptmp->callback;
# ?3 O) R# W& Y4 e' W  K* G+ u

3 c( K; l' j. a8 }ptmp->callback = ptmp->next->callback;

. X  u# k2 f5 ]* X, c0 O) V7 R$ Q+ l- ?' \9 \
ptmp->next->callback = callback;

9 ?  |. N, _. f% h( P9 K' p
) D8 S5 i" r/ t8 l* L) mjiffies = ptmp->jiffies;

* N; h# R+ L$ n' J/ N) T6 u
7 R1 `, E7 f  r. z3 a5 Q) aptmp->jiffies = ptmp->next->jiffies;

# k3 i# r4 X# w! ~2 O- I. Z, e" q/ |
ptmp->next->jiffies = jiffies;

2 w9 H3 O7 D% P
' D3 @# ]3 N/ J8 J3 Y- }ptmp = ptmp->next;

/ ]) ?4 a, u* f2 V& c* K
# W) ^/ {9 Q+ _; E}
1 h* W: Y' ]0 ~6 l

- P6 v  Q& m& Z1 W1 Z* A}
9 u! K$ q0 G5 D/ u- R# ]* {

. i; P7 V' p7 P! ~3 kEXIT:
! u$ t, q* M9 S9 l0 N$ t6 B8 M' P# o3 O* i  c4 V! Z8 G
EA = 1;

  U7 {/ `0 U! l3 V" Z, `
; l4 ]7 X( m1 lreturn;
# F( _  A0 m: \+ V
}
# a* X6 s" Q, _6 G$ X+ S7 V
9 X6 W( {7 f( ovoid do_timer(void)  ^3 q* c& G% i* c7 A5 }% t* s( v
{; W/ Y; v. K6 }; n9 i
3 K+ _9 W+ u% [4 A. B; P

) I+ P4 S' `5 `( _. ]" w  d5 owhile((timer_header != NULL)
; V: g# J2 k& T

6 _4 Z$ M: j8 R0 ?
) f# z# ]% D1 G&&(timer_header->callback != NULL)
7 Q6 Q7 o# F, {3 Y* U
5 N0 E; k$ n* |+ Q" l6 P& T& t
6 a& @4 a" P8 k3 D: |
&&(--timer_header->jiffies <= 0))

) t5 a" f! z' b) I: ~% K0 ?9 B. ]# o" `* W' D1 x: X# H
{

$ ?6 r# B. s5 S" m4 {  ?' @9 n4 W' o6 F( F
void (*callback_fptr)(void);

, Y8 K1 A4 W7 F2 S7 ^3 b  O5 J* v  \# D

; T0 P9 W' _% C8 U' ^- Ocallback_fptr = timer_header->callback;
6 m. l% F! L4 b" T

4 O) m' ]; |3 T4 }# k! S" _  R/ Ntimer_header->callback = NULL;

' E" Y2 H, U2 Y5 y5 J7 O+ i5 O5 F6 t' R
timer_header = timer_header->next;
1 L* [" E) ?# ^$ _" H5 E3 D' }5 u
6 }* V- \; J4 p. `: p
(*callback_fptr)();
- a* o: ~7 j8 o$ M  L" ?* y

- @/ W4 \- y: u}
; h7 o1 a& b8 w

" e$ s5 o# ~* Y

) ~! v. r9 b( k) N}
8 y3 C# ?' M& J; n///////////////////////////////////////////////////
4 b7 Z$ b) J% a4 B, w) _$ |
  p* M6 k" n7 G; u
7 [4 A6 P6 U" u3 C1 y
上述code,我已经导入并开始测试了,短短几十行代码大大改善了我的code base的感官,降低了代码的耦合度,现在看上去清爽多了J!  \6 J: z* A8 Z; {: [) o, \

4 `7 U& b% c, ^1 C4 B8 j# d- [野人献曝,博君一笑
3 x% ^  J$ a, ]6 I( ~
; D: L8 C3 b9 o6 u2 |Peter- d) i( t  X" M4 d( r- l+ `3 Q$ g
  , J6 R* I! M0 @3 m  c

9 e  E, a. l/ X7 E[ 本帖最后由 peterhu 于 2009-4-20 09:51 编辑 ]
您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

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

GMT+8, 2026-3-5 17:41 , Processed in 0.057696 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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