/* mailbox kernel services */

/*
 * Copyright (c) 1997-2014 Wind River Systems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <microkernel.h>
#include <string.h>
#include <toolchain.h>
#include <sections.h>

#include <micro_private.h>

#include <misc/__assert.h>
#include <misc/util.h>

/**
 *
 * @brief Determines if mailbox message is synchronous or asynchronous
 *
 * Returns a non-zero value if the specified message contains a valid pool ID,
 * indicating that it is an asynchronous message.
 */
#define ISASYNCMSG(message) ((message)->tx_block.pool_id != 0)

/**
 *
 * @brief Copy a packet
 *
 * @param in the packet to be copied
 * @param out the packet to copy to
 *
 * @return N/A
 */
static void copy_packet(struct k_args **out, struct k_args *in)
{
	GETARGS(*out);

	/*
	 * Copy the data from <in> to <*out> and create
	 * a backpointer to the original packet.
	 */

	memcpy(*out, in, sizeof(struct k_args));
	(*out)->Ctxt.args = in;
}

/**
 *
 * @brief Determine if there is a match between the mailbox sender and receiver
 *
 * @return matched message size, or -1 if no match
 */
static int match(struct k_args *Reader, struct k_args *Writer)
{
	if ((Reader->args.m1.mess.tx_task == ANYTASK ||
	     Reader->args.m1.mess.tx_task == Writer->args.m1.mess.tx_task) &&
	    (Writer->args.m1.mess.rx_task == ANYTASK ||
	     Writer->args.m1.mess.rx_task == Reader->args.m1.mess.rx_task)) {
		if (!ISASYNCMSG(&(Writer->args.m1.mess))) {
			int32_t info;

			Reader->args.m1.mess.tx_task =
				Writer->args.m1.mess.tx_task;

			Writer->args.m1.mess.rx_task =
				Reader->args.m1.mess.rx_task;

			info = Reader->args.m1.mess.info;
			Reader->args.m1.mess.info = Writer->args.m1.mess.info;
			Writer->args.m1.mess.info = info;
		} else {
			Reader->args.m1.mess.tx_task =
				Writer->args.m1.mess.tx_task;
			Reader->args.m1.mess.tx_data = NULL;
			Reader->args.m1.mess.tx_block =
				Writer->args.m1.mess.tx_block;
			Reader->args.m1.mess.info = Writer->args.m1.mess.info;
		}

		if (Reader->args.m1.mess.size > Writer->args.m1.mess.size) {
			Reader->args.m1.mess.size = Writer->args.m1.mess.size;
		} else {
			Writer->args.m1.mess.size = Reader->args.m1.mess.size;
		}

		/*
		 * The __ASSERT_NO_MSG() statements are used to verify that
		 * the -1 will not be returned when there is a match.
		 */

		__ASSERT_NO_MSG(Writer->args.m1.mess.size ==
			Reader->args.m1.mess.size);

		__ASSERT_NO_MSG(Reader->args.m1.mess.size != (uint32_t)(-1));

		return Reader->args.m1.mess.size;
	}

	return -1; /* There was no match */
}

/**
 * @brief Prepare transfer
 *
 * @return true or false
 */
static bool prepare_transfer(struct k_args *move,
					    struct k_args *reader,
					    struct k_args *writer)
{
	/* extract info from writer and reader before they change: */

	/*
	 * prepare writer and reader cmd packets for 'return':
	 * (this is shared code, irrespective of the value of 'move')
	 */
	__ASSERT_NO_MSG(reader->next == NULL);
	reader->Comm = _K_SVC_MBOX_RECEIVE_ACK;
	reader->Time.rcode = RC_OK;

	__ASSERT_NO_MSG(writer->next == NULL);
	writer->alloc = true;

	writer->Comm = _K_SVC_MBOX_SEND_ACK;
	writer->Time.rcode = RC_OK;

