美文网首页
cocore 阅读

cocore 阅读

作者: RudyHao | 来源:发表于2022-04-06 18:27 被阅读0次
image.png

1: coobjc.h 内联函数 启动协程

co_launch(^{

});

2.将block转换成OC协程对象 COCoroutine.m 并且创建c的协程对象coroutine_t

        COCoroutine *co = [COCoroutine coroutineWithBlock:block onQueue:nil];

        coroutine_t  *co = coroutine_create((void (*)(void *))co_exec);
        if (stackSize > 0 && stackSize < 1024*1024) {   // Max 1M
            co->stack_size = (uint32_t)((stackSize % 16384 > 0) ? ((stackSize/16384 + 1) * 16384) : stackSize);        // Align with 16kb
        }
        //设置  coroutine_t 为当前COCoroutine属性 _co
        //c协程对象 coroutine_t 和 当前 OC对象 COCoroutine 双向引用
        _co = co;
        coroutine_setuserdata(co, (__bridge_retained void *)self, co_obj_dispose);
        //将OC绑定到couserdata
        co->userdata = userdata;
        //设置释放回调指针
        co->userdata_dispose = ud_dispose;

3. 执行协程 coobjc.h COCoroutine.m

return [co resume]; 
//将当前任务放入CODispatch 队列
3.1 self.dispatch dispatch_async_block:^{
        //将协程添加到调度程序 进入真正的协程处理方法
        //跳转到 coroutine_resume_im.m
        coroutine_resume(self.co);
    }];
3.1 //获取当前运行的协程
    coroutine_t *coroutine_self() 
3.2 //获取当前运行的协程调度器。调度器跟协程关系?
    // 调度器由一个主协程,co->is_scheduler = true;
    // 调度器结构
        struct coroutine_scheduler {
            coroutine_t         *main_coroutine; //跟随调度器同时生成的主协程
            coroutine_t         *running_coroutine; //当前正在运行的协程
            coroutine_list_t     coroutine_queue; //等待执行的协程
        };
    //调度结构体,全局唯一 pthread_getspecific,pthread_setspecific实现
    coroutine_scheduler_t 
    //里面有一个主协程
    coroutine_scheduler_t *coroutine_scheduler_self(void)

4. coroutine_resume

    4.1 //将当前协程加入队列
        scheduler_queue_push(scheduler, co);
    4.2 //如果当前有正在运行
        if (scheduler->running_coroutine) {
            //如果当前有正在执行的协程,插入到队尾
            scheduler_queue_push(scheduler, scheduler->running_coroutine);
            //恢复当前协程继续执行
            coroutine_yield(scheduler->running_coroutine);
        } else {
            // 当前调度没有协程执行,恢复调度协程
            // 调度主协程
            coroutine_resume_im(co->scheduler->main_coroutine);

            //主协程入口方法
            // 从coroutine_queue pop一个协程出来执行
            coroutine_scheduler_main
        }

5. //执行协程

//由主协程的入口函数调度 协程
// COROUTINE_SUSPEND
void coroutine_resume_im(coroutine_t *co)
    //创建pre_context
    co->pre_context = malloc(sizeof(coroutine_ucontext_t));
    //保存现场
    //将当前寄存器的值写入co->pre_context
    coroutine_getcontext(co->pre_context);

    //创建co->context
    co->context = calloc(1, sizeof(coroutine_ucontext_t));

    //设置入口函数为pc
    //设置sp,fp
    coroutine_makecontext(co->context, (IMP)coroutine_main, co, (void *)co->stack_top);    
//设置参数
void coroutine_makecontext (coroutine_ucontext_t *ctx, IMP func, void *arg, void *stackTop)
{
    struct coroutine_ucontext_re *uctx = (struct coroutine_ucontext_re *)ctx;
    uintptr_t stackBegin = (uintptr_t)stackTop - sizeof(uintptr_t);
    uctx->GR.__fp = stackBegin;
    uctx->GR.__sp = stackBegin;
    uctx->GR.__x[0] = (uintptr_t)arg;
    uctx->GR.__pc = (uintptr_t)func;
}
//调用汇编 执行指令
coroutine_begin(co->context);

6. coroutine_yield

void coroutine_yield(coroutine_t *co){
    //保存现场,将寄存器的值写入oc->pre_context
    //并且设置状态,下次可以恢复调度
    co->status = COROUTINE_SUSPEND;
}

相关关键结构体
typedef struct coroutine_ucontext {
    uint64_t data[100];
} coroutine_ucontext_t;

struct coroutine_ucontext_re {
    struct GPRs {
        uint64_t __x[29]; // x0-x28
        uint64_t __fp;    // Frame pointer x29
        uint64_t __lr;    // Link register x30
        uint64_t __sp;    // Stack pointer x31
        uint64_t __pc;    // Program counter
        uint64_t padding; // 16-byte align, for cpsr
    } GR;
    double  VR[32];
};

//协程先保存当前寄存器的值到pre_context
//将寄存器的值写入pre_context coroutine_ucontext_t
extern int coroutine_getcontext (coroutine_ucontext_t *__ucp);

//恢复现场,将context的值读入寄存器,执行入口函数
//由coroutine_scheduler_main 唤醒协程执行
extern int coroutine_setcontext (coroutine_ucontext_t *__ucp);

//恢复现场,执行入口函数
extern int coroutine_begin (coroutine_ucontext_t *__ucp);
//汇编指令找到pc
ldr x9, [x0, #0x100] // restore pc into lr
//跳转到入口函数
ret x9

相关文章

  • cocore 阅读

    1: coobjc.h 内联函数 启动协程 2.将block转换成OC协程对象 COCoroutine.m 并且创...

  • 阅读是一件非常重要的小事

    坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持阅读,坚持...

  • 阅读、阅读、还是阅读

    阅读、阅读、还是阅读 ——第十二周给海螺们的一封信 亲爱的大海螺、小海螺们 周末好! 今天,是第十二周的末端,距离...

  • 阅读,阅读,还是阅读。

    中国古代宋真宗的《励学篇》写到:“富家不用买良田,书中自有千钟粟。安居不用架高楼,书中自有黄金屋。娶妻莫恨...

  • 阅读,阅读,再阅读……

    苏联数育家苏霍姆林斯基曾说过“让孩子变聪明的方法,不是补课,不是增加作业量,而是阅读,阅读,再阅读。” 如果说文化...

  • 阅读—阅读—再阅读

    突然想知道背诵作文到底是对是错? 也许家长或老师的出发点并没有对错之分,他们都寄希望于每个孩子都能学习更多知识。不...

  • 【文魁大脑读书会2016】杜星默 第本7/52《如何阅读一本书》

    阅读目的:学习阅读 阅读方法:检视阅读 笔记: 阅读的四个层次:基础阅读,检视阅读,分析阅读和主题阅读。 检视阅读...

  • 阅读、阅读……

    弘扬中华优秀传统文化,与阅读同行,启迪大脑潜能,提升综合素养,从小培养孩子的读书习惯,润育生命,智慧人生。 ...

  • 阅读,阅读

    临近期末,很多家长都问我孩子的成绩问题,并且发愁。比如,阅读理解题和看图写话不好,很拉分怎么办?周末一大早,我们来...

  • 阅读?阅读!

    “语文老师,我们班主任从这周开始不让我们借书了。” “为什么?” “怕耽误学习呗!” “你们晚上延时的时间是让学生...

网友评论

      本文标题:cocore 阅读

      本文链接:https://www.haomeiwen.com/subject/jhqdsrtx.html