/************************************************************************
*
* Module name : MESSAGE.C
*
* Module description :
* This module manages inter-task message communication.
*
* Project : RTMK
*
* Target platform : DOS
*
* Compiler & Library : BC++ 3.1
*
* Author : Richard Shen
*
* Creation date : 17 August, 1995
*
************************************************************************/
#include
#include
#include "rtmkloc.h"
/************************************************************************
* Function name : RtmkPut
* Description : Send a message to the destination task
* :
* Parameters : process - Destination task control block
* : message - Message buffer
* Returns : -
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 17Aug95 RCS Created.
* 06Sep95 RCS Provide multi-process waiting on sending message
************************************************************************/
void RtmkPut(PROCESS process, void *message)
{
if (process->msgPending)
{
PROCESS p = process;
/*
If the destination task has a unread pending message, the message
originating task will preempted
*/
while (p->msgSender)
p = p->msgSender;
p->msgSender = curProcess; /* Save message sender */
while (process->msgPending)
{
DisableInterrupt();
readyProcess &= ~curProcess->procMask; /* Say process not ready */
EnableInterrupt();
Scheduler(NULL, FALSE); /* Switch to other task */
} /* end-of-while */
} /* end of if */
process->msgPending = TRUE; /* Message arrived */
DisableInterrupt();
readyProcess |= process->procMask; /* Process is ready to run */
EnableInterrupt();
/* Copy message to message buffer of destination tasks */
memcpy(process->msgBuf, (char *)message, MSG_BUF_SZ);
if (curProcess->priority < process->priority)
{
/* Priority is higher than the current process, switch to it */
Scheduler(process, FALSE);
} /* end of if */
} /* RtmkPut() */
/************************************************************************
* Function name : RtmkGet
* Description : Wait for a message and read message when arrived
* :
* Parameters : message - Message buffer to read from
* Returns : -
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 17Aug95 RCS Created.
* 06Sep95 RCS Provide multi-process waiting on sending message
************************************************************************/
void *RtmkGet(void *message)
{
while (curProcess->msgPending == FALSE)
{
/* Message not arrived */
DisableInterrupt();
readyProcess &= ~curProcess->procMask; /* Say process not ready */
EnableInterrupt();
if (curProcess->evWait && curProcess->evReceived)
{
/* Process ready flag is set by the arrival of an event */
return(NULL);
} /* end of if */
Scheduler(NULL, FALSE); /* Switch to next process */
} /* end of while */
/* Message arrived, copy message to data buffer */
memcpy((char *)message, curProcess->msgBuf, MSG_BUF_SZ);
curProcess->msgPending = FALSE;
/* Resume ready state of messsage sender */
if (curProcess->msgSender)
{
DisableInterrupt();
readyProcess |= curProcess->msgSender->procMask;
curProcess->msgSender = curProcess->msgSender->msgSender;
EnableInterrupt();
} /* end of if */
return(message);
} /* RtmkGet() */
/************************************************************************
* Function name : RtmkEmpty
* Description : Premitive returns the status of task's pending
* : message buffer
* Parameters : -
* Returns : FALSE, if there is a pending unread inter-task
* : message. Otherwise TRUE.
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 17Aug95 RCS Created.
************************************************************************/
bool RtmkEmpty(void)
{
if (curProcess->msgPending)
return(FALSE);
return(TRUE);
} /* RtmkEmpty() */