	if (move) {
		/* { move != NULL, which means full data exchange } */
		bool all_data_present = true;

		move->Comm = _K_SVC_MOVEDATA_REQ;
		/*
		 * transfer the data with the highest
		 * priority of reader and writer
		 */
		move->priority = max(writer->priority, reader->priority);
		move->Ctxt.task = NULL;
		move->args.moved_req.action =
			(MovedAction)(MVDACT_SNDACK | MVDACT_RCVACK);
		move->args.moved_req.total_size = writer->args.m1.mess.size;
		move->args.moved_req.extra.setup.continuation_send = NULL;
		move->args.moved_req.extra.setup.continuation_receive = NULL;

		/* reader: */
		if (reader->args.m1.mess.rx_data == NULL) {
			all_data_present = false;
			__ASSERT_NO_MSG(0 == reader->args.m1.mess.extra
					    .transfer); /* == extra.sema */
			reader->args.m1.mess.extra.transfer = move;
			/*SENDARGS(reader); */
		} else {
			move->args.moved_req.destination =
				reader->args.m1.mess.rx_data;
			writer->args.m1.mess.rx_data =
				reader->args.m1.mess.rx_data;

			/* chain the reader */
			move->args.moved_req.extra.setup.continuation_receive = reader;
		}

		/* writer: */
		if (ISASYNCMSG(&(writer->args.m1.mess))) {
			move->args.moved_req.source =
				writer->args.m1.mess.tx_block.pointer_to_data;
			reader->args.m1.mess.tx_block =
				writer->args.m1.mess.tx_block;
		} else {
			__ASSERT_NO_MSG(writer->args.m1.mess.tx_data != NULL);
			move->args.moved_req.source =
				writer->args.m1.mess.tx_data;
			reader->args.m1.mess.tx_data =
				writer->args.m1.mess.tx_data;
		}
		/* chain the writer */
		move->args.moved_req.extra.setup.continuation_send = writer;

		return all_data_present;
	}

	/* { NULL == move, which means header exchange only } */
	return 0; /* == don't care actually */
}

/**
 * @brief Do transfer
 *
 * @return N/A
 */
static void transfer(struct k_args *pMvdReq)
{
	__ASSERT_NO_MSG(pMvdReq->args.moved_req.source != NULL);
	__ASSERT_NO_MSG(pMvdReq->args.moved_req.destination != NULL);

	_k_movedata_request(pMvdReq);
	FREEARGS(pMvdReq);
}

/**
 * @brief Process the acknowledgment to a mailbox send request
 *
 * @return N/A
 */
void _k_mbox_send_ack(struct k_args *pCopyWriter)
{
	struct k_args *Starter;

	if (ISASYNCMSG(&(pCopyWriter->args.m1.mess))) {
		if (pCopyWriter->args.m1.mess.extra.sema) {
			/*
			 * Signal the semaphore.  Alternatively, this could
			 * be done using the continuation mechanism.
			 */

			struct k_args A;
#ifndef NO_KARG_CLEAR
			memset(&A, 0xfd, sizeof(struct k_args));
#endif
			A.Comm = _K_SVC_SEM_SIGNAL;
			A.args.s1.sema = pCopyWriter->args.m1.mess.extra.sema;
			_k_sem_signal(&A);
		}

		/*
		 * release the block from the memory pool
		 * unless this an asynchronous transfer.
		 */

		if (pCopyWriter->args.m1.mess.tx_block.pool_id != (uint32_t)(-1)) {
			/*
			 * special value to tell if block should be
			 * freed or not
			 */
			pCopyWriter->Comm = _K_SVC_MEM_POOL_BLOCK_RELEASE;
			pCopyWriter->args.p1.pool_id =
				pCopyWriter->args.m1.mess.tx_block.pool_id;
			pCopyWriter->args.p1.rep_poolptr =
				pCopyWriter->args.m1.mess.tx_block
					.address_in_pool;
			pCopyWriter->args.p1.rep_dataptr =
				pCopyWriter->args.m1.mess.tx_block
					.pointer_to_data;
			pCopyWriter->args.p1.req_size =
				pCopyWriter->args.m1.mess.tx_block.req_size;
			SENDARGS(pCopyWriter);
			return;
		}

		FREEARGS(pCopyWriter);
		return;
	}

	/*
	 * Get a pointer to the original command packet of the sender
	 * and copy both the result as well as the message information
	 * from the received packet of the sender before resetting the
	 * TF_SEND and TF_SENDDATA state bits.
	 */

	Starter = pCopyWriter->Ctxt.args;
	Starter->Time.rcode = pCopyWriter->Time.rcode;
	Starter->args.m1.mess = pCopyWriter->args.m1.mess;
	_k_state_bit_reset(Starter->Ctxt.task, TF_SEND | TF_SENDDATA);

	FREEARGS(pCopyWriter);
}

