Chinaunix首页 | 论坛 | 博客
  • 博客访问: 52802
  • 博文数量: 24
  • 博客积分: 42
  • 博客等级: 民兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-13 21:32
文章分类
文章存档

2013年(4)

2012年(20)

分类:

2012-08-27 09:19:59

原文地址:linux驱动笔记一 作者:zhangyd6

第一   互斥操作

一, 信号量

初始化 init_MUTEX(struct semaphore *sem)

P函数 down(struct semaphore *sem)   down_interruptible(struct semaphore *sem)

V操作 up(struct semapheore *sem)

二 读取者/写入着信号量

初始化 init_rwsem(struct rw_sempahore *sem);

读操作 down_read(struct rw_seamphore *sem);

Up_read(struct rw_semphore *sem);

写操作 down_write (struct rw_semphore *sem);

Up_write(struct rw_semphore *sem);

三 Completion  

初始化: struct completion my_completion;

 Init_completion(&my_completion );

等待:  void wait_for_completion(struct completion *c)

触发:   void complete(struct completion *c);

  Void complet_all(struct completion *c);

四 自旋锁

所有自旋锁等待本质上都是不可中断的, 一旦调用sping_lock, 在获得锁之前将一直处于自旋的状态。

初始化: void spin_lock_init(spinlock_t *lock);

获得锁: void spin_lock(spinlock_t *lock);

Void spin_lock_irq(spinlock *lock);

void apin_lock_irqsave(spinlock *lock);

Void spin_lock_bh(spinlock *lock);

释放锁: void spin_unlock(spinlock_t *lock);

对共享资源的访问时间很短, 可以用自旋锁来访问。并且可以用在中断里。

 五 读取者/写入者 自旋锁

自旋锁大的 读者/写者 形式

定义: rwlock_t my_rwlock

   Rwlock_init(&my_lock);

读者: read_lock(rwlock_t *lock)

   Read_lock_irq(); read_lock_irqsave();  read_lock_bh();

Read_unlock(); read_unlock_irqsave()。。。。。。。。

写者: write_lock(rwlock_t *lock);

Write_lock_irqsave(); write_lock_irq(); write_lock_bh();

Write_unlock(); write_unlock_irqsave();。。。。。。

六  原子变量

原子操作

七  seqlock

当要保护的资源很小, 很简单, 会很频繁的访问而且写入访问会很少发生且必须快速是,就可以使用seqlock.本质上seqlock会允许读者对资源的自由访问,但需要读取者检查是否和写入者冲突,当这种冲突发生时,就需要重试对资源的访问。 通常不用于保护包含指针的数据结构。

八 读取 复制 更新

     通常发生在经常读取 而很少写入的情形的优化。被保护的资源应该通过指针访问,而对这些资源应该通过指针访问,而对这些资源的引用必须用原子代码拥有。 写入者首先复制, 然后修改副本, 之后 用新的版本替代相关的指针。

第二  进程的休眠

第一 简单休眠

声明: DELCARE_WAIT_QUEUE_HEAD(name);

或者 wait_queue_head_t my_queue;

Init_wait_queue_head(&my_queue);

等待: wat_event(queue, condition);

Wiat_event_interrupt(); wait_event_timeout(); wait_event_interruptible_timeout();

唤醒: void wake_up(wait_queue_head_t *queue);

   Void wake_up_interruptible(wait_queue_head_t *queue);

  Wake_up_all();

Wake_up_nr(); 

Wake_up_interruptible_sync();

第三  中断下半部分

第一 tasklet 机制

task queue基于bottom half,bottom half基于tasklet,而tasklet则基于softirq

do_softirq()有四种执行动机, 分别是: 从系统调用中返回, 从异常中返回, 调度程序中 以及处理完硬件中断之后

    一个tasklet执行结束后, 它就从执行队列里删除了,要想重新让他转入运行,就必须重新调用tasklet_schedule();

定义:  1   DECLARE_TASKLET(my_tasklet, my_tasklet_func , data); 定义一个名为tasklet结构my_tasklet, 与my_tasklet_func(data)函数相关联。。

2   tasklet_shedule(&my_tasklet); 登记my_tasklet, 允许系统在适当的时候进行调度运行。

第二  工作队列

工作队列与tasklet之间的区别:

 1   tasklet 在软件中断的上下文执行,所有的tasklet代码必须是原子的。相反,工作队列函数是一个特殊的内核进程的上下文中运行,因此他们具有更好的灵活行。尤其是, 工作队列函数可以休眠。

2    tasklet 始终运行在被初始提交的同一个处理器上,但这只是工作队列的默认方式。

3  内核代码可以请求工作队列函数的执行延迟给定的时间间隔。

定义: static struct work_struct jiq_work;

初始化: INIT_WORK(&jiq_work, jiq_print_wq, &jiq_data);

触发: schedule_work(struct work_struct *work);

清除: void flush_workqueue(struct workqueue_struct *queue);

同一个tasklet 和 timer 只能在同一个CPU上运行,而不同的软中间断运行在不同的CPU上。Tasklet 可以被调度多次,但实际 只有一次运行, 是不能积累的。

信号

只要同一个信号处于未决状态,如果此时又收到同一个信号,那么就合并两个信号位一个,这就是不可靠信号。对于可靠的信号就是排队的信号,一个收到多次,就调用多次信号处理函数。

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

上一篇:没有了

下一篇:Double-Colon Rules(双冒号规则)

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