zoukankan      html  css  js  c++  java
  • Linux tasklet 的测试

    在看 内核代码的时候 发现 tasklet 的 api ,想着如何去使用它。

     

     首先是 tasklet_disable 和 tasklet_kill 的 区别

    测试demo 如下:

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/slab.h>
    #include <linux/kobject.h>
    #include <linux/list.h>
    #include <linux/kthread.h>
    #include <asm/ptrace.h>
    #include <linux/sched.h>
    #include <linux/delay.h>
    #include <linux/interrupt.h>
    int data  = 10;
    
    void tasklet_func(unsigned long data)
    {
        printk(KERN_INFO "tasklet_func 
    ");
    }
    struct tasklet_struct tasklet;
    
    int threadfn(void *data)
    {
        static int count =  0 ;
        int args = *(int *)data;
        printk(KERN_INFO "enter thead_fn");
        while(1)
        {
            msleep(2*1000);
            printk(KERN_INFO "threadfn data: %d, count: %d
    ",args , ++count);
            if(count == 3)
            {
                printk(KERN_INFO "tasklet_kill 
    ");
                tasklet_kill(&tasklet);
            }
            else
            {
                printk(KERN_INFO "-----------
    ");
                tasklet_schedule(&tasklet);
            }
            
        }
    } 
    
    //模块初始化函数
    static int __init test_kobj_init(void)
    {
       tasklet_init(&tasklet,tasklet_func,data);
          
       struct task_struct *  thread =  kthread_create( threadfn,(void * )&data,"mythread");
       if(thread != NULL)
       {
           printk(KERN_INFO "thread create success
    ");
           wake_up_process(thread);
           
       }else
       {
           printk(KERN_ERR "thread create err
    ");
       }
    
        return 0;
    }
    
    
    //模块清理函数
    static void __exit test_kobj_exit(void)
    {
        printk(KERN_INFO "test_kobj_exit 
    ");
        return;
    }
    
    module_init(test_kobj_init);
    module_exit(test_kobj_exit);
    
    MODULE_AUTHOR("LoyenWang");
    MODULE_LICENSE("GPL");

    我一开始的设想是  调用了tasklet_kill函数之后 ,以后的调用都不会出现 tasklet_func .

    但是实际情况却是如此。

    当 count == 3 时候 我没有去调度 ,所以 func 没有打印很正常 ,但是 再下一个再次使用 tasklet_schedule 时候 ,依然可以有打印出来 ,

    所以  tasklet_kill 不会影响  tasklet_schedule 的调度。

    于是测试 demo2

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/slab.h>
    #include <linux/kobject.h>
    #include <linux/list.h>
    #include <linux/kthread.h>
    #include <asm/ptrace.h>
    #include <linux/sched.h>
    #include <linux/delay.h>
    #include <linux/interrupt.h>
    int data  = 10;
    
    void tasklet_func(unsigned long data)
    {
        printk(KERN_INFO "tasklet_func 
    ");
    }
    struct tasklet_struct tasklet;
    
    int threadfn(void *data)
    {
        static int count =  0 ;
        int args = *(int *)data;
        printk(KERN_INFO "enter thead_fn");
        while(1)
        {
            msleep(2*1000);
            printk(KERN_INFO "threadfn data: %d, count: %d
    ",args , ++count);
            if(count == 3)
            {
                printk(KERN_INFO "tasklet_kill 
    ");
                tasklet_disable(&tasklet);
            }else if (count == 5)
            {
                printk(KERN_INFO " tasklet_enable 
    ");
                tasklet_enable(&tasklet);
            }
            else
            {
                printk(KERN_INFO "-----------
    ");
                tasklet_schedule(&tasklet);
            }
            
        }
    } 
    
    //模块初始化函数
    static int __init test_kobj_init(void)
    {
       tasklet_init(&tasklet,tasklet_func,data);
          
       struct task_struct *  thread =  kthread_create( threadfn,(void * )&data,"mythread");
       if(thread != NULL)
       {
           printk(KERN_INFO "thread create success
    ");
           wake_up_process(thread);
           
       }else
       {
           printk(KERN_ERR "thread create err
    ");
       }
    
        return 0;
    }
    
    
    //模块清理函数
    static void __exit test_kobj_exit(void)
    {
        printk(KERN_INFO "test_kobj_exit 
    ");
        return;
    }
    
    module_init(test_kobj_init);
    module_exit(test_kobj_exit);
    
    MODULE_AUTHOR("LoyenWang");
    MODULE_LICENSE("GPL");

    就是在 count == 3 时候 , 使用tasklet_disable ,在count == 4 时候 ,尝试调度 ,在count ==5 时候,tasklet_enable  ,接着之后尝试调度。

    现象如下:

     发现 在使用了 tasklet_disable  之后 ,尝试调度 会失效 , 当再次 tasklet_enable   ,尝试调度成功。

  • 相关阅读:
    字符串分割并按大小排序
    为人之气
    RMQ
    线段树
    算法中的数学
    动态规划(DP)
    图的表示
    广度优先搜索(BFS)
    深度优先搜索(DFS)
    MyBatis(3.2.3)
  • 原文地址:https://www.cnblogs.com/coversky/p/15255722.html
Copyright © 2011-2022 走看看