/* * So, we need to get back to where we came from. This can happen in two * different ways: * 1) PCC_MLCONT is set, in which case we need to go to the mainloop * 2) It is not set, and we simply jump to pcc_uc_ret. */ void puffs_cc_yield(struct puffs_cc *pcc) { struct puffs_cc *jumpcc; int rv; assert(puffs_fakecc == 0); pcc->pcc_flags &= ~PCC_BORROWED; /* romanes eunt domus */ DPRINTF(("puffs_cc_yield: ")); if ((pcc->pcc_flags & PCC_MLCONT) == 0) { DPRINTF(("no mlcont, pcc %p\n", pcc)); swapcontext(&pcc->pcc_uc, &pcc->pcc_uc_ret); } else { DPRINTF(("mlcont, pcc %p\n", pcc)); pcc->pcc_flags &= ~PCC_MLCONT; rv = puffs__cc_create(pcc->pcc_pu, puffs__theloop, &jumpcc); if (rv) abort(); /* p-p-p-pa-pa-panic (XXX: fixme) */ swapcontext(&pcc->pcc_uc, &jumpcc->pcc_uc); DPRINTF(("puffs_cc_yield: post swap pcc %p\n", pcc)); } }
/* public, but not really tested and only semi-supported */ int puffs_dispatch_create(struct puffs_usermount *pu, struct puffs_framebuf *pb, struct puffs_cc **pccp) { struct puffs_cc *pcc; if (puffs__cc_create(pu, dispatch, &pcc) == -1) return -1; pcc->pcc_pb = pb; *pccp = pcc; return 0; }