Changed full boolean with ipc flags and simplified ipc calls.

This commit is contained in:
Bahadir Balban
2009-05-23 13:52:06 +03:00
parent 63bf6c3e41
commit 577cc34db6
2 changed files with 49 additions and 42 deletions

View File

@@ -13,8 +13,8 @@
#if defined (__KERNEL__) #if defined (__KERNEL__)
/* These are for internally created ipc paths. */ /* These are for internally created ipc paths. */
int ipc_send(l4id_t to, int full); int ipc_send(l4id_t to, unsigned int flags);
int ipc_sendrecv(l4id_t to, l4id_t from, int full); int ipc_sendrecv(l4id_t to, l4id_t from, unsigned int flags);
#endif #endif

View File

@@ -15,21 +15,14 @@
#include INC_GLUE(message.h) #include INC_GLUE(message.h)
/* /*
* ipc syscall uses an ipc_type variable and flags and send/recv * ipc syscall uses an ipc_type variable and send/recv
* details are embedded in this variable. * details are embedded in this variable.
*/ */
#define IPC_TYPE_FLAGS_SHIFT 2
enum IPC_TYPE { enum IPC_TYPE {
IPC_INVALID = 0, IPC_INVALID = 0,
IPC_SEND = 1, IPC_SEND = 1,
IPC_RECV = 2, IPC_RECV = 2,
IPC_SENDRECV = 3, IPC_SENDRECV = 3,
IPC_SEND_FULL = 5,
IPC_RECV_FULL = 6,
IPC_SENDRECV_FULL = 7,
IPC_SEND_EXTENDED = 9,
IPC_RECV_EXTENDED = 10,
IPC_SENDRECV_EXTENDED = 11,
}; };
/* Copy full utcb region from one task to another. */ /* Copy full utcb region from one task to another. */
@@ -61,7 +54,7 @@ int ipc_full_copy(struct ktcb *to, struct ktcb *from)
* L4_ANYTHREAD. This is done for security since the receiver cannot trust * L4_ANYTHREAD. This is done for security since the receiver cannot trust
* the sender info provided by the sender task. * the sender info provided by the sender task.
*/ */
int ipc_msg_copy(struct ktcb *to, struct ktcb *from, int full) int ipc_msg_copy(struct ktcb *to, struct ktcb *from, unsigned int flags)
{ {
unsigned int *mr0_src = KTCB_REF_MR0(from); unsigned int *mr0_src = KTCB_REF_MR0(from);
unsigned int *mr0_dst = KTCB_REF_MR0(to); unsigned int *mr0_dst = KTCB_REF_MR0(to);
@@ -77,7 +70,7 @@ int ipc_msg_copy(struct ktcb *to, struct ktcb *from, int full)
mr0_dst[MR_SENDER] = from->tid; mr0_dst[MR_SENDER] = from->tid;
/* Check if full utcb copying is requested and do it */ /* Check if full utcb copying is requested and do it */
if (full) if (flags & L4_IPC_FLAGS_FULL)
ret = ipc_full_copy(to, from); ret = ipc_full_copy(to, from);
return ret; return ret;
@@ -133,8 +126,30 @@ int ipc_handle_errors(void)
* waitqueue have been removed at that stage. * waitqueue have been removed at that stage.
*/ */
int ipc_recv_extended(l4id_t recv_tid, unsigned int flags)
{
return 0;
}
int ipc_sendrecv_extended(l4id_t to, l4id_t from, unsigned int flags)
{
return 0;
}
int ipc_send_extended(l4id_t recv_tid, unsigned int flags)
{
//struct ktcb *receiver = tcb_find(recv_tid);
/*
* First we copy userspace buffer to process kernel stack.
* If we page fault, we only punish current process time.
*/
return 0;
}
/* Interruptible ipc */ /* Interruptible ipc */
int ipc_send(l4id_t recv_tid, int full) int ipc_send(l4id_t recv_tid, unsigned int flags)
{ {
struct ktcb *receiver = tcb_find(recv_tid); struct ktcb *receiver = tcb_find(recv_tid);
struct waitqueue_head *wqhs, *wqhr; struct waitqueue_head *wqhs, *wqhr;
@@ -163,7 +178,7 @@ 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, flags)) < 0)
ipc_signal_error(receiver, ret); ipc_signal_error(receiver, ret);
// printk("%s: (%d) Waking up (%d)\n", __FUNCTION__, // printk("%s: (%d) Waking up (%d)\n", __FUNCTION__,
@@ -189,7 +204,7 @@ int ipc_send(l4id_t recv_tid, int full)
return ipc_handle_errors(); return ipc_handle_errors();
} }
int ipc_recv(l4id_t senderid, int full) int ipc_recv(l4id_t senderid, unsigned int flags)
{ {
struct waitqueue_head *wqhs, *wqhr; struct waitqueue_head *wqhs, *wqhr;
int ret = 0; int ret = 0;
@@ -228,7 +243,7 @@ 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) flags)) < 0)
ipc_signal_error(sleeper, ret); ipc_signal_error(sleeper, ret);
// printk("%s: (%d) Waking up (%d)\n", // printk("%s: (%d) Waking up (%d)\n",
@@ -269,13 +284,13 @@ int ipc_recv(l4id_t senderid, int full)
* (6) System task calls ipc_send() sending the return result. * (6) System task calls ipc_send() sending the return result.
* (7) Rendezvous occurs. Both tasks exchange mrs and leave rendezvous. * (7) Rendezvous occurs. Both tasks exchange mrs and leave rendezvous.
*/ */
int ipc_sendrecv(l4id_t to, l4id_t from, int full) int ipc_sendrecv(l4id_t to, l4id_t from, unsigned int flags)
{ {
int ret = 0; int ret = 0;
if (to == from) { if (to == from) {
/* Send ipc request */ /* Send ipc request */
if ((ret = ipc_send(to, full)) < 0) if ((ret = ipc_send(to, flags)) < 0)
return ret; return ret;
/* /*
@@ -283,7 +298,7 @@ int ipc_sendrecv(l4id_t to, l4id_t from, int full)
* A client would block its server only very briefly * A client would block its server only very briefly
* between these calls. * between these calls.
*/ */
if ((ret = ipc_recv(from, full)) < 0) if ((ret = ipc_recv(from, flags)) < 0)
return ret; return ret;
} else { } else {
printk("%s: Unsupported ipc operation.\n", __FUNCTION__); printk("%s: Unsupported ipc operation.\n", __FUNCTION__);
@@ -292,34 +307,29 @@ int ipc_sendrecv(l4id_t to, l4id_t from, int full)
return ret; return ret;
} }
static inline int __sys_ipc(l4id_t to, l4id_t from, unsigned int ipc_type) static inline int __sys_ipc(l4id_t to, l4id_t from,
unsigned int ipc_type, unsigned int flags)
{ {
int ret; int ret;
switch (ipc_type) { switch (ipc_type) {
case IPC_SEND: case IPC_SEND:
ret = ipc_send(to, 0); if (flags & L4_IPC_FLAGS_EXTENDED)
ret = ipc_send_extended(to, flags);
else
ret = ipc_send(to, flags);
break; break;
case IPC_RECV: case IPC_RECV:
ret = ipc_recv(from, 0); if (flags & L4_IPC_FLAGS_EXTENDED)
ret = ipc_recv_extended(from, flags);
else
ret = ipc_recv(from, flags);
break; break;
case IPC_SENDRECV: case IPC_SENDRECV:
ret = ipc_sendrecv(to, from, 0); if (flags & L4_IPC_FLAGS_EXTENDED)
break; ret = ipc_sendrecv_extended(to, from, flags);
case IPC_SEND_FULL: else
ret = ipc_send(to, 1); ret = ipc_sendrecv(to, from, flags);
break;
case IPC_RECV_FULL:
ret = ipc_recv(from, 1);
break;
case IPC_SENDRECV_FULL:
ret = ipc_sendrecv(to, from, 1);
break;
case IPC_SEND_EXTENDED:
break;
case IPC_RECV_EXTENDED:
break;
case IPC_SENDRECV_EXTENDED:
break; break;
case IPC_INVALID: case IPC_INVALID:
default: default:
@@ -387,15 +397,12 @@ int sys_ipc(syscall_context_t *regs)
/* [1] for Receive, [1:0] for both */ /* [1] for Receive, [1:0] for both */
ipc_type |= ((from != L4_NILTHREAD) << 1); ipc_type |= ((from != L4_NILTHREAD) << 1);
/* Short, full or extended ipc set here. Bits [3:2] */
ipc_type |= (flags & L4_IPC_FLAGS_MASK) << IPC_TYPE_FLAGS_SHIFT;
if (ipc_type == IPC_INVALID) { if (ipc_type == IPC_INVALID) {
ret = -EINVAL; ret = -EINVAL;
goto error; goto error;
} }
if ((ret = __sys_ipc(to, from, ipc_type)) < 0) if ((ret = __sys_ipc(to, from, ipc_type, flags)) < 0)
goto error; goto error;
return ret; return ret;