⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mos.cpp

📁 语法分析器 完成从c/c++向C++转变
💻 CPP
📖 第 1 页 / 共 2 页
字号:

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 + -