/**
 *
 * @brief Process the timeout for a mailbox send request
 *
 * @return N/A
 */
void _k_mbox_send_reply(struct k_args *pCopyWriter)
{
	FREETIMER(pCopyWriter->Time.timer);
	REMOVE_ELM(pCopyWriter);
	pCopyWriter->Time.rcode = RC_TIME;
	pCopyWriter->Comm = _K_SVC_MBOX_SEND_ACK;
	SENDARGS(pCopyWriter);
}

/**
 *
 * @brief Process a mailbox send request
 *
 * @return N/A
 */
void _k_mbox_send_request(struct k_args *Writer)
{
	kmbox_t MailBoxId = Writer->args.m1.mess.mailbox;
	struct _k_mbox_struct *MailBox;
	struct k_args *CopyReader;
	struct k_args *CopyWriter;
	struct k_args *temp;
	bool bAsync;

	bAsync = ISASYNCMSG(&Writer->args.m1.mess);

	struct k_task *sender = NULL;

	/*
	 * Only deschedule the task if it is not a poster
	 * (not an asynchronous request).
	 */

	if (!bAsync) {
		sender = _k_current_task;
		_k_state_bit_set(sender, TF_SEND);
	}

	Writer->Ctxt.task = sender;

	MailBox = (struct _k_mbox_struct *)MailBoxId;

	copy_packet(&CopyWriter, Writer);

	if (bAsync) {
		/*
		 * Clear the [Ctxt] field in an asynchronous request as the
		 * original packet will not be available later.
		 */

		CopyWriter->Ctxt.args = NULL;
	}

	/*
	 * The [next] field can be changed later when added to the Writer's
	 * list, but when not listed, [next] must be NULL.
	 */

	CopyWriter->next = NULL;

	for (CopyReader = MailBox->readers, temp = NULL; CopyReader != NULL;
	     temp = CopyReader, CopyReader = CopyReader->next) {
		uint32_t u32Size;

		u32Size = match(CopyReader, CopyWriter);

		if (u32Size != (uint32_t)(-1)) {
#ifdef CONFIG_OBJECT_MONITOR
			MailBox->count++;
#endif

			/*
			 * There is a match.  Remove the chosen reader from the
			 * list.
			 */

			if (temp != NULL) {
				temp->next = CopyReader->next;
			} else {
				MailBox->readers = CopyReader->next;
			}
			CopyReader->next = NULL;

#ifdef CONFIG_SYS_CLOCK_EXISTS
			if (CopyReader->Time.timer != NULL) {
				/*
				 * The reader was trying to handshake with
				 * timeout
				 */
				_k_timer_delist(CopyReader->Time.timer);
				FREETIMER(CopyReader->Time.timer);
			}
#endif

			if (u32Size == 0) {
				/* No data exchange--header only */
				prepare_transfer(NULL, CopyReader, CopyWriter);
				SENDARGS(CopyReader);
				SENDARGS(CopyWriter);
			} else {
				struct k_args *Moved_req;

				GETARGS(Moved_req);

				if (prepare_transfer(Moved_req,
						     CopyReader, CopyWriter)) {
					/*
					 * <Moved_req> will be cleared as well
					 */
					transfer(Moved_req);
				} else {
					SENDARGS(CopyReader);
				}
			}
			return;
		}
	}

	/* There is no matching receiver for this message. */

	if (bAsync) {
		/*
		 * For asynchronous requests, just post the message into the
		 * list and continue.  No further action is required.
		 */

		INSERT_ELM(MailBox->writers, CopyWriter);
		return;
	}

	if (CopyWriter->Time.ticks != TICKS_NONE) {
		/*
		 * The writer specified a wait or wait with timeout operation.
		 *
		 * Note: Setting the command to SEND_TMO is only necessary in
		 * the wait with timeout case.  However, it is more efficient
		 * to blindly set it rather than waste time on a comparison.
		 */

		CopyWriter->Comm = _K_SVC_MBOX_SEND_REPLY;

		/* Put the letter into the mailbox */
		INSERT_ELM(MailBox->writers, CopyWriter);

#ifdef CONFIG_SYS_CLOCK_EXISTS
		if (CopyWriter->Time.ticks == TICKS_UNLIMITED) {
			/* This is a wait operation; there is no timer. */
			CopyWriter->Time.timer = NULL;
		} else {
			/*
			 * This is a wait with timeout operation.
			 * Enlist a new timeout.
			 */
			_k_timeout_alloc(CopyWriter);
		}
#endif
	} else {
		/*
		 * This is a no-wait operation.
		 * Notify the sender of failure.
		 */
		CopyWriter->Comm = _K_SVC_MBOX_SEND_ACK;
		CopyWriter->Time.rcode = RC_FAIL;
		SENDARGS(CopyWriter);
	}
}

