实例说明 async_schedule的使用

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);

猜你喜欢

转载自blog.csdn.net/deggfg/article/details/81509508
今日推荐