嵌入式操作系统内核原理和开发(信号量)-2

上一篇 / 下一篇  2012-09-17 15:19:16 / 个人分类:杂谈

51Testing软件测试网 ^&F N`1Y0Ru |@

  上面的get函数看上去比较复杂,但是所有的同步函数基本上都是这样的设计的,看多了反而有一种八股文的感觉。刚开始看的同学可能觉得不是很习惯。不要紧,每天多看两眼,时间长了就ok了。好了,接着我们继续去卡看信号量的释放函数是怎么处理的,大家做好心理准备哦,

0ccqg,T%Bu;A3?v051Testing软件测试网5N0N0k+J%T!P ?.O ?

51Testing软件测试网_1Au9Z]!l|*H%^ Y

51Testing软件测试网!L*TJe4\)wy1@

static RAW_U16 internal_semaphore_put(RAW_SEMAPHORE *semaphore_ptr, RAW_U8 opt_wake_all)
N-pj!T3x$n0{
je,V2gTR0@A0 LIST *block_list_head;51Testing软件测试网8X:KiwM&Nz&pd
 51Testing软件测试网i|0g$bHN
 RAW_SR_ALLOC();
51Testing软件测试网3SszD:w?TD(g}

Waj&fhXj8J3W0 #if (RAW_SEMA_FUNCTION_CHECK > 0)
D2OKy,J!h0 51Testing软件测试网*vV,bW^8}
 if (semaphore_ptr == 0) {51Testing软件测试网Qs%}CM3?9MxC
  51Testing软件测试网!j/un$wL [8i
  return RAW_NULL_OBJECT;51Testing软件测试网P-J |H7THM
 }
8q7?@[0?5?$[f0 
}6]F,kz&b M0 #endif
51Testing软件测试网)C+z%I2VnbG%V

51Testing软件测试网kR$M`/e%n'k

 block_list_head = &semaphore_ptr->common_block_obj.block_list;
\xl(b+P0 51Testing软件测试网8I6z,y's,@r$r {u
 RAW_CRITICAL_ENTER();51Testing软件测试网Z3}a+xp6t
 /*if no block task on this list just return*/51Testing软件测试网q!FE.o,j C R'Ij
 if (is_list_empty(block_list_head)) {       51Testing软件测试网L MAy3qH
    51Testing软件测试网msca E$w
  if (semaphore_ptr->count == 0xffffffff) {
51Testing软件测试网5f9O&|7Z*V z

*XT*G*`.~;Z*B/H:^aZ0   RAW_CRITICAL_EXIT();
vI'OhN;M0   return RAW_SEMOPHORE_OVERFLOW;

^,N8p(F C8G0

+ig P3Ek!@;`0  }51Testing软件测试网B'pJAY] o
  /*increase resource*/51Testing软件测试网9K,Z3?)[}
     semaphore_ptr->count++;                                     
D%c5__;NT5y/QF"]0j0    51Testing软件测试网@4RQb^%m`
     RAW_CRITICAL_EXIT();
o#]v VxCN_a0     return RAW_SUCCESS;51Testing软件测试网 B5\/Jd a eWG
 }

7P%L z V\Nd bV0

d-xD2wrM*nyZ{0 /*wake all the task blocked on this semphore*/51Testing软件测试网-J2X;cdI
 if (opt_wake_all) {

-Jy9`m;M ? B051Testing软件测试网iVLb.~VI/j

  while (!is_list_empty(block_list_head)) {51Testing软件测试网Klqm&O^R
   raw_wake_object(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list));
})V"yA1Hfc0  }

sk&Rea G7O0

dM[:Pajx0 }

i!s E1q L?8L0

8NA$Y o`9L0 else {
:R(Vv7E/mNkZy0  51Testing软件测试网k*@Qki&^7f/nq6_
  /*Wake up the highest priority task block on the semaphore*/51Testing软件测试网(J-F)S4UJ @9v
  raw_wake_object(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list));
)J/V!iLA)G\0 }51Testing软件测试网#IU8Mdz&b,qa%N2hh
 51Testing软件测试网J WRa@a3@
 RAW_CRITICAL_EXIT();

u!E2{B8[P+t'o0

@x-d%Pi6emH0 raw_sched();   51Testing软件测试网8H Q L]*d h5`\A

4c+P%V9LQ~ @;}0 return RAW_SUCCESS;51Testing软件测试网z#Y0Y&Y TlfbN\Z
}

1Z ^A/u4I6`G0
51Testing软件测试网&k7b Dv8pM2m}

  看上去,信号量的释放函数也比较长,不管只要有耐心,都是可以看明白的,我们就来具体分析一下,

-G/G?qB cO6_u0

/kj}7GV?+eGD5M0  (1)判断参数的合法性;51Testing软件测试网?(KC+a7a.m

51Testing软件测试网H7|L'h@&`o

  (2)判断当前是否有等待队列,如果没有,则count自增,函数返回,当然如果count达到了0xffffffff也要返回,不过概率极低;51Testing软件测试网(oj4yn"fB-w

51Testing软件测试网,hc"c V6mBF

  (3) 当前存在等待队列,根据opt_wake_all的要求是唤醒一个线程还是唤醒所有的线程;51Testing软件测试网Hd6v5A}

^/g`J/u|'I0  (4)调用系统调度函数,让高优先级任务及时得到运行的机会;51Testing软件测试网Ub"vcm*R3i

3I"f MY#Xk!\y/P0  (5)当前线程再次得到运行的机会,函数返回。51Testing软件测试网 U LQ5S-F}v7O

51Testing软件测试网 A(_cW{

 有了上面的讲解,我们发现os的代码其实也没有那么恐怖。所以,请大家一鼓作气,看看信号量是怎么删除的吧,51Testing软件测试网R3fNi#kS#Y1m

51Testing软件测试网;v!WI(c#q/R m-R5BC&oXQ

mt)bl{S0
51Testing软件测试网:~6w/R@P7J!H&aR

RAW_U16 raw_semaphore_delete(RAW_SEMAPHORE *semaphore_ptr)
-D Qn"} B2H&{){0{51Testing软件测试网2H2G#f(LtR+iT
 LIST *block_list_head;
4i(x)_"U8pj0 51Testing软件测试网 y~)V%U N I
 RAW_SR_ALLOC();
51Testing软件测试网M+r$HWGt

51Testing软件测试网`ah+R] l)o K)Lk

 #if (RAW_SEMA_FUNCTION_CHECK > 0)
