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

📄 exec.cpp

📁 一个嵌入式系统的C代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// RETURNS: TRUE  .. process moved//          FALSE .. unknown process or not suspended!//BOOL Exec::Resume (UINT16 uTarg){  if (uTarg == PqSusBlock.PqGet(uTarg)) {    arrPCB[uTarg].uStatus &= ~PS_Suspended;    PqBlocked.PqAdd(arrPCB[uTarg]);    MSG msg(ID_Kernel, ANI_SBLK_BLK, uTarg);    pTx->SendMsg(ID_ANIM, &msg);    return TRUE;  }  if (uTarg == PqSusReady.PqGet(uTarg)) {    arrPCB[uTarg].uStatus &= ~PS_Suspended;    PqReady.PqAdd(arrPCB[uTarg]);    MSG msg(ID_Kernel, ANI_SRDY_RDY, uTarg);    pTx->SendMsg(ID_ANIM, &msg);    return TRUE;  }  return FALSE;}/////////////////// Add the passed message to the reply message queue of process <uProc>// (which will cause it to un-block next time the scheduler runs).  In// this release of RCOS, the reply queue is limited to one message for// simplicity.  If the process was suspended, move it to the Suspended// Ready queue.//// If the unblocking process is free to run and has a higher priority// than the current process (if any), of the reason for the unblocking// is <KM_Signal> (ie an IPC message), the current process gets pre-empted// by unilaterally clobbering its remaining quantum.//void Exec::PostReply (UINT16 uProc, PMSG pM){  if (arrPCB[uProc].uPid != NO_PROC) {    arrPCB[uProc].pReply = new MSG(*pM);    arrPCB[uProc].uStatus &= ~PS_Blocked;    if (arrPCB[uProc].uStatus & PS_Suspended) {      if (uProc == PqSusBlock.PqGet(uProc)) {        PqSusReady.PqAdd(arrPCB[uProc]);        MSG msg(ID_Kernel, ANI_SBLK_SRDY, uProc);        pTx->SendMsg(ID_ANIM, &msg);      }    }    else      if ((uCurProc != NO_PROC) &&         ((arrPCB[uProc].nPriority > arrPCB[uCurProc].nPriority) ||          (pM->wMsgType == KM_Signal))) {        arrPCB[uCurProc].nQuantum = PCD_PREEMPT;        MSG msg(ID_Kernel, ANI_PREEMPT, uProc);        pTx->SendMsg(ID_ANIM, &msg);      }  }}//////////////////////// Remove all trace of this process and its memory allocation - including// any shared memory blocks.// NOTE :: This is VERY incomplete - frinstance, we unilaterally dispose// of memory - what if the process is sharing text with another, eh?// RETURNS: TRUE  .. process deleted Ok//          FALSE .. invalid process ID//BOOL Exec::Kill (UINT16 uTarg){  if (arrPCB[uTarg].uPid != NO_PROC) {    MSG msg(ID_Kernel, KM_Close, (UINT16)arrMCB[uTarg].hText);    pTx->SendMsg(ID_MMU, &msg);    arrMCB[uTarg].hText = (HANDLE)ID_NULL;    msg = message(ID_Kernel, KM_Close, arrMCB[uTarg].hStack);    pTx->SendMsg(ID_MMU, &msg);    arrMCB[uTarg].hStack = (HANDLE)ID_NULL;    if (arrPCB[uTarg].pszName) {      DELETE_ARRAY arrPCB[uTarg].pszName;      arrPCB[uTarg].pszName = NULL;    }    if (arrPCB[uTarg].pDev) {      delete arrPCB[uTarg].pDev;      arrPCB[uTarg].pDev = NULL;    }    UINT16 *pn;    while (pn = (UINT16*)arrPCB[uTarg].Share.DblGetHead())      SmClose(uTarg, *pn);    if (arrPCB[uTarg].pFile)      delete arrPCB[uTarg].pFile;    arrPCB[uTarg].pFile = NULL;    arrPCB[uTarg].uPid = NO_PROC;    --uProcCnt;    return TRUE;  }  return FALSE;}//////////////////////// Create a new process - Only way to do this is for the current process// to fork (are processes like bacteria?), but Process ZERO pulls a trick.// It is not a p-code process, but it has stack and text segments allocated// to it which we will duplicate for its child.  Before invoking <fork>, it// has set the p-code to <execl> and loaded the name of the replacement// program onto its stack - so when the new process (Child of Conx) gets// the CPU, it's first action is to load itself.  P-code processes that// fork will duplicate their stack and text, retaining any handles to shared// memory, semiphores and open streams. Note that shared memory blocks must// have their usage count increased.//// RETURNS: PID      Of child created, or//          NO_PROC  if process could not be created//UINT16 Exec::Fork (void){  if (uProcCnt < MAX_PROC) {    INT16 i;    for (i = 1; i < MAX_PROC; i++)      if (arrPCB[i].uPid == NO_PROC)        break;    arrPCB[i].uStatus = PS_Zombie;    MSG msg(ID_Kernel, MMU_Duplicate, arrMCB[uCurProc].hText);    pTx->SendMsg(ID_MMU, &msg);    if (arrMCB[i].hText = (HANDLE)msg.wParam) {      msg = message(ID_Kernel, MMU_Duplicate, arrMCB[uCurProc].hStack);      pTx->SendMsg(ID_MMU, &msg);      if (0 == (arrMCB[i].hStack = (HANDLE)msg.wParam)) {        msg = message(ID_Kernel, KM_Close, arrMCB[i].hText);        pTx->SendMsg(ID_MMU, &msg);      }      else {        ++uProcCnt;        arrPCB[i].uPid = i;        arrPCB[i].uPidp = uCurProc;        arrPCB[i].nPriority = DEF_PRIORITY;        arrPCB[i].pReply = NULL;        arrPCB[i].pFile = NULL;        arrPCB[i].uIP = arrPCB[uCurProc].uIP;        arrPCB[i].uSP = arrPCB[uCurProc].uSP;        arrPCB[i].uBP = arrPCB[uCurProc].uBP;        arrPCB[i].uStatus = PS_Created;        PqIn.PqAdd(arrPCB[i]);        UINT16 *pn = (UINT16*)arrPCB[uCurProc].Share.DblGetHead();        while (pn) {          ShareMem.QmIncCnt(*pn);          arrPCB[i].Share.DblAppend((void*)pn, sizeof(UINT16));          pn = (UINT16*)arrPCB[uCurProc].Share.DblGetNext();        }        msg = message(ID_Kernel, ANI_FORKS, i);        pTx->SendMsg(ID_ANIM, &msg);        return i;      }    }  }  return NO_PROC;}////////////// Take a "snapshot" of the current contents for the Animator..//void Exec::GetQcom (UINT16 uWhich, PMSG_ANIQ pUarr){  if (uWhich == 0) {    PqIn.PqImage(pUarr->arr[0]);    PqReady.PqImage(pUarr->arr[1]);    PqBlocked.PqImage(pUarr->arr[2]);    PqSusReady.PqImage(pUarr->arr[3]);    PqSusBlock.PqImage(pUarr->arr[4]);  }  else {    switch ((uWhich >> 8) & 0xff) {      case INPUT_Q: PqIn.PqImage(pUarr->arr[0]); break;      case READY_Q: PqReady.PqImage(pUarr->arr[0]); break;      case BLOKED_Q: PqBlocked.PqImage(pUarr->arr[0]); break;      case SUSRDY_Q: PqSusReady.PqImage(pUarr->arr[0]); break;      case SUSBLK_Q: PqSusBlock.PqImage(pUarr->arr[0]); break;    }    switch (uWhich & 0xff) {      case INPUT_Q: PqIn.PqImage(pUarr->arr[1]); break;      case READY_Q: PqReady.PqImage(pUarr->arr[1]); break;      case BLOKED_Q: PqBlocked.PqImage(pUarr->arr[1]); break;      case SUSRDY_Q: PqSusReady.PqImage(pUarr->arr[1]); break;      case SUSBLK_Q: PqSusBlock.PqImage(pUarr->arr[1]); break;    }  }}/////////////// Fill in details of current process for animator..//void Exec::GetPcom (PMSG_ANIP pM){  if (uCurProc == NO_PROC)    pM->uNr[0] = NO_PROC;  else {    pM->uNr[0] = arrPCB[uCurProc].uPid;    pM->uNr[1] = arrPCB[uCurProc].uPidp;    pM->uNr[2] = arrPCB[uCurProc].uBP;    pM->uNr[3] = arrPCB[uCurProc].uIP;    pM->uNr[4] = arrPCB[uCurProc].uSP;    pM->uNr[5] = arrPCB[uCurProc].uTos;    pM->uNr[6] = arrPCB[uCurProc].nQuantum;    pM->nPri   = arrPCB[uCurProc].nPriority;    pM->pszName = arrPCB[uCurProc].pszName;    DeCode(arrPCB[uCurProc].lCode, pM->szPCD);  }}/////////////////////////////////////////////////////////////////////////////                 Class Member Functions for the Priority Queue//-------------------------------------------------------------------------// Create a priority queue for processes.  No limit placed on size, since// no more than MAX_PROC can ever be created - so even if they all arrive// in this queue at the same time (unlikeley), the total size is limited.// Ordered instatntiations will hold entries in descending priority.//Pque::Pque (BOOL bOrd) : DblList(DESCENDING){  bOrdered = bOrd;}Pque::~Pque (void){  PQMBR pD = (PQMBR)DblGetHead();  while (pD) {    DblDelete();    pD = (PQMBR)DblGetNext();  }}//////////// Check for any elements in queue// RETURNS: TRUE  .. yes there is//          FALSE .. no there 'aint//BOOL Pque::PqEmpty (void){  return ((DblGetHead() == NULL) ? TRUE : FALSE);}///////////// Add a PID to this queue.  If the queue is ordered, insert at priority// one less than actual, then adjust back to correct.  This ensures that// processes at equal priority are served Round-Robin.//void Pque::PqAdd (PCB& proc){  QMBR temp;  temp.uPid = proc.uPid;  temp.nKey = proc.nPriority - 1;  if (!bOrdered)    DblAppend((void*)&temp, sizeof(QMBR));  else {    PQMBR pLoc = (PQMBR)DblInsert((void*)&temp, sizeof(QMBR));    pLoc->nKey++;  }}/////////////////// Remove member from head queue - use with ordered queue to "get" member// with highest "key" (normally priority, but could be quantum, whatever..)// RETURNS: PID # removed, or//          NO_PROC if queue empty//UINT16 Pque::PqGet (void){  PQMBR pD = (PQMBR)DblGetHead();  if (pD) {    UINT16 uPid = pD->uPid;    DblDelete();    return uPid;  }  return NO_PROC;}/////////////////// Remove member with passed process ID from queue// RETURNS: PID # removed, or//          NO_PROC if queue empty//UINT16 Pque::PqGet (UINT16 uTarg){  PQMBR pD = (PQMBR)DblGetHead();  while (pD)    if (pD->uPid != uTarg)      pD = (PQMBR)DblGetNext();    else {      UINT16 uPid = pD->uPid;      DblDelete();      return uPid;    }  return NO_PROC;}//////////////////// See if passed PID is in this list// RETURNS: TRUE  .. yes it is//          FALSE .. no it ain't//BOOL Pque::PqFind (UINT16 uTarg){  PQMBR pD = (PQMBR)DblGetHead();  while (pD) {    if (pD->uPid == uTarg)      return TRUE;    pD = (PQMBR)DblGetNext();  }  return FALSE;}/////////////// The passed pointer references an array [MAX_PROC] of UINT. This routine// copies the queues PID numbers into the array, setting empty elements to// 0xffff (why didn't I just use signed ints in the first place?).//void Pque::PqImage (UINT16 *p){  PQMBR pD = (PQMBR)DblGetHead();  for (INT16 i = 0; i < MAX_PROC; i++) {    *(p + i) = ((pD) ? pD->uPid : NO_PROC);    if (pD)      pD = (PQMBR)DblGetNext();  }}/////////////////////////////////// eof ////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -