📄 philosopherthread.c
字号:
/* =============================================================================
*
* Description: This is the C implementation for Thread PhilosopherThread
*
* -----------------------------------------------------------------------------
* Comments:
*
* ===========================================================================*/
/* Get access to any of the VDK features & datatypes used */
#include "VDK.h"
#include <stdio.h>
/* Macros */
#define PRINT_STATE(name,state) \
do \
{ \
VDK_PushUnscheduledRegion(); \
printf("Philosopher-%s is %s at time %d\n",name,state,VDK_GetUptime()); \
fflush(stdout); \
VDK_PopUnscheduledRegion(); \
} while(0)
typedef struct PhilosopherData
{
char *name;
VDK_SemaphoreID left, right;
VDK_EventBitID full;
} PhilosopherData;
static const PhilosopherData philosopherInstanceData[5] =
{
"1", kChopStick5, kChopStick1, kPhilosopher1Full,
"2", kChopStick1, kChopStick2, kPhilosopher2Full,
"3", kChopStick2, kChopStick3, kPhilosopher3Full,
"4", kChopStick3, kChopStick4, kPhilosopher4Full,
"5", kChopStick4, kChopStick5, kPhilosopher5Full
};
void
PhilosopherThread_RunFunction(void **inPtr)
{
int chopsticksAvailable;
const PhilosopherData *pData = (const PhilosopherData *)*inPtr;
/* We need to wait for everbody else */
/* philosopher is thinking now */
PRINT_STATE(pData->name,"THINKING");
/* philosopher collects both left and right chopsticks, if not available she will wait */
/* philosopher is hungry */
PRINT_STATE(pData->name,"HUNGRY");
do {
/* make sure no other thread takes control */
VDK_PushUnscheduledRegion();
/* if the chopsticks are available then acquire them atomically */
chopsticksAvailable = (VDK_GetSemaphoreValue(pData->left) && VDK_GetSemaphoreValue(pData->right));
if (chopsticksAvailable) /* Both chopsticks are available */
{
PRINT_STATE(pData->name,"Grabbing both");
/* philosopher takes her left and right chopsticks */
VDK_PendSemaphore(pData->left,0);
VDK_PendSemaphore(pData->right,0);
/* let other threads take control now */
VDK_PopUnscheduledRegion();
} else {
/* give someone else a chance */
VDK_PopUnscheduledRegion();
VDK_Yield();
}
} while ( !chopsticksAvailable );
/* philosopher is eating now */
PRINT_STATE( pData->name,"EATING");
VDK_Sleep( 3 ); /* Just to simulate eating */
PRINT_STATE( pData->name,"DONE");
/* once she finishes she will put both the chopsticks back on the table */
/* philosopher puts both the chopsticks on the table */
VDK_PostSemaphore(pData->left);
VDK_PostSemaphore(pData->right);
/* let the System control thread know that I'm done */
VDK_SetEventBit(pData->full);
PRINT_STATE( pData->name,"LEAVING");
/* Check if all threads have finished to print a message */
if (VDK_GetEventValue(kAllPhilosophersFull) == true)
{
VDK_PushUnscheduledRegion();
printf("---------- All Done ----------\n");
fflush(stdout);
VDK_PopUnscheduledRegion();
}
/* The semaphore never gets posted. The thread will be pending forever */
VDK_PendSemaphore(kAllDone,0);
}
int
PhilosopherThread_ErrorFunction(void **inPtr)
{
/* Put this thread's error handling code HERE */
/* we ignore this error because we know we getting while checking the
* value of a semaphore in an unscheduled region */
if (VDK_GetLastThreadError() == VDK_kDbgPossibleBlockInRegion)
return VDK_kDbgPossibleBlockInRegion;
else {
/* The default ErrorHandler goes to KernelPanic */
VDK_CThread_Error(VDK_GetThreadID());
return 0;
}
}
void
PhilosopherThread_InitFunction(void **inPtr, VDK_ThreadCreationBlock *pTCB)
{
/* Put code to be executed when this thread has just been created HERE */
int instanceNum = *((int *)pTCB->user_data_ptr);
*inPtr = (void*) (&philosopherInstanceData[instanceNum - 1]);
/* This routine does NOT run in new thread's context. Any non-static thread
* initialization should be performed at the beginning of "Run()."
*/
}
void
PhilosopherThread_DestroyFunction(void **inPtr)
{
/* Put code to be executed when this thread is destroyed HERE */
/* This routine does NOT run in the thread's context. Any VDK API calls
* should be performed at the end of "Run()."
*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -