Exemplo n.º 1
0
//-------------------------------------------------------
//
// int MboxSend(mbox_t handle,int length, void* message);
//
// Send a message (pointed to by "message") of length
// "length" bytes to the specified mailbox.  Messages of
// length 0 are allowed.  The call 
// blocks when there is not enough space in the mailbox.
// Messages cannot be longer than MBOX_MAX_MESSAGE_LENGTH.
// Note that the calling process must have opened the 
// mailbox via MboxOpen.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxSend(mbox_t handle, int length, void* message) {


//	if(mbox_list[handle].msg_count >= MBOX_MAX_BUFFERS_PER_MBOX) {
		SemHandleWait(mbox_list[handle].empty);
//	}
	LockHandleAcquire(mbox_list[handle].lock);

	bcopy(message,mbox_list[handle].msgs[mbox_list[handle].head].message,length);

	mbox_list[handle].msgs[mbox_list[handle].head].length = length;
	mbox_list[handle].head = (mbox_list[handle].head + 1) % MBOX_MAX_BUFFERS_PER_MBOX;
	mbox_list[handle].msg_count++;

	//	printf("MBOX INFO: handle: %d\n head: %d\n tail: %d\n in_use: %d\n msg_count: %d\n ",mbox_list[handle].handle,
	//			mbox_list[handle].head,mbox_list[handle].tail,mbox_list[handle].in_use,mbox_list[handle].msg_count);
	//	printf("user_list: ");
	//	for(i = 0; i < MBOX_NUM_BUFFERS; i++) {
	//		printf("%d",mbox_list[handle].users[i]);
	//	}
	//	printf("\n\n msg info: \n");
	//	for(i = 0; i < MBOX_MAX_MESSAGE_LENGTH; i++) {
	//		printf("ID: %d, msg: %s, length: %d\n",mbox_list[handle].msgs[i].id,
	//		                                         mbox_list[handle].msgs[i].message,
	//		                                         mbox_list[handle].msgs[i].length);
	//	}
	SemHandleSignal(mbox_list[handle].full);
	LockHandleRelease(mbox_list[handle].lock);
	return MBOX_SUCCESS;

	return MBOX_FAIL;
}
Exemplo n.º 2
0
//-------------------------------------------------------
//
// int MboxSend(mbox_t handle,int length, void* message);
//
// Send a message (pointed to by "message") of length
// "length" bytes to the specified mailbox.  Messages of
// length 0 are allowed.  The call 
// blocks when there is not enough space in the mailbox.
// Messages cannot be longer than MBOX_MAX_MESSAGE_LENGTH.
// Note that the calling process must have opened the 
// mailbox via MboxOpen.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxSend(mbox_t handle, int length, void* message) {
	int ibuff;
	int i;
	int cpid = GetCurrentPid();
	char* cmessage = (char*) message;
	mbox* xbox = &mboxes[handle];
	if(xbox->opened_pids[cpid] == false) {
		return MBOX_FAIL;
	}
	if(length > MBOX_MAX_MESSAGE_LENGTH) {
		return MBOX_FAIL;
	}
	// printf("***%d Waiting on mbox empty slot\n", cpid);
	SemHandleWait(xbox->s_mbox_emptyslots);
	// printf("******%d Done waiting on mbox empty slot\n", cpid);
	while(true) {
		// SemHandleWait(s_buff_emptyslots);
		while(LockHandleAcquire(l_buff) != SYNC_SUCCESS);
		for(ibuff = 0; ibuff < MBOX_NUM_BUFFERS; ibuff++) {
			if(mbox_buffers[ibuff].inuse == false) {
				break;
			}
		}
		if(ibuff != MBOX_NUM_BUFFERS) {
			// buffers are not full
			mbox_buffers[ibuff].inuse = true;
			LockHandleRelease(l_buff);
			break;
		}
		LockHandleRelease(l_buff);
	}
	// printf("=%d is waiting on mbox lock\n", cpid);
	while(LockHandleAcquire(xbox->l_mbox) != SYNC_SUCCESS);
	// printf("==%d has acquired mbox lock\n", cpid);
	xbox->cbobi[xbox->tail_cbobi] = ibuff;
	xbox->tail_cbobi = (xbox->tail_cbobi + 1) % MBOX_MAX_BUFFERS_PER_MBOX;
	for(i = 0; i < length; i++) {
		mbox_buffers[ibuff].msg[i] = cmessage[i];
	}
	mbox_buffers[ibuff].length = length;
	mbox_buffers[ibuff].inuse = true;
	SemHandleSignal(xbox->s_mbox_fillslots);
	LockHandleRelease(xbox->l_mbox);
	// printf("===%d has released mbox lock\n", cpid);

	return MBOX_SUCCESS;
}
Exemplo n.º 3
0
//-------------------------------------------------------
//
// int MboxRecv(mbox_t handle, int maxlength, void* message);
//
// Receive a message from the specified mailbox.  The call 
// blocks when there is no message in the buffer.  Maxlength
// should indicate the maximum number of bytes that can be
// copied from the buffer into the address of "message".  
// An error occurs if the message is larger than maxlength.
// Note that the calling process must have opened the mailbox 
// via MboxOpen.
//   
// Returns MBOX_FAIL on failure.
// Returns number of bytes written into message on success.
//
//-------------------------------------------------------
int MboxRecv(mbox_t handle, int maxlength, void* message) {
	int ibuff;
	int cpid = GetCurrentPid();
	int i;
	mbox* xbox = &mboxes[handle];
	char* cmessage = (char*) message;

	if(xbox->opened_pids[cpid] == false) {
		return MBOX_FAIL;
	}
	// printf("***%d Waiting on mbox filled slot\n", cpid);
	SemHandleWait(xbox->s_mbox_fillslots);
	// printf("******%d Done waiting on mbox filled slot\n", cpid);
	// printf("=%d is waiting on mbox lock\n", cpid);
	while(LockHandleAcquire(xbox->l_mbox) != SYNC_SUCCESS);
	// printf("==%d has acquired mbox lock\n", cpid);
	ibuff = xbox->cbobi[xbox->head_cbobi];
	if(ibuff < 0) {
		printf("Invalid message buffer index from cbobi.head: %d\n", xbox->head_cbobi);
		exitsim();
	}
	if(mbox_buffers[ibuff].inuse == false) {
		LockHandleRelease(xbox->l_mbox);
		return MBOX_FAIL;
	}
	if(mbox_buffers[ibuff].length > maxlength) {
		LockHandleRelease(xbox->l_mbox);
		return MBOX_FAIL;
	}

	for(i = 0; i < mbox_buffers[ibuff].length; i++) {
		cmessage[i] = mbox_buffers[ibuff].msg[i];
	}
	xbox->cbobi[xbox->head_cbobi] = -1; // invalidate the cbobi
	mbox_buffers[ibuff].inuse = false;
	xbox->head_cbobi = (xbox->head_cbobi + 1) % MBOX_MAX_BUFFERS_PER_MBOX;
	// SemHandleSignal(s_buff_emptyslots);
	SemHandleSignal(xbox->s_mbox_emptyslots);
	LockHandleRelease(xbox->l_mbox);
	// printf("===%d has released mbox lock\n", cpid);

	return mbox_buffers[ibuff].length;
}
Exemplo n.º 4
0
//-------------------------------------------------------
//
// int MboxRecv(mbox_t handle, int maxlength, void* message);
//
// Receive a message from the specified mailbox.  The call 
// blocks when there is no message in the buffer.  Maxlength
// should indicate the maximum number of bytes that can be
// copied from the buffer into the address of "message".  
// An error occurs if the message is larger than maxlength.
// Note that the calling process must have opened the mailbox 
// via MboxOpen.
//   
// Returns MBOX_FAIL on failure.
// Returns number of bytes written into message on success.
//
//-------------------------------------------------------
int MboxRecv(mbox_t handle, int maxlength, void* message) {
	int size;

//	if(mbox_list[handle].msg_count == 0) {
		SemHandleWait(mbox_list[handle].full);
//	}
	LockHandleAcquire(mbox_list[handle].lock);

	if (mbox_list[handle].msgs[mbox_list[handle].tail].length <= maxlength) {
		size = mbox_list[handle].msgs[mbox_list[handle].tail].length;
	}
	else {
		return MBOX_FAIL;
	}
	bcopy(mbox_list[handle].msgs[mbox_list[handle].tail].message,message, size);

	mbox_list[handle].tail = (mbox_list[handle].tail + 1) % MBOX_MAX_BUFFERS_PER_MBOX;
	mbox_list[handle].msg_count--;

	SemHandleSignal(mbox_list[handle].empty);
	LockHandleRelease(mbox_list[handle].lock);
	return size;
}
Exemplo n.º 5
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 ();
}
Exemplo n.º 6
0
//-------------------------------------------------------
//
// int MboxRecv(mbox_t handle, int maxlength, void* message);
//
// Receive a message from the specified mailbox.  The call 
// blocks when there is no message in the buffer.  Maxlength
// should indicate the maximum number of bytes that can be
// copied from the buffer into the address of "message".  
// An error occurs if the message is larger than maxlength.
// Note that the calling process must have opened the mailbox 
// via MboxOpen.
//   
// Returns MBOX_FAIL on failure.
// Returns number of bytes written into message on success.
//
//-------------------------------------------------------
int MboxRecv(mbox_t handle, int maxlength, void* message) {
    int i;
    int qlen;
    Link *l;
    int exists = 0;
    mbox_message *m;
    
    //check if mailbox is real
    if(!&mboxs[handle]) return MBOX_FAIL;

    //check if pid opened this mailbox
    if(!AQueueEmpty(&mboxs[handle].pids ) ){
       
        qlen = AQueueLength(&mboxs[handle].pids); 
        
        l = AQueueFirst(&mboxs[handle].pids);

        for(i=0; i < qlen; i++){
            if((int)AQueueObject(l) == GetCurrentPid()){
                exists = 1; 
                break;
            }

            l = AQueueNext(l);
        }
       
       //actualy checks if pid exists 
        if(exists == 0){
            return MBOX_FAIL;
        }

        //wait until queue has something in it
        if(SemHandleWait(mboxs[handle].s_msg_full) == SYNC_FAIL){
            printf("bad sem handle wait in mbox recv\n");
            exitsim();
        }

        //lock
        if(LockHandleAcquire(mboxs[handle].l) != SYNC_SUCCESS){
            printf("FATAL ERROR: could not get lock in Mbox send!\n");
            exitsim();
        }

        l = AQueueFirst(&mboxs[handle].messages);

        m = (mbox_message *) l->object;

        //check if message longer than max length
        if(m->length > maxlength) {
            return MBOX_FAIL;
        }
 
        //copy message to local variable
        dstrncpy(message,(void*) m->message, m->length);

        //reset structure for use elsewhere
        m->inuse =0;

        //delete link
        AQueueRemove(&l);

        //unlock
        if(LockHandleRelease(mboxs[handle].l) != SYNC_SUCCESS){
            printf("FATAL ERROR: could not release lock in Mbox send!\n");
            exitsim();
        }

        if(SemHandleSignal(mboxs[handle].s_msg_empty) == SYNC_FAIL){
            printf("bad sem handle signal in mbox recv\n");
            exitsim();
        }

    }else{
        return MBOX_FAIL;
    }

    return MBOX_SUCCESS;


}
Exemplo n.º 7
0
//-------------------------------------------------------
//
// int MboxSend(mbox_t handle,int length, void* message);
//
// Send a message (pointed to by "message") of length
// "length" bytes to the specified mailbox.  Messages of
// length 0 are allowed.  The call 
// blocks when there is not enough space in the mailbox.
// Messages cannot be longer than MBOX_MAX_MESSAGE_LENGTH.
// Note that the calling process must have opened the 
// mailbox via MboxOpen.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxSend(mbox_t handle, int length, void* message) {
    int i;
    int qlen;
    Link *l;
    int exists = 0;
    
    //check if mailbox is real
    if(!&mboxs[handle]) return MBOX_FAIL;

    //check if pid opened this mailbox
    if(!AQueueEmpty(&mboxs[handle].pids ) ){
       
        qlen = AQueueLength(&mboxs[handle].pids); 
        
        l = AQueueFirst(&mboxs[handle].pids);

        for(i=0; i < qlen; i++){
            if((int)AQueueObject(l) == GetCurrentPid()){
                exists = 1; 
                break;
            }

            l = AQueueNext(l);
        }
       
       //actuall checks if pid exists 
        if(exists == 0){
            return MBOX_FAIL;
        }

        //check if message longer than max length
        if(length > MBOX_MAX_MESSAGE_LENGTH) {
            return MBOX_FAIL;
        }
        
        //check for space in mailbox 

        if((SemHandleWait(mboxs[handle].s_msg_empty)) == SYNC_FAIL ){
            printf("bad sem handle wait in mbox send\n");
            exitsim();
        }

        //lock
        if(LockHandleAcquire(mboxs[handle].l) != SYNC_SUCCESS){
            printf("FATAL ERROR: could not get lock in Mbox send!\n");
            exitsim();
        }

        for(i=0; i<MBOX_NUM_BUFFERS; i++){
            if(mbox_messages[i].inuse == 0){
                mbox_messages[i].inuse = 1;
                break;
            }
        }


        //creating mbox_message structure
        dstrncpy(mbox_messages[i].message, (char *) message, length);
        mbox_messages[i].length = length;

        if ((l = AQueueAllocLink(&mbox_messages[i])) == NULL) {
            printf("FATAL ERROR: could not allocate link for pid queue in Mbox Open!\n");
            exitsim();
        }

        //add message to end of queue
        AQueueInsertLast(&mboxs[handle].messages, l);

        //unlock
        if(LockHandleRelease(mboxs[handle].l) != SYNC_SUCCESS){
            printf("FATAL ERROR: could not release lock in Mbox send!\n");
            exitsim();
        }

        if(SemHandleSignal(mboxs[handle].s_msg_full) == SYNC_FAIL){
            printf("bad sem handle signal in mbox send\n");
            exitsim();
        }
    

    }else{
        return MBOX_FAIL;
    }

    return MBOX_SUCCESS;

}