嵌入式操作系统内核原理和开发(抢占式优先级调度)

上一篇 / 下一篇  2012-06-14 09:23:57 / 个人分类:杂谈

上面的一篇博客说到了优先级调度,但是那个优先级调度算法比较极端。打个比方说,现在王先生有三个小孩,分别是老大、老二、老三。假设现在到了饭 点,王先生需要给三个小孩喂饭。此时如果是时间片轮转的话,那么就是绝对公平,王先生每人一口不停地进行喂饭。如果是优先级调度,那么王先生首先自己有一 个优先级考量,比如说三个小孩按照年龄顺序优先级是逐渐提高的,毕竟小孩需要更多的照顾嘛。这个时候如果需要进行喂饭的话,那么王先生需要首先伺候好最小 的那个小孩老三,才会有时间照顾老二,至于老大什么时候才能得到照顾那就看造化了。

)gM%_7iDA(H0  现在,我们打算重新换一种方法。假设三个小孩的优先级分别是1、2、3,其中年龄越小优先级越高,3代表高优先级。接着,我们按照优先级给三个小孩安排时间片,分别是1、2、3。同时,这个时间片不光代表了当前可用的剩余时间,还代表了小孩此时的临时优先级。51Testing软件测试网$|Lvq6m6E

51Testing软件测试网)KEri gApM6`

  (1)首先王先生给老三喂饭,时间片降低1,即临时优先级为2;51Testing软件测试网 X MacN8{~6Vy

#Eu-U2Cy/E|l q(ddEK0  (2)接着王先生判断当前优先级最高的仍为老三,毕竟老二的优先级也没有超过老三,所以老三的时间片降1,临时优先级为1;

D A5H$^ ts0

H hx;[}6\0  (3)王先生获知当前优先级最高的为老二,老二获得时间片;51Testing软件测试网 x5q;} c#}(?nK5P${

*H+CVs6G b0  (4)此时王先生发现三个孩子的临时优先级都一样,那么就会按照固定优先级的大小依次对老三、老二、老大进行喂饭。

lqik1g ]xm051Testing软件测试网GE;p `*^7k*w

  我们发现,这中间受益最大的就是老二。当然,我们可以做进一步推论,如果老王的孩子越多,那么优先级处于中间的孩子在时间片的分配上将更加均匀,响应也会更加及时,交互性也会变得很好。51Testing软件测试网'v)["[ g8L ?]$F2xJ }

i Fa?pN0  根据以上的想法,我们重新改写了优先级调度算法,修改为抢占式优先级调度算法,51Testing软件测试网'K;HLbh"T8j{-`

