实例说明 async_schedule的使用

本文深入探讨了Linux内核中async_schedule函数的使用,该函数通过将任务放入async_pending链表并启动内核线程来实现并行处理。文章详细介绍了async_schedule的相关函数及其实现原理,并通过实例展示了如何使用async_schedule来异步执行特定功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

async_schedule


相关函数:
<linux/schedule.h>

typedef void (*async_func_t) (void *data, async_cookie_t cookie);

// 调用ptr函数运行
// 每调用一次async_schedule,就把ptr放到async_pending链表,然后开启一个内核线程来完成工作,这样实现并行
extern async_cookie_t async_schedule(async_func_t func *ptr, void *data);

// 等cookie对应的函数结束,没有结束会一直阻塞
extern void async_synchronize_cookie(async_cookie_t cookie);

// 等所有的函数结束
extern void async_synchronize_full(void);
实例
#include <linux/async.h>
#include <asm/io.h>
#include <asm/cacheflush.h>

static async_cookie_t populate_initrootfs_cookie;

/* 重点在 async_synchronize_cookie */
void __init wait_populate_initrootfs_done(void)
{
    if(populate_initrootfs_cookie)
        async_synchronize_cookie(populate_initrootfs_cookie);  // 等 populate_initrootfs_cookie 对应的函数结束,没有结束会一直阻塞
}

u32 imx_get_cpu_arg(int cpu);
void imx_set_cpu_arg(int cpu, u32 arg);
void imx_enable_cpu(int cpu, bool enable);

/* 被放到链表中异步执行的功能函数 */
static void __init async_populate_initrootfs(void *data, async_cookie_t cookie)
{
    char* errmsg;
#ifdef CONFIG_UBOOT_SMP_BOOT
    int ret;
    unsigned long timeout = jiffies + msecs_to_jiffies(5000);

    // don't do SMP boot when secondary CPU not present or used by Linux already
    if (!cpu_possible(1) || cpu_online(1)) {
        printk(KERN_WARNING "UBOOT_SMP_BOOT enabled but secondary CPU is in wrong state\n");
        goto unpack;
    }

    while ((ret = imx_get_cpu_arg(1)) == 0)
        if (time_after(jiffies, timeout))
            break;
    imx_enable_cpu(1, false);
    imx_set_cpu_arg(1, 0);

    if (ret <= 0) {
        printk(KERN_ERR "SMP load cpio fail %d\n", ret);
        goto out;
    }
    else
        printk(KERN_ERR "SMP load cpio success %x\n", ret);

    //dmac_flush_range(initrd_start, initrd_end);
unpack:
#endif

    printk(KERN_ERR "Unpacking initramfs...\n");
    errmsg = unpack_to_rootfs((char *)initrd_start, initrd_end - initrd_start);
    if (errmsg)
        printk(KERN_ERR "Initramfs unpacking failed: %s\n", errmsg);
    else
        printk(KERN_ERR "Unpacking initramfs done\n");

out:
    free_initrd();
}

static int __init populate_initrootfs(void)
{
    int err;

    printk(KERN_ERR "populate_initrootfs\n");

    err = sys_mkdir((const char __user __force *) "/dev", 0755);
    if (err < 0)
        goto out;

    err = sys_mknod((const char __user __force *) "/dev/console",
            S_IFCHR | S_IRUSR | S_IWUSR,
            new_encode_dev(MKDEV(5, 1)));
    if (err < 0)
        goto out;

    err = sys_mkdir((const char __user __force *) "/root", 0700);
    if (err < 0)
        goto out;

    /*create initroot when cpio (find initroot | cpio -o -H newc > initramfs.cpio)*/
/*  err = sys_mkdir((const char __user __force *) "/initroot", 0700);
    if (err < 0)
        goto out;
*/
    populate_initrootfs_cookie = 
        async_schedule(async_populate_initrootfs, NULL);    // 把 async_populate_initrootfs 放到async_pending链表,然后开启一个内核线程来完成工作,这样实现并行

    return 0;

out:
    printk(KERN_WARNING "Failed to create a rootfs for initroot\n");
    return err;
}
rootfs_initcall(populate_initrootfs);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值