Linux内核API autoremove_wake_function

autoremove_wake_function函数功能描述:函数在实现过程中,调用了函数default_wake_function( ),完成唤醒此等待队列中的某一进程;如果唤醒进程成功,则调用函数list_del_init( ),将此进程从等待队列中删除,否则不进行其他操作,函数执行结束,返回结果。

autoremove_wake_function文件包含

#include <linux/wait.h>

autoremove_wake_function函数定义

在内核源码中的位置:linux-3.19.3/kernel/sched/wait.c

函数定义格式:

int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)

autoremove_wake_function输入参数说明

此函数的第一个输入参数是wait_queue_t类型的指针,代表等待队列中的一个元素,其定义及详细信息参考abort_exclusive_wait( )

此函数的第二个参数是无符号的整型变量,代表能够被唤醒的进程的所处的状态,即只有处于此状态的进程才能够被唤醒,可能的取值为宏TASK_NORMAL和TASK_ALL,此二者的定义如下:

#define TASK_NORMAL        (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
#define TASK_ALL           (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED)

其中TASK_NORMAL代表唤醒等待队中处于可中断的等待状态的进程及处于不可中断的等待状态的进程;TASK_ALL代表唤醒处于TASK_NORMAL状态的进程及处于暂停状态和跟踪状态的进程。

此函数的第三个参数是一个整型变量,代表唤醒等待队列中进程的方式,可能的取值是0和非0,0代表非同步唤醒,非0代表同步唤醒。

此函数的第四个参数是一个void型的指针变量,代表唤醒进程时执行的函数,一般传递NULL。

autoremove_wake_function返回参数说明

此函数的返回结果是int型的变量值,此值可能为0或1。返回0说明唤醒进程失败,并且进程没有从等待队列中删除,说明此进程的状态不满足唤醒要求,即状态不属于第二个参数所定义的状态;返回1说明唤醒进程成功,使进程由非TASK_RUNNING状态转变为TASK_RUNNING状态,并获得CPU资源,将被调度执行,并且成功从等待队列中删除。

autoremove_wake_function实例解析

编写测试文件:autoremove_wake_function.c

头文件引用及全局变量定义:

/*头文件引用*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/kthread.h>
MODULE_LICENSE("GPL");
/*全局变量定义*/
wait_queue_head_t head;   //等待队列头元素
wait_queue_t data;        //等待队列元素

子进程处理函数定义:

int my_function(void * argc)
{
    int   wait_queue_num=0, return_data;
    wait_queue_t *curr, *next;
    printk("in the kernel thread function! \n");
    list_for_each_entry_safe(curr, next, &(head.task_list), task_list)
                          // 扫描等待队列,显示等待队列中的进程的PID值及进程所处的状态
    {
        wait_queue_num++; // 记录当前等待队列中的进程的数
        printk("the pid value of the current data of the waitqueue is:%d\n", ((struct task_struct *)(curr->private))->pid);   //显示进程的PID值
        printk("the state of the current data of the waitqueue is:%ld\n", ((struct task_struct *)(curr->private))->state); //显示进程的状态
    }
    printk("the value of the wait_queue_num is :%d\n", wait_queue_num);
                          // 输出等待队列中的进程数
    return_data=autoremove_wake_function(&data, TASK_NORMAL,1, NULL);
                          // 调用函数将父进程从等待队列中删除
    wait_queue_num=0;
    list_for_each_entry_safe(curr, next, &(head.task_list), task_list)
                          // 显示函数调用之后等待队列中进程的信息
    {
        wait_queue_num++;
        printk("the pid value of the current data of the waitqueue is:%d\n", ((struct task_struct *)(curr->private))->pid);
        printk("the state of the current data of the waitqueue is:%ld\n", ((struct task_struct *)(curr->private))->state);
    }
    printk("the value of the wait_queue_num is :%d\n", wait_queue_num);
                          // 显示函数调用之后等待队列中的元素个数
    printk("the return_data of the autoremove_wake_function is :%d\n", return_data);
                          //显示autoremove_wake_function( )函数的返回结果
    printk("the current pid is:%d\n", current->pid);    //显示当前进程的PID值
    printk("out the kernel thread function\n");
    return 0;
}

