hw: send request size through UTCB

ref #874
This commit is contained in:
Martin Stein 2013-10-17 00:41:14 +02:00 committed by Norman Feske
parent 6b9376bb01
commit 45d37e275d
3 changed files with 39 additions and 14 deletions

View File

@ -335,8 +335,7 @@ namespace Kernel
/** /**
* Send IPC request and wait for reply * Send IPC request and wait for reply
* *
* \param id kernel name of the server thread * \param id kernel name of the server thread
* \param size size of request message located in the callers UTCB
* *
* \retval 0 successful * \retval 0 successful
* \retval -1 failed * \retval -1 failed
@ -344,9 +343,9 @@ namespace Kernel
* If the call returns successful the callers UTCB provides * If the call returns successful the callers UTCB provides
* a valid reply message and its size. * a valid reply message and its size.
*/ */
inline int request_and_wait(unsigned const id, size_t const size) inline int request_and_wait(unsigned const id)
{ {
return (int)syscall(REQUEST_AND_WAIT, id, size); return (int)syscall(REQUEST_AND_WAIT, id);
} }

View File

@ -61,7 +61,7 @@ static void utcb_to_msgbuf(Msgbuf_base * const msgbuf, size_t size)
} }
/** /**
* Copy message payload with integrated size toion message buffer * Copy message payload with size header to message buffer
* *
* This function pioneers IPC messages with headers and will * This function pioneers IPC messages with headers and will
* replace utcb_to_msgbuf sometime. * replace utcb_to_msgbuf sometime.
@ -92,6 +92,30 @@ static void msgbuf_to_utcb(Msgbuf_base * const msgbuf, size_t size,
} }
/**
* Copy message payload with size header to the UTCB
*
* This function pioneers IPC messages with headers and will
* replace msgbuf_to_utcb sometime.
*/
static void msgbuf_to_sized_utcb(Msgbuf_base * const msg_buf, size_t msg_size,
unsigned const local_name)
{
Native_utcb * const utcb = Thread_base::myself()->utcb();
enum { NAME_SIZE = sizeof(local_name) };
size_t const ipc_msg_size = msg_size + NAME_SIZE;
if (ipc_msg_size > utcb->max_ipc_msg_size()) {
kernel_log() << "oversized IPC message\n";
msg_size = utcb->max_ipc_msg_size() - NAME_SIZE;
}
*(unsigned *)utcb->ipc_msg_base() = local_name;
void * const utcb_msg = (void *)((addr_t)utcb->ipc_msg_base() + NAME_SIZE);
void * const buf_msg = (void *)((addr_t)msg_buf->buf + NAME_SIZE);
memcpy(utcb_msg, buf_msg, msg_size);
utcb->ipc_msg_size(ipc_msg_size);
}
/***************** /*****************
** Ipc_ostream ** ** Ipc_ostream **
*****************/ *****************/
@ -136,8 +160,9 @@ void Ipc_client::_call()
using namespace Kernel; using namespace Kernel;
/* send request and receive reply */ /* send request and receive reply */
msgbuf_to_utcb(_snd_msg, _write_offset, Ipc_ostream::_dst.local_name()); unsigned const local_name = Ipc_ostream::_dst.local_name();
int error = request_and_wait(Ipc_ostream::_dst.dst(), _write_offset); msgbuf_to_sized_utcb(_snd_msg, _write_offset, local_name);
int error = request_and_wait(Ipc_ostream::_dst.dst());
if (error) { throw Blocking_canceled(); } if (error) { throw Blocking_canceled(); }
sized_utcb_to_msgbuf(_rcv_msg); sized_utcb_to_msgbuf(_rcv_msg);

View File

@ -624,14 +624,15 @@ void Thread::_syscall_wait_for_request()
*/ */
void Thread::_syscall_request_and_wait() void Thread::_syscall_request_and_wait()
{ {
Thread * const dst = Thread::pool()->object(user_arg_1()); Thread * const dst = Thread::pool()->object(user_arg_1());
size_t const msg_size = (size_t)user_arg_2(); if (!dst) {
assert(dst); PERR("unkonwn recipient");
_await_ipc();
return;
}
Ipc_node::send_request_await_reply( Ipc_node::send_request_await_reply(
dst, _phys_utcb->base(), msg_size, dst, _phys_utcb->ipc_msg_base(), _phys_utcb->ipc_msg_size(),
_phys_utcb->ipc_msg_base(), _phys_utcb->ipc_msg_base(), _phys_utcb->max_ipc_msg_size());
_phys_utcb->max_ipc_msg_size());
} }