设备驱动程序学习笔记(3)-同步机制快速参考

By:             潘云登

Date:          2009-6-1

Email:         intrepyd@gmail.com

Homepage: http://blog.csdn.net/intrepyd

Copyright: 该文章版权由潘云登所有。可在非商业目的下任意传播和复制。

对于商业目的下对本文的任何行为需经作者同意。


写在前面

1.          本文内容对应《linux设备驱动程序》第五章。

2.          参考《linux内核设计与实现》。

3.          希望本文对您有所帮助,也欢迎您给我提意见和建议。


同步机制快速参考

 

同步机制

信号量

头文件

<asm/semaphore.h>

类型

struct semaphore;

静态声明

DECLARE_SEMAPHORE_GENERIC(name, count);

DECLARE_MUTEX(name);

DECLARE_MUTEX_LOCKED(name);

动态初始化

void sema_init(struct semaphore *sem, int val);

void init_MUTEX(struct semaphore *sem);

void init_MUTEX_LOCKED(struct semaphore *sem);

请求

void down(struct semaphore *sem);

int down_interruptible(struct semaphore *sem);

int down_trylock(struct semaphore *sem);

释放

void up(struct semaphore *sem);

示例

/* define and declare a semaphore, named mr_sem, with a count of one */

static DECLARE_MUTEX(mr_sem);

 

/* attempt to acquire the semaphore ... */

if (down_interruptible(&mr_sem)) {

/* signal received, semaphore not acquired ... */

}

 

/* critical region ... */

 

/* release the given semaphore */

up(&mr_sem);

 

同步机制

读写信号量

头文件

<linux/rwsem.h>

类型

struct rw_semaphore;

静态声明

DECLARE_RWSEM(name);

动态初始化

void init_rwsem(struct rw_semaphore *sem);

请求

void down_read(struct rw_semaphore *sem);

int down_read_trylock(struct rw_semaphore *sem);

void down_write(struct rw_semaphore *sem);

int down_write_trylock(struct rw_semaphore *sem);

释放

void up_read(struct rw_semaphore *sem);

void up_write(struct rw_semaphore *sem);

void downgrade_write(struct rw_semaphore *sem);

示例

static DECLARE_RWSEM(mr_rwsem);

 

/* attempt to acquire the semaphore for reading ... */

down_read(&mr_rwsem);

 

/* critical region (read only) ... */

 

/* release the semaphore */

up_read(&mr_rwsem);

 

/* ... */

 

/* attempt to acquire the semaphore for writing ... */

down_write(&mr_rwsem);

 

/* critical region (read and write) ... */

 

/* release the semaphore */

up_write(&mr_sem);

 

同步机制

completion

头文件

<linux/completion.h>

类型

struct completion;

静态声明

DECLARE_COMPLETION(my_completion);

动态初始化

init_completion(&my_completion);

请求

void wait_for_completion(struct completion *c);

释放

void complete(struct completion *c);

void complete_all(struct completion *c);

示例

DECLARE_COMPLETION(comp);

 

ssize_t complete_read (struct file *filp, char _ _user *buf, size_t count,

loff_t *pos)

{

    printk(KERN_DEBUG "process %i (%s) going to sleep/n",

           current->pid, current->comm);

    wait_for_completion(&comp);

    printk(KERN_DEBUG "awoken %i (%s)/n", current->pid, current->comm);

    return 0; /* EOF */

}

 

ssize_t complete_write (struct file *filp, const char _ _user *buf, size_t count,

                        loff_t *pos)

{

    printk(KERN_DEBUG "process %i (%s) awakening the readers.../n",

           current->pid, current->comm);

    complete(&comp);

    return count; /* succeed, to avoid retrial */

}

 

同步机制

自旋锁

头文件

<linux/spinlock.h>

类型

spinlock_t;

静态声明

spinlock_t my_lock = SPIN_LOCK_UNLOCKED;

动态初始化

void spin_lock_init(spinlock_t *lock);

请求

void spin_lock(spinlock_t *lock);

void spin_lock_irqsave(spinlock_t *lock, unsigned long flags);

void spin_lock_irq(spinlock_t *lock);

void spin_lock_bh(spinlock_t *lock);

int spin_trylock(spinlock_t *lock);

int spin_trylock_bh(spinlock_t *lock);

释放

void spin_unlock(spinlock_t *lock);

void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags);

void spin_unlock_irq(spinlock_t *lock);

void spin_unlock_bh(spinlock_t *lock);

示例

spinlock_t mr_lock = SPIN_LOCK_UNLOCKED;

spin_lock(&mr_lock);

