第17章 互斥量的设计与实现

本文探讨了x86架构中实现互斥的方法,包括禁用中断和使用专用机器指令如xchg和testset指令。介绍了IA-32处理器如何通过LOCK#信号确保内存操作期间的互斥,并展示了如何利用xchg指令实现简单的互斥锁。
当所有的任务在同个单一地址空间下,使用共享资源时,必然涉及到共享资源的竞争。只有多个任务互斥地访问共享资源时才不会发生错误。只有提供互斥或信号量才能保证内核并发机制。

任何互斥尝试必须基于一些基础硬件互斥机制。最常见的这种约束是某一时刻对内存的一次访问。(intel处理器可以查看《IA-32架构软件开发人员指南 卷3 系统编程指南》中7.1节 加锁的原子操作)

x86上实现互斥,需要硬件的支持:
1、中断禁用。代价高,在单CPU上能使用。在多CPU上不能使用(多处理器中,是对等关系,没有支持互斥的中断机制)。
2、专用机器指令:在一个指令的执行周期内对一个存储单元的读和写(xchg) 或 测试和设置(testset)。在该指令的执行过程中,任何其他指令访问内存将被阻止。

IA-32处理器提供了LOCK#信号。这个信号会在某些内存操作过程中被自动发出。当做这个输出信号发出的时候,来自其他处理器或总线代理的总线控制请求将被阻塞。软件能够利用在指令前添加LOCK前缀来指定,在其他情况下也需要LOCK语义(LOCK semantices)。

在Intel 386 ,Intel 486,Pentium处理器中,直接调用加锁的指令会导致LOCK#信号的产生。硬件的设计者需要保证系统硬件中LOCK#信号的有效性,以控制多个处理器对内存的访问。对与Pentium 4,Intel Xeon,以及P6系列处理器,如果被访问的内存区域存在于处理器内部的高速缓存中,那么LOCK#信号通常不被发出;但是处理器的缓存却要被锁定。

xchg指令会自动的带有LOCK 语义。

mutex.h源代码如下所示
#ifndef	_MUTEX_H_
#define _MUTEX_H_

typedef unsigned long mutex_t;

static inline unsigned long xchgl(unsigned long x, unsigned long *ptr)
{
    __asm__ __volatile__("xchgl %0,%1\n\t"
        :"=r"(x)
        :"m"(*ptr),"0"(x)
        :"memory"
        );
    return x;
}

/*mptr是mutex_t的指针*/
#define lock(mptr) ({\
    while(xchgl(1,(mptr)));\
})

/*mptr是mutex_t的指针*/
#define unlock(mptr) xchgl(0,(mptr))


/*mptr是mutex_t的指针*/
#define init_mutex(mptr) ({*mptr = 0;})


#endif



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值