【学习笔记】原子位|内核线程

原子位和原子变量

原子变量

原子操作主要用于实现资源计数
Linux中的基本原子操作

Atomic_read

  • 返回原子变量的值

Atomic_set

  • 设置原子变量的值。

Atomic_add

  • 原子的递增计数的值。

Atomic_sub

  • 原子的递减计数的值。

atomic_cmpxchg

  • 原子比较并交换计数值。

atomic_clear_mask

  • 原子的清除掩码。
while(atomic_cmpxchg(&v, 1, 0) != 1)
        ;
for(i = 0; i < 3; i++)
{
    mdelay(1000);
}

    atomic_set(&v, 1);

atomic_cmpxchg()函数实现了一个比较+交换的原子操作(原子就是说cpu要不就不做,要做就一定要做完某些操作才能干别的事情,对应这里就是比较和交换要一次过做完).
atomic_cmpxchg()比较kgdb_active->count的值是否等用-1,如果是则把cpu的值赋给kgdb_active->count,否则不修改它的值,atomic_cmpxchg返回kgdb_active->count赋值前的值.

简单的讲,假设4个进程同时开始,1号成功进入, atomic_dec_and_test成功减1并通过检测,跳出while循环,其他3个进程成功减1但数值已为负数,不通过test,循环知道1号进程完成时加1(atomic_inc)。

while(!atomic_dec_and_test(&v))
    {
        atomic_inc(&v);    //kind like spin_lock();
        //wait ->           mutex
    }

    /*do something*/

    atomic_inc(&v);

中断

先来看一下头文件和函数(:

#include <linux/interrupt.h>

int request_irq(unsigned int irq, irq_handler_t handler, 
        unsigned long irqflags, const char *devname, void *dev_id)
irq:
    中断号 arch/arm/plat-s3c64xx/include/plat/irqs.h

handler:
    中断处理函数 irqreturn_t handler(int irq, void *dev_id);
    irqreturn_t:
        See include/linux/irqreturn.h

irqflags:
    See line 21-59 in include/linux/interrupt.h
    使用IRQF_SHARED共享irq时, irqflags必须相同
    如:      request_irq(IRQ_EINT(0), handler1, 
            IRQF_TRIGGER_FALLING | IRQF_SHARED, "dev1", &dev1);

        request_irq(IRQ_EINT(0), handler2, 
            IRQF_TRIGGER_FALLING | IRQF_SHARED, "dev2", &dev2);

devname:
    设备名, cat /proc/interrupts

dev_id:
    发生中断时将dev_id传递给handler函数,
        irqflags含有IRQF_SHARED时dev_id不能为NULL, 并且要保证唯一
    dev_id一般采用当前设备的结构体指针

1.中断时不能睡眠,进入中断时会屏蔽其他中断,此时睡眠将无法接受用于唤醒的中断,而自己处于睡眠,也无法唤醒自己。——所以使用自旋锁,不进入睡眠。
2.中断可以设为共享让其他‘人’使用。

内核线程

  • 创建内核线程:

    struct task_struct *kthread_create(int (*threadfn)(void *data),
    void *data, const char namefmt[]);

  • 唤醒内核线程(可以唤醒所有进程(线程)):

    wake_up_process(struct task_struct *k);

  • 创建并运行内核线程:

    struct task_struct *kthread_run(int (*threadfn)(void *data),
    void *data, const char namefmt[]);

在系统上运行的结果


  • 通知内核线程停止:

int kthread_stop(struct task_struct *k);
返回threadfn函数的返回值, 如果k没有被wake_up_process(k)过将返回-EINTR
不是强制停止, 如果内核线程不停止将一直等待
你可以直接拔出模块‘杀死’一个自己建立并插入的内核态线程(不使用通知),内核将会崩溃。


  • 检查是否收到停止信号:

int kthread_should_stop(void);
头文件 linux/kthread.h

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值