Chinaunix首页 | 论坛 | 博客
  • 博客访问: 32123
  • 博文数量: 20
  • 博客积分: 385
  • 博客等级: 一等列兵
  • 技术积分: 220
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-02 19:40
文章分类

全部博文(20)

文章存档

2016年(12)

2011年(2)

2009年(2)

2008年(4)

我的朋友

分类: LINUX

2011-04-13 19:37:43

内核同步之 SpinLock2.6.18/i386):

相关内核源文件说明

/*

 * include/linux/spinlock.h - 通用的 spinlock/rwlock 声明

 *

 * here's the role of the various spinlock/rwlock related include files:

 *

 * on SMP builds:

 *

 *  asm/spinlock_types.h: 包括 raw_spinlock_t/raw_rwlock_t 类型定义和初始化方法

 *

 *  linux/spinlock_types.h:定义通用的类型和初始化方法

 *  asm/spinlock.h:       包含 __raw_spin_*()/etc. 这些个底层的实现,多数是汇编代码

 *

 *   (也被引用在 UP-debug builds:)

 *

 *  linux/spinlock_api_smp.h: 包含_spin_*() APIs的原型

 *

 *  linux/spinlock.h:     建立最终的 spin_*() APIs.

 *

 * on UP builds:

 *

 *  linux/spinlock_type_up.h:

 *                        包含通用的、简单的UP spinlock类型

 *

 *  linux/spinlock_types.h:

 *                        defines the generic type and initializers

 *

 *  linux/spinlock_up.h:

 *                        contains the __raw_spin_*()/etc. version of UP

 *                        builds. (which are NOPs on non-debug, non-preempt

 *                        builds)

 *

 *   (included on UP-non-debug builds:)

 *

 *  linux/spinlock_api_up.h:

 *                        builds the _spin_*() APIs.

 *

 *  linux/spinlock.h:     builds the final spin_*() APIs.

 */

两种情况:

一、SMP、支持抢占

1、结构

/*=========spinlock_t===================*/

typedef struct {

    volatile unsigned int slock;

} raw_spinlock_t;

 

typedef struct {

    raw_spinlock_t raw_lock;

#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)

    unsigned int break_lock;

#endif

#ifdef CONFIG_DEBUG_SPINLOCK

    unsigned int magic, owner_cpu;

    void *owner;

#endif

#ifdef CONFIG_DEBUG_LOCK_ALLOC

    struct lockdep_map dep_map;

#endif

} spinlock_t;

 

/*=========rwlock_t===================*/

typedef struct {

    volatile unsigned int lock;

} raw_rwlock_t;

 

typedef struct {

    raw_rwlock_t raw_lock;

#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)

    unsigned int break_lock;

#endif

#ifdef CONFIG_DEBUG_SPINLOCK

    unsigned int magic, owner_cpu;

    void *owner;

#endif

#ifdef CONFIG_DEBUG_LOCK_ALLOC

    struct lockdep_map dep_map;

#endif

} rwlock_t;

 

2、接口举例

a),

spin_lock

#define spin_lock(lock)         _spin_lock(lock)

 

void __lockfunc _spin_lock(spinlock_t *lock)

{

    preempt_disable(); /*禁止抢占*/

    spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);

    _raw_spin_lock(lock); /* 请求锁 */

}

# define _raw_spin_lock(lock)        __raw_spin_lock(&(lock)->raw_lock)

static inline void __raw_spin_lock(raw_spinlock_t *lock)

{

    asm(__raw_spin_lock_string : "+m" (lock->slock) : : "memory");

}

 

#define __raw_spin_lock_string \

    "\n1:\t" \

    LOCK_PREFIX " ; decb %0\n\t" \

    "jns 3f\n" \

    "2:\t" \

    "rep;nop\n\t" \

    "cmpb $0,%0\n\t" \

    "jle 2b\n\t" \

    "jmp 1b\n" \

    "3:\n\t"

/*

   lock->slock的值减一,判断是否为负(jns指令判断SF标志),若非负(占有锁),跳到标号3  处,退出;若为负(等待锁),执行标号2处的代码,循环执行空指令,并比较slock0的值,如果小于等于0,继续循环,否则(锁的持有者已经释放它,slock的值被设置为1,见下边unlock)跳到标号1处,重新尝试获取锁。

*/

 


(b)

spin_unlock

# define spin_unlock(lock)        _spin_unlock(lock)

void __lockfunc _spin_unlock(spinlock_t *lock)
{
    spin_release(&lock->dep_map, 1, _RET_IP_);
    _raw_spin_unlock(lock);/* 释放锁 */
    preempt_enable();/* 开启抢占 */
}

# define _raw_spin_unlock(lock)        __raw_spin_unlock(&(lock)->raw_lock)

static inline void __raw_spin_unlock(raw_spinlock_t *lock)

{

    char oldval = 1;

    __asm__ __volatile__(

        __raw_spin_unlock_string

    );

}


#define __raw_spin_unlock_string \

    "xchgb %b0, %1" \

        :"=q" (oldval), "+m" (lock->slock) \

        :"0" (oldval) : "memory"

/* 把slock的最后字节设置为1 */

(c)
spin_trylock

static inline int __raw_spin_trylock(raw_spinlock_t *lock)

{

    char oldval;

    __asm__ __volatile__(

        "xchgb %b0,%1"

        :"=q" (oldval), "+m" (lock->slock)

        :"0" (0) : "memory");

    return oldval > 0;

}

 

/*

倘若如上的锁机制用在不支持抢占和只有一个处理器的系统中,会导致死锁(请求者空转,占有者没机会释放锁),所以在UP系统中建立的spinlock锁大不一样(空空如也)。

*/

二、UP,不支持抢占

// include/linux/spinlock_types_up.h

Typedef strutc { } raw_spinlock_t;

 

Typedef struct { }raw_rwlock_t;

 

// include/linux/spinlock_api_up.h

 

#define _spin_lock(lock)    __LOCK(lock)

 

#define _spin_trylock(lock) ({ __LOCK(lock); 1})

 

#define _spin_lock_irq(lock)  __LOCK_IRQ(lock)

 

#define __LOCK_IRQ(lock) \

  Do{local_irq_disable(); __LOCK(lock); } while(0)

 

//禁止抢占

#define __LOCK(lock) \

  Do { preempt_disable(); __acquire(lock); (void)(lock); } while(0)

 

#define _spin_unlock(lock)  _UNLOCK(lock)

 

#define __UNLOCK(lock) \

  Do{ preempt_enable();  __release(); (void)(lock); } while(0)

 

阅读(557) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:内核同步之 semaphore

给主人留下些什么吧!~~