cocore 閱讀

image.png

1: coobjc.h 內(nèi)聯(lián)函數(shù) 啟動協(xié)程

co_launch(^{

});

2.將block轉(zhuǎn)換成OC協(xié)程對象 COCoroutine.m 并且創(chuàng)建c的協(xié)程對象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
        }
        //設(shè)置  coroutine_t 為當(dāng)前COCoroutine屬性 _co
        //c協(xié)程對象 coroutine_t 和 當(dāng)前 OC對象 COCoroutine 雙向引用
        _co = co;
        coroutine_setuserdata(co, (__bridge_retained void *)self, co_obj_dispose);
        //將OC綁定到couserdata
        co->userdata = userdata;
        //設(shè)置釋放回調(diào)指針
        co->userdata_dispose = ud_dispose;

3. 執(zhí)行協(xié)程 coobjc.h COCoroutine.m

return [co resume]; 
//將當(dāng)前任務(wù)放入CODispatch 隊(duì)列
3.1 self.dispatch dispatch_async_block:^{
        //將協(xié)程添加到調(diào)度程序 進(jìn)入真正的協(xié)程處理方法
        //跳轉(zhuǎn)到 coroutine_resume_im.m
        coroutine_resume(self.co);
    }];
3.1 //獲取當(dāng)前運(yùn)行的協(xié)程
    coroutine_t *coroutine_self() 
3.2 //獲取當(dāng)前運(yùn)行的協(xié)程調(diào)度器雪位。調(diào)度器跟協(xié)程關(guān)系超歌?
    // 調(diào)度器由一個(gè)主協(xié)程箩张,co->is_scheduler = true;
    // 調(diào)度器結(jié)構(gòu)
        struct coroutine_scheduler {
            coroutine_t         *main_coroutine; //跟隨調(diào)度器同時(shí)生成的主協(xié)程
            coroutine_t         *running_coroutine; //當(dāng)前正在運(yùn)行的協(xié)程
            coroutine_list_t     coroutine_queue; //等待執(zhí)行的協(xié)程
        };
    //調(diào)度結(jié)構(gòu)體肆良,全局唯一 pthread_getspecific阿逃,pthread_setspecific實(shí)現(xiàn)
    coroutine_scheduler_t 
    //里面有一個(gè)主協(xié)程
    coroutine_scheduler_t *coroutine_scheduler_self(void)

4. coroutine_resume

    4.1 //將當(dāng)前協(xié)程加入隊(duì)列
        scheduler_queue_push(scheduler, co);
    4.2 //如果當(dāng)前有正在運(yùn)行
        if (scheduler->running_coroutine) {
            //如果當(dāng)前有正在執(zhí)行的協(xié)程,插入到隊(duì)尾
            scheduler_queue_push(scheduler, scheduler->running_coroutine);
            //恢復(fù)當(dāng)前協(xié)程繼續(xù)執(zhí)行
            coroutine_yield(scheduler->running_coroutine);
        } else {
            // 當(dāng)前調(diào)度沒有協(xié)程執(zhí)行时肿,恢復(fù)調(diào)度協(xié)程
            // 調(diào)度主協(xié)程
            coroutine_resume_im(co->scheduler->main_coroutine);

            //主協(xié)程入口方法
            // 從coroutine_queue pop一個(gè)協(xié)程出來執(zhí)行
            coroutine_scheduler_main
        }

5. //執(zhí)行協(xié)程

//由主協(xié)程的入口函數(shù)調(diào)度 協(xié)程
// COROUTINE_SUSPEND
void coroutine_resume_im(coroutine_t *co)
    //創(chuàng)建pre_context
    co->pre_context = malloc(sizeof(coroutine_ucontext_t));
    //保存現(xiàn)場
    //將當(dāng)前寄存器的值寫入co->pre_context
    coroutine_getcontext(co->pre_context);

    //創(chuàng)建co->context
    co->context = calloc(1, sizeof(coroutine_ucontext_t));

    //設(shè)置入口函數(shù)為pc
    //設(shè)置sp,fp
    coroutine_makecontext(co->context, (IMP)coroutine_main, co, (void *)co->stack_top);    
//設(shè)置參數(shù)
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;
}
//調(diào)用匯編 執(zhí)行指令
coroutine_begin(co->context);

6. coroutine_yield

void coroutine_yield(coroutine_t *co){
    //保存現(xiàn)場庇茫,將寄存器的值寫入oc->pre_context
    //并且設(shè)置狀態(tài),下次可以恢復(fù)調(diào)度
    co->status = COROUTINE_SUSPEND;
}

相關(guān)關(guān)鍵結(jié)構(gòu)體
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];
};

//協(xié)程先保存當(dāng)前寄存器的值到pre_context
//將寄存器的值寫入pre_context coroutine_ucontext_t
extern int coroutine_getcontext (coroutine_ucontext_t *__ucp);

//恢復(fù)現(xiàn)場螃成,將context的值讀入寄存器旦签,執(zhí)行入口函數(shù)
//由coroutine_scheduler_main 喚醒協(xié)程執(zhí)行
extern int coroutine_setcontext (coroutine_ucontext_t *__ucp);

//恢復(fù)現(xiàn)場,執(zhí)行入口函數(shù)
extern int coroutine_begin (coroutine_ucontext_t *__ucp);
//匯編指令找到pc
ldr x9, [x0, #0x100] // restore pc into lr
//跳轉(zhuǎn)到入口函數(shù)
ret x9

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锈颗,一起剝皮案震驚了整個(gè)濱河市顷霹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌击吱,老刑警劉巖淋淀,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異覆醇,居然都是意外死亡朵纷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門永脓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來袍辞,“玉大人,你說我怎么就攤上這事常摧〗劣酰” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵落午,是天一觀的道長谎懦。 經(jīng)常有香客問我,道長溃斋,這世上最難降的妖魔是什么界拦? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮梗劫,結(jié)果婚禮上享甸,老公的妹妹穿的比我還像新娘。我一直安慰自己梳侨,他們只是感情好蛉威,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著猫妙,像睡著了一般瓷翻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上割坠,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天齐帚,我揣著相機(jī)與錄音,去河邊找鬼彼哼。 笑死对妄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的敢朱。 我是一名探鬼主播剪菱,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拴签!你這毒婦竟也來了孝常?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蚓哩,失蹤者是張志新(化名)和其女友劉穎构灸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岸梨,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喜颁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了曹阔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片半开。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赃份,靈堂內(nèi)的尸體忽然破棺而出寂拆,到底是詐尸還是另有隱情,我是刑警寧澤抓韩,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布纠永,位于F島的核電站,受9級特大地震影響园蝠,放射性物質(zhì)發(fā)生泄漏渺蒿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一彪薛、第九天 我趴在偏房一處隱蔽的房頂上張望茂装。 院中可真熱鬧,春花似錦善延、人聲如沸少态。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彼妻。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侨歉,已是汗流浹背屋摇。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留幽邓,地道東北人炮温。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像牵舵,于是被迫代替她去往敵國和親柒啤。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容