PaF5{ c5F B0

w,EPd#kaG$~_l0

$d&|7gJ^6@0int find_next_thread()
.?DL ?%@S0{51Testing软件测试网+AX6Z9ij5s,yc1[]
    int index;
Ii'j6H]1cO0S0    int choice = THREAD_MAX_NUMBER -1;
i_"C8t0KGc0    int value = gAllTask[choice].time_slice;
51Testing软件测试网y@@6D0gVp_

-N:AT#`"M9Cs%f0    for(index = choice -1; index >= 0; index --)
-S5Q8Jn,a/t8^8|o0    {51Testing软件测试网n`4LWdE
        if(value < gAllTask[index].time_slice)
m_$p Z(Swu-A0        {51Testing软件测试网d,_l5q4s
            choice = index;51Testing软件测试网 __8A \.u5l
            value = gAllTask[index].time_slice;
w$IN"Uy&W#_d0        }
"D3d K.Q{uP0    }
51Testing软件测试网:ZwLAb

1e,Z9v}%ke!~ \,y9D0    if(0 == value)
Ul:]XhN_3U0        choice = -1;

T K6Q~U4dY#LZ0

C!@Dl.Y0    return choice;     
&z,{7Z3c1[D!y0}
51Testing软件测试网GYp#hOM~*Q

51Testing软件测试网yl)e$f u u:Q

  当然,加上原来的时间片轮转调度、通用优先级调度方法,此时就存在三种调度方法了。我们可以自己设置宏,通过宏的设置灵活选用调度算法,51Testing软件测试网7}W.K8lx d {G

51Testing软件测试网:f ^KUY r

51Testing软件测试网!R$wnp+j3B

#define TIME_ROUND_SCHEDULE     0
8As1Z.A'z,ao:|9X0#define HARD_PRIORITY_SCHEDULE  0
(Oto"Ae IPWg8r8CXj0#define SOFT_PRIORITY_SCHEDULE  1
d6G)w3o1J2|U0这些代码都是可以在系统中共存的。选用什么算法,取决于实际情况是什么样的情形。

9K1N3HWx6[]J5K0

;sNi Z5nd0

-t9C,YLP7D4el0#include <stdio.h>
R N[3JVc J%r0#include <time.h>
&@D#mwU)`6eE0#include <stdlib.h>51Testing软件测试网WY&bI)G-g TJ
#include <signal.h>
"t2^"M eVR!YE,Q|0#include <assert.h>51Testing软件测试网i"w+H+I|
#include <string.h>51Testing软件测试网!c U7o5c]0g.e
#include <sys/time.h>

$Rv`du2BB0

!xI kmA V0OK`J"S0#define UINT32 unsigned         int
{1E/^6q(Xb0#define STACK_LENGTH            51251Testing软件测试网EG2{L3F+N
#define THREAD_MAX_NUMBER       10
I Bv;pDY;O\6m0#define TIME_ROUND_SCHEDULE     0
hptia4V0#define HARD_PRIORITY_SCHEDULE  0
~ X:a `2oA?iy0#define SOFT_PRIORITY_SCHEDULE  1 

5dIv"PR(@.H&C051Testing软件测试网ReaU,YK4J$w

typedef struct _TASK_INFO
X7K@+zV,k%F9c`r0{
8D*MMW0NPj!X;A0    UINT32 id;51Testing软件测试网2r1J.w$? j4_.G1y@$u
    UINT32* stack;51Testing软件测试网 }8{-x.Le
    UINT32 size;
tL;gOs+y"hA%mQ0    UINT32 context;51Testing软件测试网 vE2VFK&E6p#{3SS/`1f
    UINT32 priority;
*@-Wy6P_/S D4P(q$n_0    UINT32 time_slice;51Testing软件测试网9fO%h.}6pu
    void (*func)();
51Testing软件测试网$PC.HV%R\m

51Testing软件测试网``)g x`*?^3y8E

}TASK_INFO;

a k q"_;v#i?A YY~m]0

X*{%Tk"H0static struct itimerval oldtv;
7FLK&B3P g0UINT32 old   = 0;51Testing软件测试网*M"jUUC
UINT32 count = 0;
?;K'f5Ing x a/y6y@0UINT32 task_stack[THREAD_MAX_NUMBER][STACK_LENGTH] = {0};
6_JOA!Z-u a9]S0TASK_INFO gAllTask[THREAD_MAX_NUMBER] = {0};51Testing软件测试网q6N;e8h%x)s`*c
UINT32 current_thread_id = 0;
51Testing软件测试网,?;]+]8l%X|aQ2y

51Testing软件测试网$K!T D#jF

void set_timer()51Testing软件测试网0l'kYQj~[h
{
Ju ES2CJ0        struct itimerval itv;
Z$}o'DOz2I B0        itv.it_interval.tv_sec = 1;51Testing软件测试网"k h bM#D|,L
        itv.it_interval.tv_usec = 0;51Testing软件测试网s3|iz_6^}nZ r eR R
        itv.it_value.tv_sec = 1;51Testing软件测试网 eC${| @/_-q,F
        itv.it_value.tv_usec = 0;
?O4Y4ov'P0        setitimer(ITIMER_REAL, &itv, &oldtv);
UF*d|l"a7^0}
51Testing软件测试网)[H%v}4YDx

d9H A"j/v0void swap(UINT32* prev, UINT32* next)
.o cE%U\q*IV0{
$g;H l;K/YI0    __asm("push %%eax\n\t"51Testing软件测试网/Z0auz bY6sHYXFj
          "push %%ebx\n\t"51Testing软件测试网t[h"F&fi lk
          "push %%ecx\n\t"
'@.iIU7\] XJM)U0          "push %%edx\n\t"51Testing软件测试网M?&F z1| Ol-@
          "push %%esi\n\t"51Testing软件测试网H:gcmz A
          "push %%edi\n\t"51Testing软件测试网VAElB?{ SA
          "push %%ebp\n\t"51Testing软件测试网*n!mx+KUc o8R g
          "push %%esp\n\t"
's R;g9h7k0          "lea 0x8(%%ebp), %%eax\n\t"51Testing软件测试网f!\ W{f:Rb
          "mov (%%eax), %%eax\n\t"51Testing软件测试网{:j.?k)y.J(kJ
          "mov %%esp, (%%eax)\n\t"

rX:|+p/zbo0

Q6CaK`+s*{K)b;b0          "lea 0xc(%%ebp), %%eax\n\t"51Testing软件测试网1G)^ ^ f!\c$E7X/Rl9|
          "mov (%%eax), %%eax\n\t"51Testing软件测试网eh4tL @8aD
          "mov (%%eax), %%esp\n\t"51Testing软件测试网@/R.n{c+H|*Y%aP8f
          "pop %%esp\n\t"51Testing软件测试网;[`5N"iK
          "pop %%ebp\n\t"
aG/Xoi:[:l u~d0          "pop %%edi\n\t"51Testing软件测试网p [6orI0D_3S-[
          "pop %%esi\n\t"51Testing软件测试网b ^Q&VE8Py.[i
          "pop %%edx\n\t"
v8^lN,s$kJxS0          "pop %%ecx\n\t"51Testing软件测试网a \*}g.sPL1ks
          "pop %%ebx\n\t"51Testing软件测试网:E&j~$M| ABi
          "pop %%eax\n\t"51Testing软件测试网 s ZSm6AC aP
          ::);
})g4odze.ux m0}

3vI5n h4b y{4}0H'U051Testing软件测试网s^q+~3L W

void hello()51Testing软件测试网IQ8nNL
{
O#{y,k ~-M{0        int temp = 0;
51Testing软件测试网4j8U:nb+K:zJ

51Testing软件测试网rP+\(E8['~v

        while(1) {
b1j5V jGx0            printf("id = %d, temp = %d, count = %d in thread!\n",current_thread_id,  temp ++, count ++);51Testing软件测试网6LQ|f[CF
            swap(&gAllTask[current_thread_id].context, &old);

4q`%\.b7l/|1Ie&p l0

"Qj3Y{7x cJs]0            printf("id = %d, temp = %d, count = %d in thread!\n",current_thread_id,  temp ++, count ++);
r+T x.}i0            swap(&gAllTask[current_thread_id].context, &old);
My3Rr'e qgT0        }51Testing软件测试网"} |Tmi2~8^*yl
}
51Testing软件测试网?[Y |p*i0H

51Testing软件测试网@}3D b*sQ\:^

#if HARD_PRIORITY_SCHEDULE51Testing软件测试网 B*^ krP
int find_next_thread()
1w)[-N8I9W0{
.zt[Vz:v}L5E'Uv'G0    int index;
51Testing软件测试网:gN0~Y eA$j2z!Y

51Testing软件测试网U O%DWG+H

    for(index = THREAD_MAX_NUMBER -1; index >=0; index --)
Js(E,x/v~0    {51Testing软件测试网c(sCgc1w4_
        if(0 != gAllTask[index].time_slice)
8e8n e3s_)w R6Fi0            break;51Testing软件测试网{[1f4kM,u
    }

!vM5|{Ip0

Ha!]w G0    return index;     
w3Y X&wVh%T*G0}
51Testing软件测试网7X%GJ9yI

^,w6W3qf0#endif

-Z[:x4h kw9{,GR;a051Testing软件测试网jc6{)]+Md+Y7bZ

51Testing软件测试网jI,Qk![
#if SOFT_PRIORITY_SCHEDULE51Testing软件测试网&{Z Q7K vI ]e
int find_next_thread()51Testing软件测试网't6[,C#}`h7V2k
{51Testing软件测试网R3W!k7c-b1c(\
    int index;51Testing软件测试网dZx2_3j)h*E C9z
    int choice = THREAD_MAX_NUMBER -1;51Testing软件测试网0C_/@8h g?m{
    int value = gAllTask[choice].time_slice;

3b}6Q-Y[ ID+Me0

} R*V6LN^0@&|q|0    for(index = choice -1; index >= 0; index --)
-{-R1jMh1Y'gTc-H0    {51Testing软件测试网R7G NQ-ju\1O
        if(value < gAllTask[index].time_slice)
3DH%p&p)Tk:v0        {51Testing软件测试网 i H4qV[,Bt {S@(j
            choice = index;51Testing软件测试网H `i(t)H#UE*W[
            value = gAllTask[index].time_slice;51Testing软件测试网j9@p0B9L:[
        }
t\7Mz3}E(k;Z!R0    }

J6_/fBaY0

'VzTo0~[0    if(0 == value)51Testing软件测试网!T p1zBO*B7z
        choice = -1;

#n$UR2X} P/T@051Testing软件测试网U&D"FV D4wijR

    return choice;     
eo1ZN3j f7K+`0}
51Testing软件测试网/ZM(W/D)c*GTZ

51Testing软件测试网i"eb-e0{3t

#endif

i#`\v ^#iS7[P8{ c051Testing软件测试网&C1ON'Dq3E9VF$Py

void reset_time_slice ()
U0@9Ba'Rxw0{
EY-b{ B0    int index;
51Testing软件测试网#h!^9Z`"L'h6w

51Testing软件测试网 [oT,i*_{Z[%{

    for(index = 0; index < THREAD_MAX_NUMBER; index++)
$|)i,o;S1ij3^0        gAllTask[index].time_slice = gAllTask[index].priority + 1;
`:ERt@D/i |0}

+{-`%N{J.mm+O9w.z,O051Testing软件测试网;a d~Sj

void task_init(int index)
[1Zc4V$Dp8fi`0{51Testing软件测试网Soa }(lK
        UINT32 unit = gAllTask[index].size;
qvIW,f3Hi0        UINT32* pData = gAllTask[index].stack;

fVt nN$PV4_0

jCe!L%j'dq U1}0        memset((void*)pData,(int) 0, unit * sizeof(UINT32));51Testing软件测试网0g5ae gG0}Aa Z
        pData[unit -1] = (UINT32) gAllTask[index].func;51Testing软件测试网5N7DQ$a^c$s(G3R
        pData[unit -2] = 0;51Testing软件测试网0M.UC+O].e;u"j
        pData[unit -3] = 0;51Testing软件测试网CE? E F(|~B
        pData[unit -4] = 0;51Testing软件测试网.cNvw7Q~c l
        pData[unit -5] = 0;51Testing软件测试网0@-?@q+?B:I
        pData[unit -6] = 0;
+M0}'Lc O-y O$j0        pData[unit -7] = 0;51Testing软件测试网qZ[{ w,hs
        pData[unit -8] = 0;51Testing软件测试网o{Z l0r ^
        pData[unit -9] = 0;51Testing软件测试网0~:E1_.o m LK
        pData[unit -10] = (UINT32) &pData[unit - 9];
L)UDt_(~0        gAllTask[index].context = (UINT32) &pData[unit -10];
Tm;BN6F0}
51Testing软件测试网.Qxi,m.[ hoW7H

51Testing软件测试网+b U9cx:_zw

#if TIME_ROUND_SCHEDULE
7n"[C&Z~:OY]D0void signal_handler(int m)51Testing软件测试网@0O E@t*Nt/e\
{
$h"M?y]En9V0        current_thread_id = current_thread_id % THREAD_MAX_NUMBER;
cM`j2}3eNVg0        swap(&old, &gAllTask[current_thread_id].context);
m;M Z6l7a+s9h;I0        current_thread_id ++;
"Fg/M@a3cFb0}

+I$Wbm3I _0

9@?'UC4|1^qYR M5VR0#else51Testing软件测试网/Guo(h7|G
void signal_handler(int m)51Testing软件测试网_A^N1GEc
{51Testing软件测试网$LTjOCL\B
        int index;
51Testing软件测试网o-@%a/A.r

O Cg Y+U1[e1E"X%LWx0start:
;P L.zh@&?"o0        index = find_next_thread();
i6ffmL9c u_'JO0        if(-1 == index)51Testing软件测试网/i6^aga\l
        {51Testing软件测试网K!OA'lN%E.J`.X
            reset_time_slice();51Testing软件测试网,Cul-cK,ed/{)t
            goto start;51Testing软件测试网P@ S?7jU
        }

cZ~D9Q6A mFT0

-J AZ&N%Z u*['FH0        gAllTask[index].time_slice --;
juF'`_C0        current_thread_id = index;51Testing软件测试网9R_ir5t gT
        swap(&old, &gAllTask[current_thread_id].context);
+|hu3|%d.T0}51Testing软件测试网Q*v4S6KO$d$o&|6n8]5kR
#endif
51Testing软件测试网,A*hJwg

jnH*e4KLO!T051Testing软件测试网IJhT ?k
void set_all_task() 
ht$k}_3tp~:UM8oe0{51Testing软件测试网m3n U+kt
        int index;
BMR(H(j!S3t3X&K0        memset(gAllTask, 0, sizeof(gAllTask));

-x"\&GLp0

0EmRc RU0        for(index = 0; index < THREAD_MAX_NUMBER; index ++)51Testing软件测试网1]9\]Y%gVOEP Z
        {51Testing软件测试网-h5pE4x6Zf5S9A
            gAllTask[index].id = index;51Testing软件测试网4DW|:xTLF
            gAllTask[index].stack = task_stack[index];51Testing软件测试网 wg[N1e)C7[!u
            gAllTask[index].size = STACK_LENGTH;51Testing软件测试网hCF#V.^F
            gAllTask[index].context = 0;
D)g!qH$f2]YR0            gAllTask[index].func = hello;
,R J[`s2DB3e-X8d0            gAllTask[index].priority = index;51Testing软件测试网 Y9V!qRrJo6t
            gAllTask[index].time_slice = index + 1;

PcK/|-S1D)}.N4_051Testing软件测试网1m Z(}"[?-K Du C

            task_init(index);
W8\0i;iaT K9q0        }
L{\J\ UexaQ*r+o0}
51Testing软件测试网,l.h&n1~7p6X)c!?2q+O(P

6\ j5R Av h%`6v[%G9P0int main()51Testing软件测试网8jdxh0Fh'm{
{51Testing软件测试网)i#iJ$R8~Z8l
        char val;

0Uv"diK0

e-U.ZUzD+h0        set_all_task();51Testing软件测试网 P.p Du [)P
        set_timer();
-p?8WxW,X tw!F'L0        signal(SIGALRM, signal_handler);
51Testing软件测试网5u+A5rE:@ |

p7K w~R h!z| U9?0        while(1)51Testing软件测试网\V;LFJ w
        {51Testing软件测试网0O)t"e$g8\2E2^"@n+x
            scanf("%c", &val);51Testing软件测试网-CQ0c+L#XM6T |&K*p
        }
51Testing软件测试网?wX.c)q0n1Jr7Uaw

f*Zt&W E4Hy b&Zk0        exit(0);51Testing软件测试网|{(plxf4W
        return 1;51Testing软件测试网0@-Rg6M j qZ
}

]x6Anie0

相关链接:51Testing软件测试网 So ?-K3xC#a

嵌入式操作系统内核原理和开发(开篇)

/~n/B['cS"_;X0

嵌入式操作系统内核原理和开发(cpu的那些事)51Testing软件测试网Yc1x wA3w%O!sf

嵌入式操作系统内核原理和开发(中断)51Testing软件测试网BQ` b7Ci2B

嵌入式操作系统内核原理和开发(地址空间)51Testing软件测试网g\Qu.u7g2AfS

嵌入式操作系统内核原理和开发(系统中断仿真)51Testing软件测试网w4s*b.Qs`"L

嵌入式操作系统内核原理和开发(线程切换)

F(g Hv6|(d)F#Kc0K&]0

嵌入式操作系统内核原理和开发(任务创建和堆栈溢出检查)

\3|0?c4S:T0

嵌入式操作系统内核原理和开发(多线程轮转)

Yj Ns'E0

嵌入式操作系统内核原理和开发(通用优先级调度)51Testing软件测试网A/Y-W[u7b8j3B0E.Y


l^W Gr,v%d0

TAG:

 

评分:0

我来说两句

Open Toolbar