T JGU!~/S0 
;h!jRr7A0 if (semaphore_ptr == 0) {51Testing软件测试网aA&lOUg
  51Testing软件测试网os)RB[6`I.F.H
  return RAW_NULL_OBJECT;
&M[AU,F"e8|-r0 }
O @5t^ SMLJ*Y6i0 
6s7C_"X/Fhd0 #endif
51Testing软件测试网u I5} ksa:r

@eS P)_+O,e+F9i0 block_list_head = &semaphore_ptr->common_block_obj.block_list;51Testing软件测试网0a+}'T#nH+`A
 
7I}7]-Q/z9wR0 RAW_CRITICAL_ENTER();
51Testing软件测试网V1q-a`"bZT

x:c8W4e;V ?1B"@0 /*All task blocked on this queue is waken up*/51Testing软件测试网+l6k#?cjI:v
 while (!is_list_empty(block_list_head)) {51Testing软件测试网#m9M}+E%leUm\8W
  delete_pend_obj(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list)); 
p6z&jW/?"J(C&B0 }                            
51Testing软件测试网 C,Ls;? ^N8~7^

ko;{ UO'~6Wz O0 RAW_CRITICAL_EXIT();51Testing软件测试网A"}FK^+g
 raw_sched();51Testing软件测试网QZWh;U)d1b%{~y;y
 return RAW_SUCCESS;51Testing软件测试网M6D${V9? k_Pm
}

)^2dN sl e,l0

7Lo+q2Lgo~0  信号量删除的工作其实很少,也很简单,同样我们也来梳理一下,51Testing软件测试网?yrp:^

51Testing软件测试网B(o7S6@y-j'J;D

  (1)判断参数合法性;51Testing软件测试网\;}W%Oi#e

S4_l&oUE0  (2)唤醒阻塞队列中的每一个线程;

5S%|fq2[AOJ051Testing软件测试网 eYq_2k

  (3)调用系统调度函数,因为高优先级的任务很有可能刚刚从阻塞队列中释放出来;

7qL#a,kK051Testing软件测试网O$f:cvzs"[x"x

  (4)当前线程再次运行,函数返回。51Testing软件测试网W%o$g.Gjr*K:P

51Testing软件测试网DUc$rG/b*B

  通过上面几个函数的讲解,我们发现关于os互斥部分的代码其实也不复杂。只要对系统本身和中断有一些了解,其实代码都是可以看懂的。当然,上面的代码我们还是讲的比较粗糙,所以有些细节还是要补充一下,

Dl7Yo6w:}/I#E)qnb051Testing软件测试网8o]|M/ND\

  (1)多线程共享的函数必须在关中断的情况下进行操作,当然多核的时候关中断也不好使了;

A*yVI#Y+u7F] j0

L!{e_1?^8x0  (2)实时系统的抢占是每时每刻都在进行的,比如中断返回时、信号量释放时、调用延时函数、调用调度函数的时候,所以大家心中要有抢占的概念;51Testing软件测试网 c:d(k!B;N

51Testing软件测试网 `S`-y.j!@2lX P&oT

  (3)互斥函数中大量使用了链表的结构,建议大家好好掌握链表的相关算法;51Testing软件测试网I U]s'j io2m X5u

51Testing软件测试网EoQcA6Dq

  (4)关于os的代码一定要多看、多思考、多练习才会有进步和提高,纸上得来终觉浅、绝知此事要躬行。51Testing软件测试网9?7zw~%X)d

相关链接:

j8v+K$o$K%SX0

嵌入式操作系统内核原理和开发(开篇)51Testing软件测试网/pfW;`s(A"B

嵌入式操作系统内核原理和开发(cpu的那些事)

+hcR_O+E0

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

2d ~au#]cW0

嵌入式操作系统内核原理和开发(地址空间)

R k_E[V0

嵌入式操作系统内核原理和开发(系统中断仿真)51Testing软件测试网Su!e e0uNT5\r`)xQ

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

0n{,R$nB8M6a"{0

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

UZOq!lQAu0

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

d7hF{jq#~4O0

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

5j8BDu%QDO-o$k}0

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

_X+G!VlT@0

嵌入式操作系统内核原理和开发(头文件调整)51Testing软件测试网)vu/eA'Xa.M osd

嵌入式操作系统内核原理和开发(内存分配算法)

'[QN+d K$wX0

嵌入式操作系统内核原理和开发(固定内存分配算法)

A.NZh(Au$Tnw0

嵌入式操作系统内核原理和开发(基于链表节点的内存分配算法)51Testing软件测试网Oi.f!H%Zr

嵌入式操作系统内核原理和开发(最快、最优、最差内存分配算法)51Testing软件测试网 {"Y$|0Trm


TAG:

 

评分:0

我来说两句

Open Toolbar