Пример #1
0
//----------------------------------------------------------------------
//
//	ProcessSuspend
//
//	Place a process in suspended animation until it's
//	awakened by ProcessAwaken.
//
//	NOTE: This must only be called from an interrupt or trap.  It
//	should be immediately followed by ProcessSchedule().
//
//----------------------------------------------------------------------
void ProcessSuspend (PCB *suspend) {
  // Make sure it's already a runnable process.
  dbprintf ('p', "Suspending PCB 0x%x (%s).\n", (int)suspend, suspend->name);
  ASSERT (suspend->flags & PROCESS_STATUS_RUNNABLE, "Trying to suspend a non-running process!\n");
  ProcessSetStatus (suspend, PROCESS_STATUS_WAITING);
  ClkResetProcess();
  if (AQueueRemove(&(suspend->l)) != QUEUE_SUCCESS) {
    printf("FATAL ERROR: could not remove process from run Queue in ProcessSuspend!\n");
    exitsim();
  }
  if ((suspend->l = AQueueAllocLink(suspend)) == NULL) {
    printf("FATAL ERROR: could not get Queue Link in ProcessSuspend!\n");
    exitsim();
  }
  if (AQueueInsertLast(&waitQueue, suspend->l) != QUEUE_SUCCESS) {
    printf("FATAL ERROR: could not insert suspend PCB into waitQueue!\n");
    exitsim();
  }
}
Пример #2
0
//----------------------------------------------------------------------
//
//	doInterrupt
//
//	Handle an interrupt or trap.
//
//----------------------------------------------------------------------
void
dointerrupt (unsigned int cause, unsigned int iar, unsigned int isr,
	     uint32 *trapArgs)
{
  int	result;
  int	i;
  uint32	args[4];
  int	intrs;
  uint32 handle;
  int ihandle;

  dbprintf ('t',"Interrupt cause=0x%x iar=0x%x isr=0x%x args=0x%08x.\n",
	    cause, iar, isr, (int)trapArgs);
  // If the TRAP_INSTR bit is set, this was from a trap instruction.
  // If the bit isn't set, this was a system interrupt.
  if (cause & TRAP_TRAP_INSTR) {
    cause &= ~TRAP_TRAP_INSTR;
    switch (cause) {
    case TRAP_CONTEXT_SWITCH:
      dbprintf ('t', "Got a context switch trap!\n");
      ProcessSchedule ();
      ClkResetProcess();
      break;
    case TRAP_EXIT:
    case TRAP_USER_EXIT:
      dbprintf ('t', "Got an exit trap!\n");
      ProcessDestroy (currentPCB);
      ProcessSchedule ();
      ClkResetProcess();
      break;
    case TRAP_PROCESS_FORK:
      dbprintf ('t', "Got a fork trap!\n");
      break;
    case TRAP_PROCESS_SLEEP:
      dbprintf ('t', "Got a process sleep trap!\n");
      ProcessSuspend (currentPCB);
      ProcessSchedule ();
      ClkResetProcess();
      break;
    case TRAP_PRINTF:
      // Call the trap printf handler and pass the arguments and a flag
      // indicating whether the trap was called from system mode.
      dbprintf ('t', "Got a printf trap!\n");
      TrapPrintfHandler (trapArgs, isr & DLX_STATUS_SYSMODE);
      break;
    case TRAP_OPEN:
      // Get the arguments to the trap handler.  If this is a user mode trap,
      // copy them from user space.
      if (isr & DLX_STATUS_SYSMODE) {
	args[0] = trapArgs[0];
	args[1] = trapArgs[1];
      } else {
	char	filename[32];
	// trapArgs points to the trap arguments in user space.  There are
	// two of them, so copy them to to system space.  The first argument
	// is a string, so it has to be copied to system space and the
	// argument replaced with a pointer to the string in system space.
	MemoryCopyUserToSystem (currentPCB, (char *)trapArgs, (char *)args, sizeof(args[0])*2);
	MemoryCopyUserToSystem (currentPCB, (char *)(args[0]), (char *)filename, 31);
	// Null-terminate the string in case it's longer than 31 characters.
	filename[31] = '\0';
	// Set the argument to be the filename
	args[0] = (uint32)filename;
      }
      // Allow Open() calls to be interruptible!
      intrs = EnableIntrs ();
      ProcessSetResult (currentPCB, args[1] + 0x10000);
      printf ("Got an open with parameters ('%s',0x%x)\n", (char *)(args[0]), args[1]);
      RestoreIntrs (intrs);
      break;
    case TRAP_CLOSE:
      // Allow Close() calls to be interruptible!
      intrs = EnableIntrs ();
      ProcessSetResult (currentPCB, -1);
      RestoreIntrs (intrs);
      break;
    case TRAP_READ:
      // Allow Read() calls to be interruptible!
      intrs = EnableIntrs ();
      ProcessSetResult (currentPCB, -1);
      RestoreIntrs (intrs);
      break;
    case TRAP_WRITE:
      // Allow Write() calls to be interruptible!
      intrs = EnableIntrs ();
      ProcessSetResult (currentPCB, -1);
      RestoreIntrs (intrs);
      break;
    case TRAP_DELETE:
      intrs = EnableIntrs ();
      ProcessSetResult (currentPCB, -1);
      RestoreIntrs (intrs);
      break;
    case TRAP_SEEK:
      intrs = EnableIntrs ();
      ProcessSetResult (currentPCB, -1);
      RestoreIntrs (intrs);
      break;
    case TRAP_PROCESS_GETPID:
      ProcessSetResult(currentPCB, GetCurrentPid()); 
      break;
    case TRAP_PROCESS_CREATE:
      TrapProcessCreateHandler(trapArgs, isr & DLX_STATUS_SYSMODE);
      break;
    case TRAP_SEM_CREATE:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      ihandle = SemCreate(ihandle);
      ProcessSetResult(currentPCB, ihandle); //Return handle
      break;
    case TRAP_SEM_WAIT:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      handle = SemHandleWait(ihandle);
      ProcessSetResult(currentPCB, handle); //Return 1 or 0
      break;
    case TRAP_SEM_SIGNAL:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      handle = SemHandleSignal(ihandle);
      ProcessSetResult(currentPCB, handle); //Return 1 or 0
      break;
    case TRAP_MALLOC:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      ihandle = (int)malloc(currentPCB, ihandle);
      ProcessSetResult(currentPCB, ihandle); //Return handle
      break;
    case TRAP_MFREE:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      ihandle = mfree(currentPCB, (void*)ihandle);
      ProcessSetResult(currentPCB, ihandle); //Return handle
      break;
    case TRAP_LOCK_CREATE:
      ihandle = LockCreate();
      ProcessSetResult(currentPCB, ihandle); //Return handle
      break;
    case TRAP_LOCK_ACQUIRE:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      handle = LockHandleAcquire(ihandle);
      ProcessSetResult(currentPCB, handle); //Return 1 or 0
      break;
    case TRAP_LOCK_RELEASE:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      handle = LockHandleRelease(ihandle);
      ProcessSetResult(currentPCB, handle); //Return 1 or 0
      break;
    case TRAP_COND_CREATE:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      ihandle = CondCreate(ihandle);
      ProcessSetResult(currentPCB, ihandle); //Return handle
      break;
    case TRAP_COND_WAIT:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      ihandle = CondHandleWait(ihandle);
      ProcessSetResult(currentPCB, ihandle); //Return 1 or 0
      break;
    case TRAP_COND_SIGNAL:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      ihandle = CondHandleSignal(ihandle);
      ProcessSetResult(currentPCB, ihandle); //Return 1 or 0
      break;
    case TRAP_COND_BROADCAST:
      ihandle = GetIntFromTrapArg(trapArgs, isr & DLX_STATUS_SYSMODE);
      ihandle = CondHandleBroadcast(ihandle);
      ProcessSetResult(currentPCB, ihandle); //Return 1 or 0
      break;
    default:
      printf ("Got an unrecognized trap (0x%x) - exiting!\n",
	      cause);
      exitsim ();
      break;
    }
  } else {
    switch (cause) {
    case TRAP_TIMER:
      dbprintf ('t', "Got a timer interrupt!\n");
      // ClkInterrupt returns 1 when 1 "process quantum" has passed, meaning
      // that it's time to call ProcessSchedule again.
      if (ClkInterrupt()) {
        ProcessSchedule ();
      }
      break;
    case TRAP_KBD:
      do {
	i = *((uint32 *)DLX_KBD_NCHARSIN);
	result = *((uint32 *)DLX_KBD_GETCHAR);
	printf ("Got a keyboard interrupt (char=0x%x(%c), nleft=%d)!\n",
		result, result, i);
      } while (i > 1);
      break;
    case TRAP_ACCESS:
      printf ("Exiting after illegal access at iar=0x%x, isr=0x%x\n", iar, isr);
      exitsim ();
      break;
    case TRAP_ADDRESS:
      printf ("Exiting after illegal address at iar=0x%x, isr=0x%x\n",
	      iar, isr);
      exitsim ();
      break;
    case TRAP_ILLEGALINST:
      printf ("Exiting after illegal instruction at iar=0x%x, isr=0x%x\n",
	      iar, isr);
      exitsim ();
      break;
    case TRAP_PAGEFAULT:
      MemoryPageFaultHandler(currentPCB);
      break;
    default:
      printf ("Got an unrecognized system interrupt (0x%x) - exiting!\n",
	      cause);
      exitsim ();
      break;
    }
  }
  dbprintf ('t',"About to return from dointerrupt.\n");
  // Note that this return may schedule a new process!
  intrreturn ();
}