模块加载函数定义:

static int __init autoremove_wake_function_init(void)
{
    // 局部变量定义
    char namefrm[] = "add_wait_queue.c";
    struct task_struct * result;
    int result1=-2, wait_queue_num=0, left_time;
    wait_queue_t *curr, *next;
    printk("into autoremove_wake_function_init.\n");
    result=kthread_create_on_node(my_function, NULL, -1, namefrm); //创建1个新进程
    wake_up_process(result);
    init_waitqueue_head(&head);           //初始化等待队列头元素
    init_waitqueue_entry(&data, current); // 用当前进程初始化等待队列中的一个元素
    add_wait_queue(&head, &data);         //将当前进程加入等待队列
    left_time = schedule_timeout_uninterruptible(1000); //将等待队列置于不可中断的等待状态
    if(data.private! =NULL)
            result1=autoremove_wake_function(&data, TASK_ALL,0, NULL);
                                          // 将当前进程从等待队列中删除
    list_for_each_entry_safe(curr, next, &(head.task_list), task_list)
                                          // 显示当前等待队列中的进程的信息
    {
        wait_queue_num++;
        printk("the pid value of the current data of the waitqueue is:%d\n", ((struct task_struct *)(curr->private))->pid);
        printk("the state of the current data of the waitqueue is:%ld\n", ((struct task_struct *)(curr->private))->state);
    }
    printk("the letf time of the sleep_on_timeout is :%d\n", left_time);
                                          //显示函数sleep_on_timeout( )的返回结果
    printk("the return result of the autoremove_wake_function is :%d\n", result1);
                                  //显示函数autoremove_wake_function( )的返回结果
    printk("the value of the wait_queue_num is :%d\n", wait_queue_num);
                                          // 显示当前等待队列中的元素个数
    printk("the pid of the kthread_create_on_node is :%d\n", result->pid);
                                          //显示函数kernel_thread( )的返回结果
    printk("the current pid is:%d\n", current->pid);    //显示当前进程的PID值
    printk("out autoremove_wake_function_init.\n");
    return 0;
}

模块退出函数定义:

static void __exit autoremove_wake_function_exit(void)
{
    printk("Goodbye autoremove_wake_function\n");
}

模块加载、退出函数调用:

module_init(autoremove_wake_function_init);
module_exit(autoremove_wake_function_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod autoremove_wake_function.ko插入内核模块,然后输入命令dmesg -c查看模块插入结果,会出现如图所示的结果。

Linux内核API autoremove_wake_function

结果分析:

由上图可以得出在子进程执行时,函数autoremove_wake_function( )执行前,等待队列中有一个元素,并且进程的状态是2,即处于不可中断的等待状态。在子进程中当函数autoremove_wake_function( )执行之后,等待队列中的元素个数变为0,函数autoremove_wake_function( )的返回结果是1,说明函数能够唤醒进程,并将进程从等待队列中删除。

在父进程中函数schedule_timeout_uninterruptible ( )的返回结果是1000,说明进程是被强制唤醒的而非超时唤醒的,也说明了函数autoremove_wake_function( )能够唤醒进程。

赞(0)
未经允许不得转载:极客笔记 » Linux内核API autoremove_wake_function

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
Linux内核API 模块机制
Linux内核API 模块机制Linux内核API __module_addressLinux内核API __module_text_addressLinux内核API __print_symbolLinux内核API __symbol_getLinux内核API __symbol_putLinux内核API find_moduleLinux内核API find_symbolLinux内核API module_is_liveLinux内核API module_putLinux内核API module_refcountLinux内核API sprint_symbolLinux内核API symbol_put_addrLinux内核API try_module_get
Linux内核API 进程管理
Linux内核API 进程管理Linux内核API __task_pid_nr_nsLinux内核API find_get_pidLinux内核API find_pid_nsLinux内核API find_vpidLinux内核API get_pidLinux内核API get_task_mmLinux内核API mmputLinux内核API ns_of_pidLinux内核API pid_nrLinux内核API pid_taskLinux内核API pid_vnrLinux内核API put_pidLinux内核API task_active_pid_nsLinux内核API task_tgid_nr_ns
Linux内核API 进程调度
Linux内核API 进程调度Linux内核API __wake_upLinux内核API __wake_up_syncLinux内核API __wake_up_sync_keyLinux内核API abort_exclusive_waitLinux内核API add_wait_queueLinux内核API add_wait_queue_exclusiveLinux内核API autoremove_wake_functionLinux内核API completeLinux内核API complete_allLinux内核API completion_doneLinux内核API current_thread_infoLinux内核API default_wake_functionLinux内核API do_exitLinux内核API finish_waitLinux内核API init_waitqueue_entryLinux内核API init_waitqueue_headLinux内核API kthread_create_on_nodeLinux内核API kthread_stopLinux内核API prepare_to_waitLinux内核API prepare_to_wait_exclusiveLinux内核API remove_wait_queueLinux内核API sched_setschedulerLinux内核API set_cpus_allowed_ptrLinux内核API set_user_niceLinux内核API task_niceLinux内核API try_wait_for_completionLinux内核API wait_for_completionLinux内核API wait_for_completion_interruptible_timeoutLinux内核API wait_for_completion_killableLinux内核API wait_for_completion_timeoutLinux内核API wake_up_processLinux内核API yield
Linux内核API 中断机制
Linux内核API 中断机制Linux内核API __tasklet_hi_scheduleLinux内核API __tasklet_scheduleLinux内核API disable_irqLinux内核API disable_irq_nosyncLinux内核API disable_irq_wakeLinux内核API enable_irqLinux内核API enable_irq_wakeLinux内核API free_irqLinux内核API irq_set_chipLinux内核API irq_set_chip_dataLinux内核API irq_set_irq_typeLinux内核API irq_set_irq_wakeLinux内核API remove_irqLinux内核API request_irqLinux内核API request_threaded_irqLinux内核API setup_irqLinux内核API tasklet_disableLinux内核API tasklet_disable_nosyncLinux内核API tasklet_enableLinux内核API tasklet_hi_scheduleLinux内核API tasklet_initLinux内核API tasklet_killLinux内核API tasklet_scheduleLinux内核API tasklet_trylockLinux内核API tasklet_unlock
Linux内核API 内存管理
Linux内核API 内存管理Linux内核API __free_pagesLinux内核API __get_free_pagesLinux内核API __get_vm_areaLinux内核API __kreallocLinux内核API alloc_pagesLinux内核API alloc_pages_exactLinux内核API find_vmaLinux内核API find_vma_intersectionLinux内核API free_pagesLinux内核API free_pages_exactLinux内核API get_unmapped_areaLinux内核API get_zeroed_pageLinux内核API kcallocLinux内核API kfreeLinux内核API kmallocLinux内核API kmem_cache_allocLinux内核API kmem_cache_createLinux内核API kmem_cache_destroyLinux内核API kmem_cache_freeLinux内核API kmem_cache_zallocLinux内核API kmemdupLinux内核API ksizeLinux内核API kstrdupLinux内核API kstrndupLinux内核API kzallocLinux内核API memdup_userLinux内核API mempool_allocLinux内核API mempool_alloc_pagesLinux内核API mempool_alloc_slabLinux内核API mempool_createLinux内核API mempool_destroyLinux内核API mempool_freeLinux内核API mempool_free_pagesLinux内核API mempool_free_slabLinux内核API mempool_kfreeLinux内核API mempool_kmallocLinux内核API mempool_resizeLinux内核API nr_free_buffer_pagesLinux内核API page_addressLinux内核API page_cache_getLinux内核API page_cache_releaseLinux内核API page_zoneLinux内核API probe_kernel_addressLinux内核API probe_kernel_readLinux内核API vfreeLinux内核API vma_pagesLinux内核API vmallocLinux内核API vmalloc_to_pageLinux内核API vmalloc_to_pfnLinux内核API vmalloc_user
Linux内核API 定时机制
Linux内核API 定时机制Linux内核API __round_jiffiesLinux内核API __round_jiffies_relativeLinux内核API __round_jiffies_upLinux内核API __round_jiffies_up_relativeLinux内核API add_timerLinux内核API current_kernel_timeLinux内核API del_timerLinux内核API del_timer_syncLinux内核API do_gettimeofdayLinux内核API do_settimeofdayLinux内核API get_secondsLinux内核API getnstimeofdayLinux内核API init_timerLinux内核API init_timer_deferrableLinux内核API init_timer_keyLinux内核API init_timer_on_stackLinux内核API init_timer_on_stack_keyLinux内核API mktimeLinux内核API mod_timerLinux内核API mod_timer_pendingLinux内核API ns_to_timespecLinux内核API ns_to_timevalLinux内核API round_jiffiesLinux内核API round_jiffies_relativeLinux内核API round_jiffies_upLinux内核API round_jiffies_up_relativeLinux内核API set_normalized_timespecLinux内核API setup_timerLinux内核API setup_timer_on_stackLinux内核API timer_pendingLinux内核API timespec_add_nsLinux内核API timespec_compareLinux内核API timespec_equalLinux内核API timespec_subLinux内核API timespec_to_nsLinux内核API timeval_compareLinux内核API timeval_to_nsLinux内核API try_to_del_timer_sync
Linux内核API 同步机制
Linux内核API 同步机制Linux内核API atomic_addLinux内核API atomic_add_negativeLinux内核API atomic_add_returnLinux内核API atomic_add_unlessLinux内核API atomic_cmpxchgLinux内核API atomic_decLinux内核API atomic_dec_and_testLinux内核API atomic_incLinux内核API atomic_inc_and_testLinux内核API atomic_readLinux内核API atomic_setLinux内核API atomic_subLinux内核API atomic_sub_and_testLinux内核API atomic_sub_returnLinux内核API downLinux内核API down_interruptibleLinux内核API down_killableLinux内核API down_readLinux内核API down_read_trylockLinux内核API down_timeoutLinux内核API down_trylockLinux内核API down_writeLinux内核API down_write_trylockLinux内核API downgrade_writeLinux内核API init_rwsemLinux内核API read_seqbeginLinux内核API read_seqretryLinux内核API sema_initLinux内核API seqlock_initLinux内核API upLinux内核API up_readLinux内核API up_writeLinux内核API write_seqlockLinux内核API write_sequnlock
Linux内核API 文件系统
Linux内核API 文件系统Linux内核API __mnt_is_readonlyLinux内核API current_umaskLinux内核API d_allocLinux内核API d_find_aliasLinux内核API dputLinux内核API fgetLinux内核API generic_fillattrLinux内核API get_fs_typeLinux内核API get_max_filesLinux内核API get_superLinux内核API have_submountsLinux内核API I_BDEVLinux内核API inode_add_bytesLinux内核API inode_get_bytesLinux内核API inode_set_bytesLinux内核API inode_sub_bytesLinux内核API is_bad_inodeLinux内核API make_bad_inodeLinux内核API may_umountLinux内核API may_umount_treeLinux内核API mnt_want_writeLinux内核API notify_changeLinux内核API put_unused_fdLinux内核API unshare_fs_structLinux内核API vfs_fstatLinux内核API vfs_getattrLinux内核API vfs_statfs
Linux内核API 设备管理
Linux内核API 设备管理Linux内核API __class_createLinux内核API __class_registerLinux内核API cdev_addLinux内核API cdev_allocLinux内核API cdev_delLinux内核API cdev_initLinux内核API class_createLinux内核API class_destroyLinux内核API class_registerLinux内核API class_unregisterLinux内核API device_addLinux内核API device_createLinux内核API device_delLinux内核API device_destroyLinux内核API device_initializeLinux内核API device_registerLinux内核API device_renameLinux内核API device_unregisterLinux内核API get_deviceLinux内核API put_deviceLinux内核API register_chrdevLinux内核API unregister_chrdev