Chinaunix首页 | 论坛 | 博客
  • 博客访问: 158361
  • 博文数量: 40
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 355
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-27 18:05
文章分类
文章存档

2011年(1)

2010年(9)

2009年(16)

2008年(14)

我的朋友

分类: LINUX

2008-12-05 16:26:08

自旋锁
不能睡眠,持有时间尽可能短
 

linux/spinlock.h
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)
//spin_lock 禁止中断
//spin_loc_irqsave 禁止中断(只在本地处理器)在获得自旋锁之前; 之前的中断状态保存在 flags 里
//spin_lock_irq 确信释放你的自旋锁时打开中断
//spin_lock_bh 在获取锁之前禁止软件中断, 但是硬件中断是打开的

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);

int spin_trylock(spinlock_t *lock);
int spin_trylock_bh(spinlock_t *lock);
//非阻塞的自旋锁操作,函数成功时返回非零( 获得了锁 ), 否则 0



读者/写者自旋锁
linux/spinlokc.h

rwlock_t my_rwlock = RW_LOCK_UNLOCKED; /* Static way */
rwlock_t my_rwlock;
rwlock_init(&my_rwlock); /* Dynamic way */

可用函数的列表现在应当看来相当类似. 对于读者, 下列函数是可用的:

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 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);

有趣地, 没有 read_trylock. 对于写存取的函数是类似的:

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 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);


 

不加锁算法

在内核中通用的环形缓存linux/kfifo.h

原子变量

asm/atomic.h
atomic_t v = ATOMIC_INIT(0);
//编译时
void atomic_set(atomic_t *v, int i);
//动态设定
int atomic_read(atomic_t *v);
//返回 v 的当前值.
void atomic_add(int i, atomic_t *v);
//由 v 指向的原子变量加 i. 返回值是 void
void atomic_sub(int i, atomic_t *v);
//从 *v 减去 i.

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);
//进行一个特定的操作并且测试结果; 如果, 在操作后, 原子值是 0, 那么返回值是真; 否则, 它是假. 注


意没有 atomic_add_and_test.

int atomic_add_negative(int i, atomic_t *v);
//加整数变量 i 到 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_add 和其类似函数, 除了它们返回原子变量的新值给调用者.

注意
    需要多个 atomic_t 变量的操作仍然需要某种其他种类的加锁.
     atomic_t 假设最多24 位,不要赋的值太大

位操作

asm/bitops.h
void set_bit(nr, void *addr);
//设置第 nr 位在 addr 指向的数据项中.
void clear_bit(nr, void *addr);
//清除指定位在 addr 处的无符号长型数据. 它的语义与 set_bit 的相反.
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);
//原子地动作如同前面列出的,还返回这个位以前的值.

seqlock 锁

 

读取-拷贝-更新

阅读(1159) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~