int task_mbox_put(kmbox_t mbox, kpriority_t prio, struct k_msg *M, int32_t timeout)
{
	struct k_args A;

	__ASSERT((M->size == 0) || (M->tx_data != NULL),
			 "Invalid mailbox data specification\n");

	if (unlikely(M->size == (uint32_t)(-1))) {
		/* the sender side cannot specify a size of -1 == 0xfff..ff */
		return RC_FAIL;
	}

	M->tx_task = _k_current_task->id;
	M->tx_block.pool_id = 0; /* NO ASYNC POST */
	M->extra.sema = 0;
	M->mailbox = mbox;

	A.priority = prio;
	A.Comm = _K_SVC_MBOX_SEND_REQUEST;
	A.Time.ticks = timeout;
	A.args.m1.mess = *M;

	KERNEL_ENTRY(&A);

	*M = A.args.m1.mess;
	return A.Time.rcode;
}

/**
 *
 * @brief Process a mailbox receive acknowledgment
 *
 * This routine processes a mailbox receive acknowledgment.
 *
 * INTERNAL:  This routine frees the <pCopyReader> packet
 *
 * @return N/A
 */
void _k_mbox_receive_ack(struct k_args *pCopyReader)
{
	struct k_args *Starter;

	/* Get a pointer to the original command packet of the sender */
	Starter = pCopyReader->Ctxt.args;

	/* Copy result from received packet */
	Starter->Time.rcode = pCopyReader->Time.rcode;

	/* And copy the message information from the received packet. */
	Starter->args.m1.mess = pCopyReader->args.m1.mess;

	/* Reschedule the sender task */
	_k_state_bit_reset(Starter->Ctxt.task, TF_RECV | TF_RECVDATA);

	FREEARGS(pCopyReader);
}

/**
 * @brief Process the timeout for a mailbox receive request
 *
 * @return N/A
 */
