📄 mos.cpp
字号:
SEM_HANDLE
MOS_C::SemInit(PCHAR pcSemName)
{
C_DEF_VMODULE("MOS_C::SemInit")
SEM_P pclSem;
PVOID pvTemp;
SEM_HANDLE sRetSemHandle;
// Check if exists already;
clSemList.FindFirst((PVOID *) &pclSem);
while(pclSem != NULL)
{
if(strcmp(pclSem -> GetName(),pcSemName) == 0)
return(pclSem -> GetHandle());
}
// must be new one
pclSem = new SEM_C;
pclSem -> SetName(pcSemName);
pclSem -> SetHandle(sSemHandle);
sRetSemHandle = sSemHandle;
sSemHandle++; // inc global handle
// insert into list
clSemList.FindLast(&pvTemp);
clSemList.AddAfterCur((PVOID) pclSem);
return(sRetSemHandle);
}
//
// Mos SemTerm
//
SHORT
MOS_C::SemTerm(SEM_HANDLE sSemHandle)
{
C_DEF_MODULE("MOS_C::SemTerm")
SEM_P pclSem;
PVOID pvTemp;
BOOL fFound = C_FALSE;
// Check if exists already;
clSemList.FindFirst((PVOID *) &pclSem);
while(pclSem != NULL)
{
if(pclSem -> GetHandle() == sSemHandle)
{
fFound = C_TRUE;
clSemList.DeleteCur();
delete pclSem;
break;
}
}
if(!fFound)
C_SET_STATUS(C_NOTOK)
C_RETURN
}
//
// Mos SemFindHandle
//
VOID
MOS_C::SemFindHandle(SEM_HANDLE sSemHandle, SEM_P * ppclSem, BOOL * pfFound)
{
C_DEF_VMODULE("MOS_C::SemFindHandle")
*pfFound = C_FALSE;
// Check if exists
clSemList.FindFirst((PVOID *) ppclSem);
while(*ppclSem != NULL)
{
if((*ppclSem) -> GetHandle() == sSemHandle)
{
*pfFound = C_TRUE;
break;
}
}
}
//
// Mos SemNextProc
//
VOID
MOS_C::SemNextProc(SEM_P pclSem)
{
C_DEF_MODULE("MOS_C::SemNextProc")
LONG lNumEntries;
PROC_P pclReleasedProc;
C_STATUS = pclSem -> clQueSemWait.GetEntries(&lNumEntries);
if(lNumEntries != 0)
{
//
// Retrieve the process which was waiting for the semaphore
//
C_STATUS = pclSem -> clQueSemWait.Deq((PVOID *) &pclReleasedProc);
//
// Place it back on the ready queue
//
C_STATUS = ReschedReady(pclReleasedProc);
//
// Give it the semaphore
//
C_STATUS = SemWait(pclSem -> GetHandle());
}
C_SET_STATUS(C_STATUS) // to make compiler be quiet
}
//
// Mos SemWait
//
SHORT
MOS_C::SemWait(SEM_HANDLE sSemHandle)
{
C_DEF_MODULE("MOS_C::SemWait")
SEM_P pclSem;
PVOID pvTemp;
BOOL fFound = C_FALSE;
#ifdef ANNOUNCE
printf("Process %d: %s : Requesting semaphore\n",
pclRunProc -> GetId(), pclRunProc -> GetName());
#endif
SemFindHandle(sSemHandle,&pclSem,&fFound);
if(fFound)
{
if(pclSem -> GetVal() != SEM_AVAIL)
{
#ifdef ANNOUNCE
printf("Process %d: %s : Queued for semaphore\n", pclRunProc -> GetId(),
pclRunProc -> GetName());
#endif
// Queue the process to wait for the semaphore
pclSem -> clQueSemWait.Enq((PVOID) pclRunProc);
pclRunProc -> SetState(PROC_STATE_SEM_WAIT);
C_STATUS = PROC_STATE_SUSPENDED;
}
else
{
#ifdef ANNOUNCE
printf("Process %d: %s : Obtained semaphore\n", pclRunProc -> GetId(),
pclRunProc -> GetName());
#endif
pclSem -> SetVal(pclSem -> GetVal() + 1);
pclRunProc -> SetfCritical(C_TRUE);
}
}
C_RETURN
}
//
// Sem Signal
//
// Called by a process when it releases exclusive access to the
// semaphore
//
SHORT
MOS_C::SemSignal(SEM_HANDLE sSemHandle)
{
C_DEF_MODULE("MOS_C::SemSignal")
SEM_P pclSem;
BOOL fFound;
#ifdef ANNOUNCE
printf("Process %d: %s : Releasing semaphore\n", pclRunProc -> GetId(),
pclProc -> GetName());
#endif
pclRunProc -> SetfCritical(C_FALSE);
SemFindHandle(sSemHandle,&pclSem,&fFound);
if(fFound)
{
pclSem -> SetVal(pclSem -> GetVal() -1);
SemNextProc(pclSem);
}
C_RETURN
}
//
// Sem Clear
//
// Called by a process when it releases exclusive access to the
// semaphore
//
SHORT
MOS_C::SemClear(SEM_HANDLE sSemHandle)
{
C_DEF_MODULE("MOS_C::SemClear")
SEM_P pclSem;
BOOL fFound;
#ifdef ANNOUNCE
printf("Process %d: %s : Clearing semaphore\n", pclRunProc -> GetId(),
pclRunProc -> GetName());
#endif
pclRunProc -> SetfCritical(C_FALSE);
SemFindHandle(sSemHandle,&pclSem,&fFound);
if(fFound)
{
pclSem -> SetVal(SEM_AVAIL);
SemNextProc(pclSem);
}
C_RETURN
}
//
// Mos SemSet
//
SHORT
MOS_C::SemSet(SEM_HANDLE sSemHandle)
{
C_DEF_MODULE("MOS_C::SemSet")
SEM_P pclSem;
PVOID pvTemp;
BOOL fFound = C_FALSE;
#ifdef ANNOUNCE
printf("Process %d: %s : Requesting semaphore\n",
pclRunProc -> GetId(), pclRunProc -> GetName());
#endif
SemFindHandle(sSemHandle,&pclSem,&fFound);
if(fFound)
{
#ifdef ANNOUNCE
printf("Process %d: %s : Setting semaphore\n", pclRunProc -> GetId(),
pclRunProc -> GetName());
#endif
pclSem -> SetVal(MOS_SEM_SET);
}
C_RETURN
}
//
// MosCurTime
//
// Mos function to get the current time
//
LONG
MOS_C::GetTime(VOID)
{
time_t lTime;
time(&lTime);
return((LONG) lTime);
}
//
// Mos Sleep
//
// Called by a process to setup for sleeping
//
SHORT
MOS_C::Sleep(LONG lSecs)
{
C_DEF_MODULE("MOS_C::Sleep")
pclRunProc -> SetState(PROC_STATE_SLEEPING);
pclRunProc -> SetWakeTime(GetTime() + lSecs);
#ifdef ANNOUNCE
printf("Process %d: %s : Sleeping till %d\n", pclProc -> GetId(),
pclProc -> GetName(),
pclProc -> GetWakeTime());
#endif
C_STATUS = clQueSleep.SetCompareFunc(MosCompareProcWakeTime);
C_STATUS = clQueSleep.Insert((PVOID) pclRunProc);
C_SET_STATUS(PROC_STATE_SUSPENDED)
C_RETURN
}
//
// MosCompareProcId
//
SHORT
MosCompareProcId(PVOID pvData1,PVOID pvData2)
{
PROC_P pclProc1;
PROC_P pclProc2;
pclProc1 = (PROC_P) pvData1;
pclProc2 = (PROC_P) pvData2;
if(pclProc1 -> GetId() == pclProc2 -> GetId())
return(C_EQUAL);
else if(pclProc1 -> GetId() < pclProc2 -> GetId())
return(C_LOWER);
else if(pclProc1 -> GetId() > pclProc2 -> GetId())
return(C_HIGHER);
}
//
// MosCompareProcId
//
SHORT
MosCompareProcName(PVOID pvData1,PVOID pvData2)
{
PROC_P pclProc1;
PROC_P pclProc2;
pclProc1 = (PROC_P) pvData1;
pclProc2 = (PROC_P) pvData2;
return(strcmp(pclProc1 -> GetName(),pclProc2 -> GetName()));
}
//
// MosMsgWrite
//
// Write a message (class) to a target process
//
SHORT
MOS_C::MsgWrite(MSG_P pclMsg)
{
C_DEF_MODULE("MOS_C::MsgWrite")
PROC_P pclDestProc;
PROC_P pclTempProc;
SHORT sPid;
#ifdef ANNOUNCE
printf("Process %d: %s : Sending message to procid %d\n", pclProc -> GetId(),
pclProc -> GetName(),
sTargetProcId);
#endif
//
// Setup message for sending
//
pclMsg -> SetSendPid(pclRunProc -> GetId());
//
// Find address of destination process
//
C_STATUS = clProcTree.SetCompareFunc(MosCompareIdNode);
sPid = pclMsg -> GetDestPid();
C_STATUS = clProcTree.Find((PVOID) &sPid, (PVOID *) &pclDestProc);
if(pclDestProc != NULL)
{
C_STATUS = pclDestProc -> clMsgQue.Enq((PVOID) pclMsg);
//
// Check if process was sleeping, if so, wake it up.
//
// Remove it from the sleeping queue and place on ready queue
//
if(pclDestProc -> GetState() == PROC_STATE_SLEEPING)
{
C_STATUS = clQueSleep.SetCompareFunc(MosCompareIdNode);
sPid = pclDestProc -> GetId();
C_STATUS = clQueSleep.Find((PVOID) &sPid,
(PVOID *) &pclTempProc);
C_STATUS = clQueSleep.DeleteCur();
C_STATUS = ReschedReady(pclDestProc);
}
//
// Check if process was waiting on message, if so
// Remove it from the msg wait queue and place on ready queue
//
if(pclDestProc -> GetState() == PROC_STATE_MSG_WAIT)
{
C_STATUS = clQueMsgWait.SetCompareFunc(MosCompareIdNode);
sPid = pclDestProc -> GetId();
C_STATUS = clQueMsgWait.Find((PVOID) &sPid,
(PVOID *) &pclTempProc);
C_STATUS = clQueMsgWait.DeleteCur();
C_STATUS = ReschedReady(pclDestProc);
}
}
C_RETURN
}
//
// Mos MsgWaiting
//
BOOL
MOS_C::MsgWaiting(VOID)
{
C_DEF_VMODULE("MOS_C::MsgRead")
LONG lEntries;
pclRunProc -> clMsgQue.GetEntries(&lEntries); // see if anything there
if(lEntries)
return((BOOL) C_TRUE);
else
return((BOOL) C_FALSE);
}
//
// MosMsgRead
//
// Read a message
//
SHORT
MOS_C::MsgRead(MSG_P ppclMsg)
{
C_DEF_MODULE("MOS_C::MsgRead")
LONG lEntries;
pclRunProc -> clMsgQue.GetEntries(&lEntries); // see if anything there
if(lEntries)
{
C_STATUS = pclRunProc -> clMsgQue.Deq((PPVOID) ppclMsg);
}
else
{
//
// Place in Msg Wait que (Added November 23, 1991)
//
pclRunProc -> SetState(PROC_STATE_MSG_WAIT);
C_STATUS = clQueMsgWait.Insert((PVOID) pclRunProc);
C_STATUS = PROC_STATE_SUSPENDED;
}
C_RETURN
}
/*
** MosEventCheckList
**
** Check Event List
*/
SHORT
MOS_C::EventCheckList(VOID)
{
C_DEF_MODULE("MOS_C::EventCheckList")
EVENT_P pstEvent;
if(sEvents == 0)
C_LEAVE(C_OK);
C_STATUS = pclEventList.FindFirst((PVOID *) &pstEvent);
while(pstEvent != NULL)
{
/* check for event occurance */
C_STATUS = (*(pstEvent -> pCheckFunc))();
if(C_STATUS)
{
/*
** if event occurred, place back on ready/run queue
** processes awaiting events may be of higher priority than
** normal processes
*/
C_STATUS = ReschedReady(pstEvent->pclEventProc);
}
C_STATUS = pclEventList.GetNext((PVOID *) &pstEvent);
}
C_SET_STATUS(C_OK);
C_MODULE_EXIT:
C_RETURN
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -