mesg5.c 4.38 KB
#include <os.h>
#include <rmon.h>
#include "corefunc.h"

/*
 * mesg5
 *
 * Tests for:
 *	osJamMesg
 *	osRecvMesg
 *
 * Assumed working:
 *	osGetIntMask
 *	osSetIntMask
 *	osCreateMesgQueue
 *	osCreateThread
 *	osStartThread
 *	osYieldThread
 *
 * Description:
 *	Check that osRecvMesg blocks when requested and there are no messages.
 *	Check that osJamMesg does not yield processor when blocked receiving
 *		thread has same priority as sender.
 */

#define	MAX_MESSAGE	4

static void		slave(void *);

static OSMesgQueue	mesgQueue;
static OSMesg		mesgBuf[MAX_MESSAGE];

static OSMesgQueue	slaveMesgQueue;
static OSMesg		slaveMesgBuf[1];

static OSThread		slaveThread;
static char		slaveStack[STACKSIZE];


int
mesg5(void)
{
    OSIntMask savedMask, currentMask;
    OSMesg expectedMesg, actualMesg;
    int i;
    int addFailures, numFailures = 0;
    
    savedMask = osSetIntMask(OS_IM_ALL);

    osCreateMesgQueue(&slaveMesgQueue, slaveMesgBuf, 1);

    /* Set current thread priority to that of slave */
    osSetThreadPri(NULL, 10);

    osCreateThread(&slaveThread, 100, slave, (void *)0,
		   slaveStack+STACKSIZE, 10);
    osStartThread(&slaveThread);

    osCreateMesgQueue(&mesgQueue, mesgBuf, MAX_MESSAGE);

    /*
     * Loop a number of times, blocking on the reception of a message that will
     * be sent by the slave.  Since the message queue is circular buffer,
     * looping at least one more than the size of the queue is an
     * interesting test.
     */
    for (i = 0; i < MAX_MESSAGE+1; i++) {
	expectedMesg = (OSMesg)((i<<24)|(i<<16)|(i<<8)|i);
	(void)osRecvMesg(&mesgQueue, &actualMesg, OS_MESG_BLOCK);

	if (expectedMesg != actualMesg) {
	    osSyncPrintf("mesg5(1): expected message 0x%x, actual 0x%x\n",
			expectedMesg, actualMesg);
	    numFailures++;
	}
	currentMask = osGetIntMask();
	if (currentMask != OS_IM_ALL) {
	    osSyncPrintf("mesg5: expected interrupt mask 0x%x, actual 0x%x\n",
			OS_IM_ALL, currentMask);
	    numFailures++;
	}
    }

    /*
     * Loop again, receiving messages.  This time the slave will not
     * yield the processor, so only the first osRecvMesg will block.
     */
    for (i = MAX_MESSAGE-1; i >= 0; i--) {
	expectedMesg = (OSMesg)((i<<24)|(i<<16)|(i<<8)|i);
	(void)osRecvMesg(&mesgQueue, &actualMesg, OS_MESG_BLOCK);

	if (expectedMesg != actualMesg) {
	    osSyncPrintf("mesg5(2): expected message 0x%x, actual 0x%x\n",
			expectedMesg, actualMesg);
	    numFailures++;
	}
	currentMask = osGetIntMask();
	if (currentMask != OS_IM_ALL) {
	    osSyncPrintf("mesg5: expected interrupt mask 0x%x, actual 0x%x\n",
			OS_IM_ALL, currentMask);
	    numFailures++;
	}
    }

    (void)osRecvMesg(&slaveMesgQueue, (OSMesg *)&addFailures, OS_MESG_BLOCK);
    numFailures += addFailures;

    /*
     * Restore original interrupt mask and check it once more.
     */
    currentMask = osSetIntMask(savedMask);
    if (currentMask != OS_IM_ALL) {
	osSyncPrintf("mesg5: expected interrupt mask 0x%x, actual 0x%x\n",
		OS_IM_ALL, currentMask);
	numFailures++;
    }
    return(numFailures);
}

static void
slave(void *arg)
{
    OSIntMask currentMask;
    OSMesg expectedMesg;
    int i;
    int retValue;
    int numFailures = 0;

    /*
     * Loop and jam messages to the master, who is blocked waiting for it.
     * Then yield to allow the master to wait again.
     */
    for (i = 0; i < MAX_MESSAGE+1; i++) {
	expectedMesg = (OSMesg)((i<<24)|(i<<16)|(i<<8)|i);
	retValue = osJamMesg(&mesgQueue, expectedMesg, OS_MESG_NOBLOCK);

	if (retValue != 0) {
	    osSyncPrintf("mesg5: expected osJamMesg return value %d, actual %d\n",
			0, retValue);
	    numFailures++;
	}
	currentMask = osGetIntMask();
	if (currentMask != OS_IM_ALL) {
	    osSyncPrintf("mesg5: expected interrupt mask 0x%x, actual 0x%x\n",
			OS_IM_ALL, currentMask);
	    numFailures++;
	}
	osYieldThread();

    }

    /*
     * Loop again, but this time do not yield the processor.
     */
    for (i = 0; i < MAX_MESSAGE; i++) {
	expectedMesg = (OSMesg)((i<<24)|(i<<16)|(i<<8)|i);
	retValue = osJamMesg(&mesgQueue, expectedMesg, OS_MESG_NOBLOCK);

	if (retValue != 0) {
	    osSyncPrintf("mesg5: expected osJamMesg return value %d, actual %d\n",
			0, retValue);
	    numFailures++;
	}
	currentMask = osGetIntMask();
	if (currentMask != OS_IM_ALL) {
	    osSyncPrintf("mesg5: expected interrupt mask 0x%x, actual 0x%x\n",
			OS_IM_ALL, currentMask);
	    numFailures++;
	}
    }
    osJamMesg(&slaveMesgQueue, (OSMesg)numFailures, OS_MESG_BLOCK);
}