void _k_mbox_receive_reply(struct k_args *pCopyReader)
{
#ifdef CONFIG_SYS_CLOCK_EXISTS
	FREETIMER(pCopyReader->Time.timer);
	REMOVE_ELM(pCopyReader);
	pCopyReader->Time.rcode = RC_TIME;
	pCopyReader->Comm = _K_SVC_MBOX_RECEIVE_ACK;
	SENDARGS(pCopyReader);
#endif
}

/**
 * @brief Process a mailbox receive request
 *
 * @return N/A
 */
void _k_mbox_receive_request(struct k_args *Reader)
{
	kmbox_t MailBoxId = Reader->args.m1.mess.mailbox;
	struct _k_mbox_struct *MailBox;
	struct k_args *CopyWriter;
	struct k_args *temp;
	struct k_args *CopyReader;

	Reader->Ctxt.task = _k_current_task;
	_k_state_bit_set(Reader->Ctxt.task, TF_RECV);

	copy_packet(&CopyReader, Reader);

	/*
	 * The [next] field can be changed later when added to the Reader's
	 * list, but when not listed, [next] must be NULL.
	 */

	CopyReader->next = NULL;

	MailBox = (struct _k_mbox_struct *)MailBoxId;

	for (CopyWriter = MailBox->writers, temp = NULL; CopyWriter != NULL;
	     temp = CopyWriter, CopyWriter = CopyWriter->next) {
		uint32_t u32Size;

		u32Size = match(CopyReader, CopyWriter);

		if (u32Size != (uint32_t)(-1)) {
#ifdef CONFIG_OBJECT_MONITOR
			MailBox->count++;
#endif

			/*
			 * There is a match.  Remove the chosen reader
			 * from the list.
			 */

			if (temp != NULL) {
				temp->next = CopyWriter->next;
			} else {
				MailBox->writers = CopyWriter->next;
			}
			CopyWriter->next = NULL;

#ifdef CONFIG_SYS_CLOCK_EXISTS
			if (CopyWriter->Time.timer != NULL) {
				/*
				 * The writer was trying to handshake with
				 * timeout.
				 */
				_k_timer_delist(CopyWriter->Time.timer);
				FREETIMER(CopyWriter->Time.timer);
			}
#endif

			if (u32Size == 0) {
				/* No data exchange--header only */
				prepare_transfer(NULL, CopyReader, CopyWriter);
				SENDARGS(CopyReader);
				SENDARGS(CopyWriter);
			} else {
				struct k_args *Moved_req;

				GETARGS(Moved_req);

				if (prepare_transfer(Moved_req,
						     CopyReader, CopyWriter)) {
					/*
					 * <Moved_req> will be
					 * cleared as well
					 */
					transfer(Moved_req);
				} else {
					SENDARGS(CopyReader);
				}
			}
			return;
		}
	}

	/* There is no matching writer for this message. */

	if (Reader->Time.ticks != TICKS_NONE) {
		/*
		 * The writer specified a wait or wait with timeout operation.
		 *
		 * Note: Setting the command to RECV_TMO is only necessary in
		 * the wait with timeout case.  However, it is more efficient
		 * to blindly set it rather than waste time on a comparison.
		 */

		CopyReader->Comm = _K_SVC_MBOX_RECEIVE_REPLY;

		/* Put the letter into the mailbox */
		INSERT_ELM(MailBox->readers, CopyReader);

#ifdef CONFIG_SYS_CLOCK_EXISTS
		if (CopyReader->Time.ticks == TICKS_UNLIMITED) {
			/* This is a wait operation; there is no timer. */
			CopyReader->Time.timer = NULL;
		} else {
			/*
			 * This is a wait with timeout operation.
			 * Enlist a new timeout.
			 */
			_k_timeout_alloc(CopyReader);
		}
#endif
	} else {
		/*
		 * This is a no-wait operation.
		 * Notify the receiver of failure.
		 */
		CopyReader->Comm = _K_SVC_MBOX_RECEIVE_ACK;
		CopyReader->Time.rcode = RC_FAIL;
		SENDARGS(CopyReader);
	}
}


