view src/impl/CbCProcImpl.cbc @ 376:718e7398b2c3

define ptable.h
author anatofuz
date Tue, 07 Jul 2020 16:41:31 +0900
parents 4a4950e400b8
children
line wrap: on
line source

#include "types.h"
#include "defs.h"
#include "param.h"
#include "memlayout.h"
#include "mmu.h"
#include "arm.h"
#include "proc.h"
#include "spinlock.h"
#include "ptable.h"

#include "kernel.h"

#interface "CbCProc.h"

// ----
// typedef struct CbCProcImpl <Type, Isa> impl CbCProc {
//   __code next(....);
// } CbCProcImpl;
// ----

CbCProc* createCbCProcImpl(struct Context* cbc_context) {
    struct CbCProc* cbc_proc  = new CbCProc();
    struct CbCProcImpl* cb_c_proc_impl = new CbCProcImpl();
    cbc_proc->cbc_proc = (union Data*)cb_c_proc_impl;
    cbc_proc->sched = C_schedCbCProcImpl;
    cbc_proc->sleep = C_sleepCbCProcImpl;
    cbc_proc->sleep1 = C_sleep1CbCProcImpl;
    cbc_proc->wakeup = C_wakeupCbCProcImpl;
    cbc_proc->wakeup1 = C_wakeup1CbCProcImpl;
    return cbc_proc;
}

__code schedCbCProcImpl(struct CbCProcImpl* cbc_proc, __code next(...)) {
    int intena;

    if(!holding(&ptable.lock)) {
        panic("sched ptable.lock");
    }

    if(cpu->ncli != 1) {
        panic("sched locks");
    }

    if(proc->state == RUNNING) {
        panic("sched running");
    }

    if(int_enabled ()) {
        panic("sched interruptible");
    }

    intena = cpu->intena;
    swtch(&proc->context, cpu->scheduler);
    cpu->intena = intena;

    goto next(...);
}

__code sleepCbCProcImpl(struct CbCProcImpl* cbc_proc, void* chan, struct spinlock* lk, __code next(...)) {
    //show_callstk("sleep");

    if(proc == 0) {
        panic("sleep");
    }

    if(lk == 0) {
        panic("sleep without lk");
    }

    if(lk != &ptable.lock){  //DOC: sleeplock0
        acquire(&ptable.lock);  //DOC: sleeplock1
        release(lk);
    }
    proc->chan = chan;
    proc->state = SLEEPING;
    proc->lk = lk;

    goto schedCbCProcImpl(cbc_sleep1);
}

__code sleepCbCProcImpl_stub(struct Context* cbc_context) {
     CbCProcImpl* cbc_proc = (CbCProcImpl*)GearImpl(cbc_context, CbCProc, cbc_proc);
     struct spinlock* lk = Gearef(cbc_context, CbCProc)->lk;
     void* chan = Gearef(cbc_context, CbCProc)->chan;
     enum Code next = Gearef(cbc_context, CbCProc)->next;
     goto sleepCbCProcImpl(cbc_context, cbc_proc, chan, lk, next);
}


__code sleep1CbCProcImpl(struct CbCProcImpl* cbc_proc, __code next1(...)) {
    struct spinlock *lk = proc->lk;
    // Tidy up.
    proc->chan = 0;

    // Reacquire original lock.
    if(lk != &ptable.lock){  //DOC: sleeplock2
        release(&ptable.lock);
        acquire(lk);
    }

    goto next1(...);
}

__code wakeupCbCProcImpl(struct CbCProcImpl* cbc_proc, void* chan, __code next1(...)) {
    acquire(&ptable.lock);
    goto wakeup1CbCProcImpl(chan);
}

__code wakeup1CbCProcImpl(struct CbCProcImpl* cbc_proc, void* chan, __code next(...)) {
    struct proc *p;

    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) {
        if(p->state == SLEEPING && p->chan == chan) {
            p->state = RUNNABLE;
        }
    }

    release(&ptable.lock);
    goto next(...);
}