#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); }