int task_mbox_get(kmbox_t mbox, struct k_msg *M, int32_t timeout)
{
	struct k_args A;

	M->rx_task = _k_current_task->id;
	M->mailbox = mbox;
	M->extra.transfer = 0;

	/*
	 * NOTE: to make sure there is no conflict with extra.sema,
	 * there is an assertion check in prepare_transfer() if equal to 0
	 */

	A.priority = _k_current_task->priority;
	A.Comm = _K_SVC_MBOX_RECEIVE_REQUEST;
	A.Time.ticks = timeout;
	A.args.m1.mess = *M;

	KERNEL_ENTRY(&A);
	*M = A.args.m1.mess;
	return A.Time.rcode;
}


void _task_mbox_block_put(kmbox_t mbox,
		 kpriority_t prio,
		 struct k_msg *M,
		 ksem_t sema)
{
	struct k_args A;

	__ASSERT(0xFFFFFFFF != M->size, "Invalid mailbox data specification\n");

	if (M->size == 0) {
		/*
		 * trick: special value to indicate that tx_block
		 * should NOT be released in the SND_ACK
		 */
		M->tx_block.pool_id = (uint32_t)(-1);
	}

	M->tx_task = _k_current_task->id;
	M->tx_data = NULL;
	M->mailbox = mbox;
	M->extra.sema = sema;

#ifdef CONFIG_SYS_CLOCK_EXISTS
	A.Time.timer = NULL;
#endif
	A.priority = prio;
	A.Comm = _K_SVC_MBOX_SEND_REQUEST;
	A.args.m1.mess = *M;
	KERNEL_ENTRY(&A);
}

/**
 *
 * @brief Process a mailbox receive data request
 *
 * @return N/A
 */
void _k_mbox_receive_data(struct k_args *Starter)
{
	struct k_args *CopyStarter;
	struct k_args *MoveD;
	struct k_args *Writer;

	Starter->Ctxt.task = _k_current_task;
	_k_state_bit_set(_k_current_task, TF_RECVDATA);

	GETARGS(CopyStarter);
	memcpy(CopyStarter, Starter, sizeof(struct k_args));
	CopyStarter->Ctxt.args = Starter;

	MoveD = CopyStarter->args.m1.mess.extra.transfer;
	CopyStarter->Comm = _K_SVC_MBOX_RECEIVE_ACK;
	CopyStarter->Time.rcode = RC_OK;

	MoveD->args.moved_req.extra.setup.continuation_receive = CopyStarter;
	CopyStarter->next = NULL;
	MoveD->args.moved_req.destination = CopyStarter->args.m1.mess.rx_data;

	MoveD->args.moved_req.total_size = CopyStarter->args.m1.mess.size;

	Writer = MoveD->args.moved_req.extra.setup.continuation_send;
	if (Writer != NULL) {
		if (ISASYNCMSG(&(Writer->args.m1.mess))) {
			CopyStarter->args.m1.mess.tx_block =
				Writer->args.m1.mess.tx_block;
		} else {
			Writer->args.m1.mess.rx_data =
				CopyStarter->args.m1.mess.rx_data;
			CopyStarter->args.m1.mess.tx_data =
				Writer->args.m1.mess.tx_data;
		}
		transfer(MoveD); /* and MoveD will be cleared as well */
	}
}


void _task_mbox_data_get(struct k_msg *M)
{
	struct k_args A;

	/* sanity checks */
	if (unlikely(M->extra.transfer == NULL)) {
		/*
		 * protection: if a user erroneously calls this function after
		 * a task_mbox_get(), we should not run into trouble
		 */
		return;
	}

	A.args.m1.mess = *M;
	A.Comm = _K_SVC_MBOX_RECEIVE_DATA;

	KERNEL_ENTRY(&A);
}


