Added error signalling/handling functions that better clarify ipc calls.

This commit is contained in:
Bahadir Balban
2009-05-22 23:14:53 +03:00
parent d632966778
commit 63bf6c3e41

View File

@@ -89,6 +89,43 @@ int sys_ipc_control(syscall_context_t *regs)
} }
/* /*
* Upon an ipc error or exception, the sleeper task is
* notified of it via flags set by this function.
*/
void ipc_signal_error(struct ktcb *sleeper, int retval)
{
/*
* Set ipc error flag in receiver.
* Only EFAULT is expected for now
*/
BUG_ON(retval != -EFAULT);
sleeper->flags |= IPC_EFAULT;
}
/*
* After an ipc, if current task was the sleeping party,
* this checks whether errors were signalled, clears
* the ipc flags and returns the appropriate error code.
*/
int ipc_handle_errors(void)
{
/* Did we wake up normally or get interrupted */
if (current->flags & TASK_INTERRUPTED) {
current->flags &= ~TASK_INTERRUPTED;
return -EINTR;
}
/* Did ipc fail with a fault error? */
if (current->flags & IPC_EFAULT) {
current->flags &= ~IPC_EFAULT;
return -EFAULT;
}
return 0;
}
/*
* NOTE:
* Why can we safely copy registers and resume task * Why can we safely copy registers and resume task
* after we release the locks? Because even if someone * after we release the locks? Because even if someone
* tried to interrupt and wake up the other party, they * tried to interrupt and wake up the other party, they
@@ -126,11 +163,8 @@ int ipc_send(l4id_t recv_tid, int full)
spin_unlock(&wqhs->slock); spin_unlock(&wqhs->slock);
/* Copy message registers */ /* Copy message registers */
if ((ret = ipc_msg_copy(receiver, current, full)) < 0) { if ((ret = ipc_msg_copy(receiver, current, full)) < 0)
/* Set ipc error flag in receiver */ ipc_signal_error(receiver, ret);
BUG_ON(ret != -EFAULT);
receiver->flags |= IPC_EFAULT;
}
// printk("%s: (%d) Waking up (%d)\n", __FUNCTION__, // printk("%s: (%d) Waking up (%d)\n", __FUNCTION__,
// current->tid, receiver->tid); // current->tid, receiver->tid);
@@ -152,18 +186,7 @@ int ipc_send(l4id_t recv_tid, int full)
// current->tid, recv_tid); // current->tid, recv_tid);
schedule(); schedule();
/* Did we wake up normally or get interrupted */ return ipc_handle_errors();
if (current->flags & TASK_INTERRUPTED) {
current->flags &= ~TASK_INTERRUPTED;
return -EINTR;
}
/* Did ipc fail with a fault error? */
if (current->flags & IPC_EFAULT) {
current->flags &= ~IPC_EFAULT;
return -EFAULT;
}
return 0;
} }
int ipc_recv(l4id_t senderid, int full) int ipc_recv(l4id_t senderid, int full)
@@ -205,14 +228,11 @@ int ipc_recv(l4id_t senderid, int full)
/* Copy message registers */ /* Copy message registers */
if ((ret = ipc_msg_copy(current, sleeper, if ((ret = ipc_msg_copy(current, sleeper,
full)) < 0) { full)) < 0)
ipc_signal_error(sleeper, ret);
/* Set ipc fault flag on sleeper */ // printk("%s: (%d) Waking up (%d)\n",
BUG_ON(ret != -EFAULT); // __FUNCTION__,
sleeper->flags |= IPC_EFAULT;
}
// printk("%s: (%d) Waking up (%d)\n", __FUNCTION__,
// current->tid, sleeper->tid); // current->tid, sleeper->tid);
sched_resume_sync(sleeper); sched_resume_sync(sleeper);
return ret; return ret;
@@ -232,19 +252,7 @@ int ipc_recv(l4id_t senderid, int full)
spin_unlock(&wqhs->slock); spin_unlock(&wqhs->slock);
schedule(); schedule();
/* Did we wake up normally or get interrupted */ return ipc_handle_errors();
if (current->flags & TASK_INTERRUPTED) {
current->flags &= ~TASK_INTERRUPTED;
return -EINTR;
}
/* Did ipc fail with a fault error? */
if (current->flags & IPC_EFAULT) {
current->flags &= ~IPC_EFAULT;
return -EFAULT;
}
return 0;
} }
/* /*