/* critical region */

spin_unlock(&mr_lock);

 

spinlock_t mr_lock = SPIN_LOCK_UNLOCKED;

spin_lock_irq(&mr_lock);

/* critical section ... */

spin_unlock_irq(&mr_lock);

 

spinlock_t mr_lock = SPIN_LOCK_UNLOCKED;

unsigned long flags;

spin_lock_irqsave(&mr_lock, flags);

/* critical region ... */

spin_unlock_irqrestore(&mr_lock, flags);

 

同步机制

读写自旋锁

头文件

<linux/spinlock.h>

类型

rwlock_t

静态声明

rwlock_t my_rwlock = RW_LOCK_UNLOCKED;

动态初始化

void rwlock_init(rwlock_t *lock);

请求

void read_lock(rwlock_t *lock);

void read_lock_irqsave(rwlock_t *lock, unsigned long flags);

void read_lock_irq(rwlock_t *lock);

void read_lock_bh(rwlock_t *lock);

void write_lock(rwlock_t *lock);

void write_lock_irqsave(rwlock_t *lock, unsigned long flags);

void write_lock_irq(rwlock_t *lock);

void write_lock_bh(rwlock_t *lock);

int write_trylock(rwlock_t *lock);

释放

void read_unlock(rwlock_t *lock);

void read_unlock_irqrestore(rwlock_t *lock, unsigned long flags);

void read_unlock_irq(rwlock_t *lock);

void read_unlock_bh(rwlock_t *lock);

void write_unlock(rwlock_t *lock);

void write_unlock_irqrestore(rwlock_t *lock, unsigned long flags);

void write_unlock_irq(rwlock_t *lock);

void write_unlock_bh(rwlock_t *lock);

示例

rwlock_t mr_rwlock = RW_LOCK_UNLOCKED;

 

read_lock(&mr_rwlock);

/* critical section (read only) ... */

read_unlock(&mr_rwlock);

 

write_lock(&mr_rwlock);

/* critical section (read and write) ... */

write_unlock(&mr_lock);

 

同步机制

原子变量

头文件

<asm/atomic.h>

类型

atomic_t;

相关操作

void atomic_set(atomic_t *v, int i);

atomic_t v = ATOMIC_INIT(0);

int atomic_read(atomic_t *v);

void atomic_add(int i, atomic_t *v);

void atomic_sub(int i, atomic_t *v);

void atomic_inc(atomic_t *v)

void atomic_dec(atomic_t *v);

int atomic_inc_and_test(atomic_t *v);

int atomic_dec_and_test(atomic_t *v);

int atomic_sub_and_test(int i, atomic_t *v);

int atomic_add_negative(int i, atomic_t *v);

int atomic_add_return(int i, atomic_t *v);

int atomic_sub_return(int i, atomic_t *v);

int atomic_inc_return(atomic_t *v);

int atomic_dec_return(atomic_t *v);

示例

atomic_t v; /* define v */

atomic_t u = ATOMIC_INIT(0); /* define u and initialize it to zero */

 

atomic_set(&v, 4); /* v = 4 (atomically) */

atomic_add(2, &v); /* v = v + 2 = 6 (atomically) */

atomic_inc(&v); /* v = v + 1 = 7 (atomically) */

 

printk("%d/n", atomic_read(&v)); /* will print "7" */

 

同步机制

原子位操作

头文件

<asm/bitops.h>

相关操作

void set_bit(nr, void *addr);

void clear_bit(nr, void *addr);

void change_bit(nr, void *addr);

test_bit(nr, void *addr);

int test_and_set_bit(nr, void *addr);

int test_and_clear_bit(nr, void *addr);

int test_and_change_bit(nr, void *addr);

示例

/* try to set lock */

while (test_and_set_bit(nr, addr) != 0)

    wait_for_a_while(  );

 

/* do your work */

 

/* release lock, and check... */

if (test_and_clear_bit(nr, addr) =  = 0)

something_went_wrong(  ); /* already released: error */

 

unsigned long word = 0;

 

set_bit(0, &word); /* bit zero is now set (atomically) */

set_bit(1, &word); /* bit one is now set (atomically) */

printk("%ul/n", word); /* will print "3" */

clear_bit(1, &word); /* bit one is now unset (atomically) */

change_bit(0, &word); /* bit zero is flipped; now it is unset (atomically) */

 

/* atomically sets bit zero and returns the previous value (zero) */

if (test_and_set_bit(0, &word)) {

/* never true */

}

 

/* the following is legal; you can mix atomic bit instructions with normal C */

word = 7;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值