int task_mbox_data_block_get(struct k_msg *M, struct k_block *block,
			  kmemory_pool_t pool_id, int32_t timeout)
{
	int retval;
	struct k_args *MoveD;

	/* sanity checks: */
	if (M->extra.transfer == NULL) {
		/*
		 * If a user erroneously calls this function after a
		 * task_mbox_get(), we should not run into trouble.
		 * Return RC_OK instead of RC_FAIL to be downwards compatible.
		 */

		return RC_OK;
	}

	/* special flow to check for possible optimisations: */

	if (ISASYNCMSG(M)) {
		/* First transfer block */
		__ASSERT_NO_MSG(M->tx_block.pool_id != -1);
		*block = M->tx_block;

		/* This is the MOVED packet */
		MoveD = M->extra.transfer;

		/* Then release sender (writer) */

		struct k_args *Writer;

		/*
		 * This is the first of the continuation packets for
		 * continuation on send.  It should be the only one.
		 * That is, it should not have any followers.  To
		 * prevent [tx_block] from being released when the
		 * SEND_ACK is processed, change its [pool_id] to -1.
		 */

		Writer = MoveD->args.moved_req.extra.setup.continuation_send;
		__ASSERT_NO_MSG(Writer != NULL);
		__ASSERT_NO_MSG(Writer->next == NULL);

		Writer->args.m1.mess.tx_block.pool_id = (uint32_t)(-1);
		nano_task_stack_push(&_k_command_stack, (uint32_t)Writer);

#ifdef ACTIV_ASSERTS
		struct k_args *dummy;

		/*
		 * Confirm that there are not any continuation packets
		 * for continuation on receive.
		 */

		dummy = MoveD->args.moved_req.extra.setup.continuation_receive;
		__ASSERT_NO_MSG(dummy == NULL);
#endif

		FREEARGS(MoveD); /* Clean up MOVED */

		return RC_OK;
	}

	/* 'normal' flow of task_mbox_data_block_get(): */

	if (M->size != 0) {
		retval = task_mem_pool_alloc(block, pool_id,
					M->size, timeout);
		if (retval != RC_OK) {
			return retval;
		}
		M->rx_data = block->pointer_to_data;
	} else {
		block->pool_id = (kmemory_pool_t) -1;
	}

	/*
	 * Invoke task_mbox_data_get() core without sanity checks, as they have
	 * already been performed.
	 */

	struct k_args A;

	A.args.m1.mess = *M;
	A.Comm = _K_SVC_MBOX_RECEIVE_DATA;
	KERNEL_ENTRY(&A);

	return RC_OK; /* task_mbox_data_get() doesn't return anything */
}

/**
 * @brief Process a mailbox send data request
 *
 * @return N/A
 */
void _k_mbox_send_data(struct k_args *Starter)
{
	struct k_args *CopyStarter;
	struct k_args *MoveD;
	struct k_args *Reader;

	Starter->Ctxt.task = _k_current_task;
	_k_state_bit_set(_k_current_task, TF_SENDDATA);

	GETARGS(CopyStarter);
	memcpy(CopyStarter, Starter, sizeof(struct k_args));
	CopyStarter->Ctxt.args = Starter;

	MoveD = CopyStarter->args.m1.mess.extra.transfer;

	CopyStarter->Time.rcode = RC_OK;
	CopyStarter->Comm = _K_SVC_MBOX_SEND_ACK;

	MoveD->args.moved_req.extra.setup.continuation_send = CopyStarter;
	CopyStarter->next = NULL;
	MoveD->args.moved_req.source = CopyStarter->args.m1.mess.rx_data;

	Reader = MoveD->args.moved_req.extra.setup.continuation_receive;
	if (Reader != NULL) {
		Reader->args.m1.mess.rx_data =
			CopyStarter->args.m1.mess.rx_data;
		CopyStarter->args.m1.mess.tx_data =
			Reader->args.m1.mess.tx_data;

		transfer(MoveD); /* and MoveD will be cleared as well */
	}
}
