#include "vxWorks.h"
#include "semLib.h"
#include "taskLib.h"
#include "logLib.h"
#include "sysLib.h"
#include "stdio.h"
#define CONSUMER_TASK_PRI 98 /* Priority of the consumerTask task*/
#define PRODUCER_TASK_PRI 99 /* Priority of the producerTask task*/
#define PRODUCED 1 /* Flag to indicate produced status*/
#define CONSUMED 0 /* Flag to indicate consumed status*/
#define NUM_ITEMS 5 /* Number of items */
struct shMem /* Shared Memory data structure */
{
int tid; /* task id */
int count; /* count number of item produced */
int status; /* 0 if consumed or 1 if produced*/
};
LOCAL STATUS protectSharedResource (); /* protect shared data structure */
LOCAL STATUS releaseProtectedSharedResource (); /* release protected access */
LOCAL STATUS producerTask (); /* producer task */
LOCAL STATUS consumerTask (); /* consumer task */
LOCAL struct shMem shMemResource; /* shared memory structure */
LOCAL SEM_ID mutexSemId; /* mutual exclusion semaphore id*/
LOCAL BOOL notFinished; /* Flag that indicates the
* completion */
STATUS TestMSem()
{
notFinished = TRUE; /* initialize the global flag */
/* Create the mutual exclusion semaphore*/
if ((mutexSemId = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE
| SEM_INVERSION_SAFE)) == NULL)
{
perror ("Error in creating mutual exclusion semaphore");
return (ERROR);
}
/* Spwan the consumerTask task */
if (taskSpawn ("tConsumerTask", CONSUMER_TASK_PRI, 0, 5000,
(FUNCPTR) consumerTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
== ERROR)
{
perror ("consumerTask: Error in spawning demoTask");
return (ERROR);
}
/* Spwan the producerTask task */
if (taskSpawn ("tProducerTask", PRODUCER_TASK_PRI, 0, 5000,
(FUNCPTR) producerTask, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
== ERROR)
{
perror ("producerTask: Error in spawning demoTask");
return (ERROR);
}
/* Polling is not recommended. But used for making this demonstration
* simple */
while (notFinished)
taskDelay (sysClkRateGet ());
/* When done delete the mutual exclusion semaphore*/
if (semDelete (mutexSemId) == ERROR)
{
perror ("Error in deleting mutual exclusion semaphore");
return (ERROR);
}
return (OK);
}
/*****************************************************************************
* producerTask - produce the message, and write the message to the global
* shared data structure by obtaining exclusive access to
* that structure which is shared with the consumerTask.
*
* RETURNS: OK or ERROR
*
*/
STATUS producerTask ()
{
int count = 0;
int notDone = TRUE;
printf("in producerTask\n");
while (notDone)
{
/* Produce NUM_ITEMS, write each of these items to the shared
* global data structure.
*/
if (count < NUM_ITEMS)
{
/* Obtain exclusive access to the global shared data structure */
if (protectSharedResource() == ERROR)
return (ERROR);
/* Access and manipulate the global shared data structure */
if (shMemResource.status == CONSUMED)
{
count++;
shMemResource.tid = taskIdSelf ();
shMemResource.count = count;
shMemResource.status = PRODUCED;
}
/* Release exclusive access to the global shared data structure */
if (releaseProtectedSharedResource () == ERROR)
return (ERROR);
logMsg ("ProducerTask: tid = %#x, producing item = %d\n",
taskIdSelf (), count,0,0,0,0);
taskDelay (sysClkRateGet()/6); /* relingiush the CPU so that
* consumerTask can access the
* global shared data structure.
*/
}
else
notDone = FALSE;
}
return (OK);
}
/*****************************************************************************
* consumerTask - consumes the message from the global shared data
* structure and updates the status filled to CONSUMED
* so that producerTask can put the next produced message
* in the global shared data structure.
*
* RETURNS: OK or ERROR
*
*/
STATUS consumerTask ()
{
int notDone = TRUE;
printf("in consumerTask\n");
/* Initialize to consumed status */
if (protectSharedResource() == ERROR)
return (ERROR);
shMemResource.status = CONSUMED;
if (releaseProtectedSharedResource () == ERROR)
return (ERROR);
while (notDone)
{
taskDelay (sysClkRateGet()/6); /* relingiush the CPU so that
* producerTask can access the
* global shared data structure.
*/
/* Obtain exclusive access to the global shared data structure */
if (protectSharedResource() == ERROR)
return (ERROR);
/* Access and manipulate the global shared data structure */
if ((shMemResource.status == PRODUCED) && (shMemResource.count > 0))
{
logMsg ("ConsumerTask: Consuming item = %d from tid = %#x\n\n",
shMemResource.count, shMemResource.tid,0,0,0,0);
shMemResource.status = CONSUMED;
}
if (shMemResource.count >= NUM_ITEMS)
notDone = FALSE;
/* Release exclusive access to the global shared data structure */
if (releaseProtectedSharedResource () == ERROR)
return (ERROR);
}
notFinished = FALSE;
return (OK);
}
/*****************************************************************************
* protectSharedResource - Protect access to the shared data structure with
* the mutual exclusion semaphore.
*
* RETURNS: OK or ERROR
*
*/
LOCAL STATUS protectSharedResource ()
{
if (semTake (mutexSemId, WAIT_FOREVER) == ERROR)
{
perror ("protectSharedResource: Error in semTake");
return (ERROR);
}
else
return (OK);
}
/*****************************************************************************
* releaseProtectedSharedResource - Release the protected access to the
* shared data structure using the mutual
* exclusion semaphore
*
* RETURNS: OK or ERROR
*
*/
LOCAL STATUS releaseProtectedSharedResource ()
{
if (semGive (mutexSemId) == ERROR)
{
perror ("protectSharedResource: Error in semTake");
return (ERROR);
}
else
return (OK);
}