Skip to content

Commit

Permalink
feat: 添加 Lab4 练习 15 代码
Browse files Browse the repository at this point in the history
  • Loading branch information
woai3c committed Feb 26, 2020
1 parent 1c88171 commit 289a520
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
37 changes: 35 additions & 2 deletions kern/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,36 @@ static int
sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, unsigned perm)
{
// LAB 4: Your code here.
panic("sys_ipc_try_send not implemented");
struct Env *env;
if (envid2env(envid, &env, 0) < 0) return -E_BAD_ENV;
if (!env->env_ipc_recving) return -E_IPC_NOT_RECV;

if ((size_t) srcva < UTOP) {
if (((size_t) srcva % PGSIZE) != 0) {
return -E_INVAL;
}

if ((perm & PTE_U) != PTE_U || (perm & PTE_P) != PTE_P) return -E_INVAL;

pte_t *pte;
struct PageInfo *pp = page_lookup(curenv->env_pgdir, srcva, &pte);
if (!pp) return -E_INVAL;

if ((perm & PTE_W) && ((size_t) *pte & PTE_W) != PTE_W) return -E_INVAL;
if ((size_t) env->env_ipc_dstva < UTOP) {
if (page_insert(env->env_pgdir, pp, env->env_ipc_dstva, perm) < 0) return -E_NO_MEM;
env->env_ipc_perm = perm;
}
} else {
env->env_ipc_perm = 0;
}

env->env_ipc_from = curenv->env_id;
env->env_ipc_recving = 0;
env->env_ipc_value = value;
env->env_status = ENV_RUNNABLE;
env->env_tf.tf_regs.reg_eax = 0;
return 0;
}

// Block until a value is ready. Record that you want to receive
Expand All @@ -315,7 +344,11 @@ static int
sys_ipc_recv(void *dstva)
{
// LAB 4: Your code here.
panic("sys_ipc_recv not implemented");
if ((size_t) dstva < UTOP && ((size_t) dstva % PGSIZE) != 0) return -E_INVAL;
curenv->env_ipc_recving = 1;
curenv->env_ipc_dstva = dstva;
curenv->env_status = ENV_NOT_RUNNABLE;
sys_yield();
return 0;
}

Expand Down
29 changes: 26 additions & 3 deletions lib/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,17 @@ int32_t
ipc_recv(envid_t *from_env_store, void *pg, int *perm_store)
{
// LAB 4: Your code here.
panic("ipc_recv not implemented");
return 0;
if (!pg) pg = (void *)-1;
int state = sys_ipc_recv(pg);
if (state < 0) {
if (from_env_store) *from_env_store = 0;
if (perm_store) *perm_store = 0;
return state;
}

if (from_env_store) *from_env_store = thisenv->env_ipc_from;
if (perm_store) *perm_store = thisenv->env_ipc_perm;
return thisenv->env_ipc_value;
}

// Send 'val' (and 'pg' with 'perm', if 'pg' is nonnull) to 'toenv'.
Expand All @@ -39,7 +48,21 @@ void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{
// LAB 4: Your code here.
panic("ipc_send not implemented");
if (!pg) {
pg = (void *)-1;
perm = 0;
}

int state;
while (1) {
state = sys_ipc_try_send(to_env, val, pg, perm);
if (state == 0) return;
if (state != -E_IPC_NOT_RECV) {
panic("ipc_send: %e", state);
}

sys_yield();
}
}

// Find the first environment of the given type. We'll use this to
Expand Down

0 comments on commit 289a520

Please sign in to comment.