コード例 #1
0
//----------------------------------------------------------------------
//
//	SemWait
//
//	Wait on a semaphore.  As described in Section 6.4 of _OSC_,
//	we decrement the counter and suspend the process if the
//	semaphore's value is less than 0.  To ensure atomicity,
//	interrupts are disabled for the entire operation, but must be
//      turned on before going to sleep.
//
//----------------------------------------------------------------------
int SemWait (Sem *sem) {
  Link	*l;
  int		intrval;
    
  if (!sem) return SYNC_FAIL;

  intrval = DisableIntrs ();
  dbprintf ('I', "SemWait: Old interrupt value was 0x%x.\n", intrval);
  dbprintf ('s', "SemWait: Proc %d waiting on sem %d, count=%d.\n", GetCurrentPid(), (int)(sem-sems), sem->count);
  if (sem->count <= 0) {
    dbprintf('s', "SemWait: putting process %d to sleep\n", GetCurrentPid());
    if ((l = AQueueAllocLink ((void *)currentPCB)) == NULL) {
      printf("FATAL ERROR: could not allocate link for semaphore queue in SemWait!\n");
      exitsim();
    }
    if (AQueueInsertLast (&sem->waiting, l) != QUEUE_SUCCESS) {
      printf("FATAL ERROR: could not insert new link into semaphore waiting queue in SemWait!\n");
      exitsim();
    }
    ProcessSleep();
    // Don't decrement couter here because that's handled in SemSignal for us
  } else {
    sem->count--; // Decrement internal counter
    dbprintf('s', "SemWait: Proc %d granted permission to continue by sem %d\n", GetCurrentPid(), (int)(sem-sems));
  }
  RestoreIntrs (intrval);
  return SYNC_SUCCESS;
}
コード例 #2
0
//---------------------------------------------------------------------------
//	CondHandleSignal
//
//	This call wakes up exactly one process waiting on the condition
//	variable, if at least one is waiting. If there are no processes
//	waiting on the condition variable, it does nothing. In either case,
//	the calling process must have acquired the lock associated with
//	condition variable for this call to succeed, in which case it returns
//	0. If the calling process does not own the lock, it returns 1,
//	indicating that the call was not successful. This function should be
//	written in such a way that the calling process should retain the
//	acquired lock even after the call completion (in other words, it
//	should not release the lock it has already acquired before the call).
//
//	Note that the process woken up by this call tries to acquire the lock
//	associated with the condition variable as soon as it wakes up. Thus,
//	for such a process to run, the process invoking CondHandleSignal
//	must explicitly release the lock after the call is complete.
//---------------------------------------------------------------------------
int CondSignal(Cond *c) {
  Link *l;
  int intrs;
  PCB *pcb;

  if (!c) return SYNC_FAIL;

  intrs = DisableIntrs ();
  dbprintf ('s', "CondSignal: Proc %d signalling cond %d.\n", GetCurrentPid(), (int)(c-conds));

  if (c->lock->pid != GetCurrentPid()) {
    dbprintf('s', "CondSignal: Proc %d does not own cond %d.\n", GetCurrentPid(), (int)(c-conds));
    return SYNC_FAIL;
  }
  if (!AQueueEmpty(&c->waiting)) { // there is a process to wake up
    l = AQueueFirst(&c->waiting);
    pcb = (PCB *)AQueueObject(l);
    if (AQueueRemove(&l) != QUEUE_SUCCESS) { 
      printf("FATAL ERROR: could not remove link from cond queue in CondSignal!\n");
      exitsim();
    }
    dbprintf ('s', "CondSignal: Waking up PID %d, it still needs to acquire lock.\n", GetPidFromAddress(pcb));
    ProcessWakeup (pcb);
  } else {
    dbprintf('s', "CondSignal: Proc %d signalled, but no processes were waiting.\n", GetCurrentPid());
  }
  RestoreIntrs (intrs);
  return SYNC_SUCCESS;
}
コード例 #3
0
//---------------------------------------------------------------------------
//	LockHandleRelease
//
//	This procedure releases the unique lock described by the handle. It
//	first checks whether the lock is a valid lock. If not, it returns SYNC_FAIL.
//	If the lock is a valid lock, it should check whether the calling
//	process actually holds the lock. If not it returns SYNC_FAIL. Otherwise it
//	releases the lock, and returns SYNC_SUCCESS.
//---------------------------------------------------------------------------
int LockRelease(Lock *k) {
  Link *l;
  int	intrs;
  PCB *pcb;

  if (!k) return SYNC_FAIL;

  intrs = DisableIntrs ();
  dbprintf ('s', "LockRelease: Proc %d releasing lock %d.\n", GetCurrentPid(), (int)(k-locks));

  if (k->pid != GetCurrentPid()) {
    dbprintf('s', "LockRelease: Proc %d does not own lock %d.\n", GetCurrentPid(), (int)(k-locks));
    return SYNC_FAIL;
  }
  k->pid = -1;
  if (!AQueueEmpty(&k->waiting)) { // there is a process to wake up
    l = AQueueFirst(&k->waiting);
    pcb = (PCB *)AQueueObject(l);
    if (AQueueRemove(&l) != QUEUE_SUCCESS) { 
      printf("FATAL ERROR: could not remove link from lock queue in LockRelease!\n");
      exitsim();
    }
    dbprintf ('s', "LockRelease: Waking up PID %d, assigning lock.\n", (int)(GetPidFromAddress(pcb)));
    k->pid = GetPidFromAddress(pcb);
    ProcessWakeup (pcb);
  }
  RestoreIntrs (intrs);
  return SYNC_SUCCESS;
}
コード例 #4
0
//---------------------------------------------------------------------------
//	CondHandleWait
//
//	This function makes the calling process block on the condition variable
//	till either ConditionHandleSignal or ConditionHandleBroadcast is
//	received. The process calling CondHandleWait must have acquired the
//	lock associated with the condition variable (the lock that was passed
//	to CondCreate. This implies the lock handle needs to be stored
//	somewhere. hint! hint!) for this function to
//	succeed. If the calling process has not acquired the lock, it does not
//	block on the condition variable, but a value of 1 is returned
//	indicating that the call was not successful. Return value of 0 implies
//	that the call was successful.
//
//	This function should be written in such a way that the calling process
//	should release the lock associated with this condition variable before
//	going to sleep, so that the process that intends to signal this
//	process could acquire the lock for that purpose. After waking up, the
//	blocked process should acquire (i.e. wait on) the lock associated with
//	the condition variable. In other words, this process does not
//	"actually" wake up until the process calling CondHandleSignal or
//	CondHandleBroadcast releases the lock explicitly.
//---------------------------------------------------------------------------
int CondWait(Cond *c) {
  Link	*l;
  int   intrval;
    
  if (!c) return SYNC_FAIL;

  // Conds are atomic
  intrval = DisableIntrs ();
  dbprintf ('I', "CondWait: Old interrupt value was 0x%x.\n", intrval);

  // Check to see if the current process owns the lock
  if (c->lock->pid != GetCurrentPid()) {
    dbprintf('s', "CondWait: Proc %d does not own cond %d\n", GetCurrentPid(), (int)(c-conds));
    RestoreIntrs(intrval);
    return SYNC_FAIL;
  }

  dbprintf ('s', "CondWait: Proc %d waiting on cond %d.  Putting to sleep.\n", GetCurrentPid(), (int)(c-conds));
  if ((l = AQueueAllocLink ((void *)currentPCB)) == NULL) {
    printf("FATAL ERROR: could not allocate link for cond queue in CondWait!\n");
    exitsim();
  }
  if (AQueueInsertLast (&c->waiting, l) != QUEUE_SUCCESS) {
    printf("FATAL ERROR: could not insert new link into cond waiting queue in CondWait!\n");
    exitsim();
  }
  // Release the lock before going to sleep
  LockRelease(c->lock);
  RestoreIntrs(intrval); // Don't want interrupts disabled while we sleep
  ProcessSleep();
  // Immediately acquire the lock upon waking
  LockAcquire(c->lock);
  return SYNC_SUCCESS;
}
コード例 #5
0
ファイル: mailbox.c プロジェクト: Nelson0409/DLX-OS
//-------------------------------------------------------
// 
// void MboxOpen(mbox_t);
//
// Open the mailbox for use by the current process.  Note
// that it is assumed that the internal lock/mutex handle 
// of the mailbox and the inuse flag will not be changed 
// during execution.  This allows us to get the a valid 
// lock handle without a need for synchronization.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxOpen(mbox_t handle) {
	int i;

	for(i = 0; i < MBOX_NUM_BUFFERS; i++) {
		if(GetCurrentPid() == mbox_list[handle].users[i]) {
			printf("Process has already opened this mailbox\n");
			return MBOX_FAIL;
		}
	}
//	PrintUsersByHandle(handle);
	if (handle >= 0 && handle < MBOX_NUM_MBOXES) {  //modified (MBOX_NUM_BOXES)
//		printf("handle = %d, in_use = %d, message count = %d\n",handle, mbox_list[handle].in_use, mbox_list[handle].msg_count);
		if (mbox_list[handle].in_use >= 0 //&&
//				mbox_list[handle].msg_count < MBOX_MAX_BUFFERS_PER_MBOX
				) {
//			printf("second if\n");
			for (i = 0; i < MBOX_NUM_BUFFERS; i++) {
				if (mbox_list[handle].users[i] == -1) {
//					printf("free users space");
					mbox_list[handle].users[i] = GetCurrentPid();
					mbox_list[handle].in_use++;
					return MBOX_SUCCESS;
				}
			}

		}
	}
	return MBOX_FAIL;
}
コード例 #6
0
ファイル: files.c プロジェクト: yfeleke/ece469g05
int FileClose(int handle)
{
	if(handle > (FILE_MAX_OPEN_FILES-1))
	{
		printf("FileClose -- FD handle number greater than %d!\n", FILE_MAX_OPEN_FILES-1);
		return(FILE_FAIL);
	}

	if(fd_array[handle].FD_Valid == 0)
	{
		printf("FileClose -- FD handle not valid!\n");
		return(FILE_FAIL);
	}

	if(fd_array[handle].FD_PID != GetCurrentPid())
	{
		printf("FileClose -- FD handle does not belong to current process #%d,\n", GetCurrentPid());
		return(FILE_FAIL);
	}

	// Close the file descriptor handle (mark as not valid)
	fd_array[handle].FD_Valid = 0;
	dbprintf('F', "FileClose -- Successfully closed file descriptor #%d,\n", handle);

	return(FILE_SUCCESS);

}
コード例 #7
0
//-------------------------------------------------------
//
// mbox_t MboxCreate();
//
// Allocate an available mailbox structure for use. 
//
// Returns the mailbox handle on success
// Returns MBOX_FAIL on error.
//
//-------------------------------------------------------
mbox_t MboxCreate() {

	mbox_t mbox_no = MBOX_NUM_MBOXES;
	for(i = 0; i < MBOX_NUM_MBOXES;i++)
	{
		if(MailBox[i].inuse == false)
		{
			mbox_no = i;
			break;
		}
	}

	if(mbox_no == MBOX_NUM_MBOXES)
	{
		printf("MailBox cannot be assigned to the calling process : %d\n", GetCurrentPid());
		return MBOX_FAIL;
	}

	MailBox[mbox_no].inuse = true;

	if((MailBox[mbox_no].lock = LockCreate()) == SYNC_FAIL)
	{
		printf("MailBox cannot associate a lock with itself for calling process : %d\n", GetCurrentPid());
		return MBOX_FAIL;
	}

	if((MailBox[mbox_no].moreData = CondCreate(MailBox[mbox_no].lock)) == SYNC_FAIL)
	{
		printf("MailBox cannot associate a cond var for buffer emptiness calling process : %d\n", GetCurrentPid());
		return MBOX_FAIL;
	}

	if((MailBox[mbox_no].moreSpace = CondCreate(MailBox[mbox_no].lock)) == SYNC_FAIL)
	{
		printf("MailBox cannot associate a cond var for buffer saturation for calling process : %d\n", GetCurrentPid());
		return MBOX_FAIL;
	}

	if(AQueueInit(&MailBox[mbox_no].buffers) == QUEUE_FAIL)
	{
		printf("FATAL Error : Available mailbox : %d cannot have its buffer queue initialized for process : %d\n", mbox_no, GetCurrentPid());
		return MBOX_FAIL;
		//exitsim();
	}

	for(i = 0; i < PROCESS_MAX_PROCS; i++)
	{
		MailBox[mbox_no].procs_link[i] = 0;
	}

	//MailBox[mbox_no].tail = 0; 
	//MailBox[mbox_no].head = 1;
	MailBox[mbox_no].process_count = 0;


	//printf("Created mailbox with handle : %d\n", mbox_no);
	return mbox_no;
}
コード例 #8
0
ファイル: files.c プロジェクト: yfeleke/ece469g05
int FileWrite(int handle, void *mem, int num_bytes)
{
	int bytes_written;

	if(handle > (FILE_MAX_OPEN_FILES-1))
	{
		printf("FileWrite -- FD handle number greater than %d!\n", FILE_MAX_OPEN_FILES-1);
		return(FILE_FAIL);
	}

	if(fd_array[handle].FD_Valid == 0)
	{
		printf("FileWrite -- FD handle not valid!\n");
		return(FILE_FAIL);
	}

	if(fd_array[handle].FD_PID != GetCurrentPid())
	{
		printf("FileWrite -- FD handle does not belong to current process #%d,\n", GetCurrentPid());
		return(FILE_FAIL);
	}

	if(fd_array[handle].FD_Mode == FILE_READ)
	{
		printf("FileWrite -- FD handle does not have write privileges\n");
		return(FILE_FAIL);
	}

	if(num_bytes < 0)
	{
		printf("FileWrite -- num_bytes is less than zero!\n");
		return(FILE_FAIL);
	}

	if( (fd_array[handle].FD_CurrentPosition+num_bytes) > (10*sb.FS_BlockSize+(sb.FS_BlockSize*sb.FS_BlockSize/4)) )
	{
		printf("FileWrite -- File is too big!\n");
		return(FILE_FAIL);
	}

	bytes_written = DfsInodeWriteBytes(fd_array[handle].FD_InodeHandle, mem, fd_array[handle].FD_CurrentPosition, num_bytes);

	if(bytes_written == -1)
	{
		printf("FileWrite -- Write to file failed!\n");
		return(FILE_FAIL);
	}

	fd_array[handle].FD_CurrentPosition += bytes_written;

	dbprintf('F', "FileWrite -- write of %d bytes successful\n", bytes_written);
	dbprintf('F',"FileWrite -- New position for File Descriptor #%d ", handle);
	dbprintf('F',"is %d\n", fd_array[handle].FD_CurrentPosition);

	return(bytes_written);
}
コード例 #9
0
ファイル: files.c プロジェクト: yfeleke/ece469g05
int FileSeek(int handle, int num_bytes, int from_where)
{
	int filesize;
	int new_position;

	if(handle > (FILE_MAX_OPEN_FILES-1))
	{
		printf("FileSeek -- FD handle number greater than %d!\n", FILE_MAX_OPEN_FILES-1);
		return(FILE_FAIL);
	}

	if(fd_array[handle].FD_Valid == 0)
	{
		printf("FileSeek -- FD handle not valid!\n");
		return(FILE_FAIL);
	}

	if(fd_array[handle].FD_PID != GetCurrentPid())
	{
		printf("FileSeek -- FD handle does not belong to current process #%d,\n", GetCurrentPid());
		return(FILE_FAIL);
	}

	filesize = DfsInodeFilesize(fd_array[handle].FD_InodeHandle);
	if(filesize == -1)
	{
		printf("FileSeek -- Could not get filesize\n");
		return(FILE_FAIL);
	}

	dbprintf('F',"FileSeek -- Filesize for File Descriptor #%d ", handle);
	dbprintf('F',"is %d\n", filesize);

	if(from_where == FILE_SEEK_SET)
		new_position = num_bytes;
	else if(from_where == FILE_SEEK_END)
		new_position = filesize + num_bytes;
	else if(from_where == FILE_SEEK_CUR)
		new_position = fd_array[handle].FD_CurrentPosition + num_bytes;
	else
	{
		printf("FileSeek -- Invalid from_where value!\n");
		return(FILE_FAIL);
	}

	if(new_position < 0)
		new_position = 0;

	fd_array[handle].FD_CurrentPosition = new_position;
	fd_array[handle].FD_EOF_Flag = 0;

	dbprintf('F',"FileSeek -- New position for File Descriptor #%d ", handle);
	dbprintf('F',"is %d\n", fd_array[handle].FD_CurrentPosition);
	return(FILE_SUCCESS);
}
コード例 #10
0
//----------------------------------------------------------------------
//
//	SemSignal
//
//	Signal on a semaphore.  Again, details are in Section 6.4 of
//	_OSC_.
//
//----------------------------------------------------------------------
int SemSignal (Sem *sem) {
  Link *l;
  int	intrs;
  PCB *pcb;

  if (!sem) return SYNC_FAIL;

  intrs = DisableIntrs ();
  dbprintf ('s', "SemSignal: Process %d Signalling on sem %d, count=%d.\n", GetCurrentPid(), (int)(sem-sems), sem->count);
  // Increment internal counter before checking value
  sem->count++;
  if (sem->count > 0) { // check if there is a process to wake up
    if (!AQueueEmpty(&sem->waiting)) { // there is a process to wake up
      l = AQueueFirst(&sem->waiting);
      pcb = (PCB *)AQueueObject(l);
      if (AQueueRemove(&l) != QUEUE_SUCCESS) { 
        printf("FATAL ERROR: could not remove link from semaphore queue in SemSignal!\n");
        exitsim();
      }
      dbprintf ('s', "SemSignal: Waking up PID %d.\n", (int)(GetPidFromAddress(pcb)));
      ProcessWakeup (pcb);
      // Decrement counter on behalf of woken up PCB
      sem->count--;
    }
  }
  RestoreIntrs (intrs);
  return SYNC_SUCCESS;
}
コード例 #11
0
ファイル: mbox.c プロジェクト: sransara/rocket-science
//-------------------------------------------------------
//
// int MboxClose(mbox_t);
//
// Close the mailbox for use to the current process.
// If the number of processes using the given mailbox
// is zero, then disable the mailbox structure and
// return it to the set of available mboxes.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxClose(mbox_t handle) {
	int cpid = GetCurrentPid();
	uint32 intrval;
	int j;
	mbox* xbox = &mboxes[handle];
	if(xbox->opened_pids[cpid] == false) {
		return MBOX_FAIL;
	}
	xbox->opened_pids[cpid] = false;
	intrval = DisableIntrs();
	xbox->opened_pids_count -= 1;
	if(xbox->opened_pids_count == 0) {
		// reset the mbox	
		for(j = xbox->head_cbobi; j <= xbox->tail_cbobi; (j = (j+1) % MBOX_MAX_BUFFERS_PER_MBOX)) {
			mbox_buffers[xbox->cbobi[j]].inuse = false;
			xbox->cbobi[j] = -1;
		}
		//sems[xbox->s_mbox_emptyslots].inuse = false;
		//sems[xbox->s_mbox_fillslots].inuse = false;
		//locks[xbox->l_mbox].inuse = false;
		xbox->head_cbobi = 0;
		xbox->tail_cbobi = 0;
		xbox->inuse = false;
	}
	RestoreIntrs(intrval);
	return MBOX_SUCCESS;
}
コード例 #12
0
TProcessHandle CProcess::GetCurrentHandle(void)
{
#if   defined(NCBI_OS_MSWIN)
    return GetCurrentProcess();
#elif defined(NCBI_OS_UNIX)
    return GetCurrentPid();
#endif
}
コード例 #13
0
ファイル: process.c プロジェクト: sransara/rocket-science
//----------------------------------------------------------------------
//
//	ProcessDestroy
//
//	Destroy a process by setting its status to zombie and putting it
//	on the zombie queue.  The next time the scheduler is called, this
//	process will be marked as free.  We can't necessarily do it now
//	because we might be the currently running process.
//
//	NOTE: This must only be called from an interrupt or trap.  However,
//	it need not be followed immediately by a ProcessSchedule() because
//	the process can continue running.
//
//----------------------------------------------------------------------
void ProcessDestroy (PCB *pcb) {
  dbprintf ('p', "ProcessDestroy (%d): function started\n", GetCurrentPid());
  ProcessSetStatus (pcb, PROCESS_STATUS_ZOMBIE);
  if (AQueueRemove(&(pcb->l)) != QUEUE_SUCCESS) {
    printf("FATAL ERROR: could not remove link from queue in ProcessDestroy!\n");
    GracefulExit();
  }
  if ((pcb->l = AQueueAllocLink(pcb)) == NULL) {
    printf("FATAL ERROR: could not get link for zombie PCB in ProcessDestroy!\n");
    GracefulExit();
  }
  if (AQueueInsertFirst(&zombieQueue, pcb->l) != QUEUE_SUCCESS) {
    printf("FATAL ERROR: could not insert link into runQueue in ProcessWakeup!\n");
    GracefulExit();
  }
  dbprintf ('p', "ProcessDestroy (%d): function complete\n", GetCurrentPid());
}
コード例 #14
0
//---------------------------------------------------------------------------
//	CondHandleBroadcast
//
//	This function is very similar to CondHandleSignal. But instead of
//	waking only one process, it wakes up all the processes waiting on the
//	condition variable. For this call to succeed, the calling process must
//	have acquired the lock associated with the condition variable. This
//	function should be written in such a way that the calling process
//	should retain the lock even after call completion.
//
//	Note that the process woken up by this call tries to acquire the lock
//	associated with the condition variable as soon as it wakes up. Thus,
//	for such a process to run, the process invoking CondHandleBroadcast
//	must explicitly release the lock after the call completion.
//---------------------------------------------------------------------------
int CondBroadcast(Cond *c) {
  if (!c) return SYNC_FAIL;
 
  if (c->lock->pid != GetCurrentPid()) {
    dbprintf('s', "CondBroadcast: Proc %d tried to broadcast, but it doesn't own cond %d\n", GetCurrentPid(), (int)(c-conds));
    return SYNC_FAIL;
  }

  while (!AQueueEmpty(&c->waiting)) {
    if (CondSignal(c) != SYNC_SUCCESS) {
      dbprintf('s', "CondBroadcast: Proc %d failed in signalling cond %d\n", GetCurrentPid(), (int)(c-conds));
      return SYNC_FAIL;
    }
  }
  dbprintf('s', "CondBroadcast: Proc %d successful broadcast on cond %d, still needs to release lock\n", 
                 GetCurrentPid(), (int)(c-conds));
  return SYNC_SUCCESS;
}
コード例 #15
0
ファイル: process.c プロジェクト: sransara/rocket-science
//----------------------------------------------------------------------
//
//	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', "ProcessSuspend (%d): function started\n", GetCurrentPid());
  ASSERT (suspend->flags & PROCESS_STATUS_RUNNABLE, "Trying to suspend a non-running process!\n");
  ProcessSetStatus (suspend, PROCESS_STATUS_WAITING);

  if (AQueueRemove(&(suspend->l)) != QUEUE_SUCCESS) {
    printf("FATAL ERROR: could not remove process from run Queue in ProcessSuspend!\n");
    GracefulExit();
  }
  if ((suspend->l = AQueueAllocLink(suspend)) == NULL) {
    printf("FATAL ERROR: could not get Queue Link in ProcessSuspend!\n");
    GracefulExit();
  }
  if (AQueueInsertLast(&waitQueue, suspend->l) != QUEUE_SUCCESS) {
    printf("FATAL ERROR: could not insert suspend PCB into waitQueue!\n");
    GracefulExit();
  }
  dbprintf ('p', "ProcessSuspend (%d): function complete\n", GetCurrentPid());
}
コード例 #16
0
ファイル: mbox.c プロジェクト: zhan1182/OS-Design
//-------------------------------------------------------
// 
// void MboxOpen(mbox_t);
//
// Open the mailbox for use by the current process.  Note
// that it is assumed that the internal lock/mutex handle 
// of the mailbox and the inuse flag will not be changed 
// during execution.  This allows us to get the a valid 
// lock handle without a need for synchronization.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxOpen(mbox_t handle) {

  unsigned int curr_pid = GetCurrentPid();

  // Check if handle is a valid number
  if(handle < 0 || handle >= MBOX_NUM_MBOXES){
    return MBOX_FAIL;
  }

  // Check if the mbox is reserved (activated)
  if(system_mbox[handle].num_of_pid_inuse < 0){
    return MBOX_FAIL;
  }

  // Acquire the lock
  if(LockHandleAcquire(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Acquire lock for the mbox %d!\n", handle);
    exitsim();
  }

  // Update the number of pid used
  if(system_mbox[handle].mbox_pid_list[curr_pid] == 1){
    printf("The mbox %d has already been opened\n", handle);
  }
  else if(system_mbox[handle].mbox_pid_list[curr_pid] == 0){
    system_mbox[handle].num_of_pid_inuse += 1;
    system_mbox[handle].mbox_pid_list[curr_pid] = 1;
  }
  else{
    printf("FATAL ERROR: Unkown Pid %d for mbox %d!\n", curr_pid, handle);
    // Release the lock
    if(LockHandleRelease(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
      printf("FATAL ERROR: Release lock for the mbox %d!\n", handle);
      exitsim();
    }
    return MBOX_FAIL;
  }
  
  // Release the lock
  if(LockHandleRelease(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Release lock for the mbox %d!\n", handle);
    exitsim();
  }


  return MBOX_SUCCESS;
}
コード例 #17
0
ファイル: mbox.c プロジェクト: sransara/rocket-science
//-------------------------------------------------------
//
// 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;
}
コード例 #18
0
ファイル: mbox.c プロジェクト: tashanicole56/ECE469
//-------------------------------------------------------
// 
// void MboxOpen(mbox_t);
//
// Open the mailbox for use by the current process.  Note
// that it is assumed that the internal lock/mutex handle 
// of the mailbox and the inuse flag will not be changed 
// during execution.  This allows us to get the a valid 
// lock handle without a need for synchronization.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxOpen(mbox_t handle) {
    Link *l;

    if(!&mboxs[handle]) return MBOX_FAIL;

    if ((l = AQueueAllocLink ((void *)GetCurrentPid())) == NULL) {
        printf("FATAL ERROR: could not allocate link for pid queue in Mbox Open!\n");
        exitsim();
    }

    if (AQueueInsertLast (&mboxs[handle].pids, l) != QUEUE_SUCCESS) {
        printf("FATAL ERROR: could not insert new link into pid queue in Mbox Open!\n");
        exitsim();
    }

    return MBOX_SUCCESS;
}
コード例 #19
0
//-------------------------------------------------------
// 
// void MboxOpen(mbox_t);
//
// Open the mailbox for use by the current process.  Note
// that it is assumed that the internal lock/mutex handle 
// of the mailbox and the inuse flag will not be changed 
// during execution.  This allows us to get the a valid 
// lock handle without a need for synchronization.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxOpen(mbox_t handle) {
	int intrs;

	if(MailBox[handle].inuse == false)
	{
		printf("Currently passed mailbox handle : %d by calling process : %d is unallocated\n", handle ,GetCurrentPid());
		return MBOX_FAIL;
	}

	intrs = DisableIntrs ();

	MailBox[handle].process_count++;
	MailBox[handle].procs_link[GetCurrentPid()] = 1;
		

	RestoreIntrs (intrs);
	return MBOX_SUCCESS;
}
コード例 #20
0
ファイル: mbox.c プロジェクト: sransara/rocket-science
//-------------------------------------------------------
// 
// void MboxOpen(mbox_t);
//
// Open the mailbox for use by the current process.  Note
// that it is assumed that the internal lock/mutex handle 
// of the mailbox and the inuse flag will not be changed 
// during execution.  This allows us to get the a valid 
// lock handle without a need for synchronization.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxOpen(mbox_t handle) {
	int cpid = GetCurrentPid();
	uint32 intrval;

	if(handle > MBOX_NUM_MBOXES || handle < 0) {
		return MBOX_FAIL;
	}
	if(mboxes[handle].inuse == false) {
		return MBOX_FAIL;
	}
	if(mboxes[handle].opened_pids[cpid] == false) {
		mboxes[handle].opened_pids[cpid] = true;
		intrval = DisableIntrs();
		mboxes[handle].opened_pids_count += 1;
		RestoreIntrs(intrval);
	}
	return MBOX_SUCCESS;
}
コード例 #21
0
ファイル: mbox.c プロジェクト: sransara/rocket-science
//-------------------------------------------------------
//
// 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;
}
コード例 #22
0
ファイル: mailbox.c プロジェクト: Nelson0409/DLX-OS
//-------------------------------------------------------
//
// int MboxClose(mbox_t);
//
// Close the mailbox for use to the current process.
// If the number of processes using the given mailbox
// is zero, then disable the mailbox structure and
// return it to the set of available mboxes.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxClose(mbox_t handle) {
	int i;
	int pid = GetCurrentPid();
	if (handle >= 0 && handle < MBOX_NUM_MBOXES) { //modified (MBOX_NUM_BOXES)
		if (mbox_list[(int)handle].in_use > 1) {
			for (i = 0; i < MBOX_NUM_BUFFERS; i++) {
				if (mbox_list[(int)handle].users[i] == pid) {
					mbox_list[(int)handle].users[i] = -1;
					mbox_list[(int)handle].in_use--;
//					printf("MboxClose: handle = %d in_use = %d", handle, mbox_list[(int)handle].in_use);
				}
			}
			return MBOX_SUCCESS;
		}else if(mbox_list[(int)handle].in_use == 1) {
			mbox_list[(int)handle].in_use = -1;
		}
	}		
	return MBOX_FAIL;
}
コード例 #23
0
ファイル: mbox.c プロジェクト: tashanicole56/ECE469
//-------------------------------------------------------
//
// int MboxClose(mbox_t);
//
// Close the mailbox for use to the current process.
// If the number of processes using the given mailbox
// is zero, then disable the mailbox structure and
// return it to the set of available mboxes.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxClose(mbox_t handle) {
    int i;
    int length;
    Link *l;

    if(!&mboxs[handle]) return MBOX_FAIL;

    if(!AQueueEmpty(&mboxs[handle].pids)){

        length = AQueueLength(&mboxs[handle].pids); 
        
        l = AQueueFirst(&mboxs[handle].pids);

        for(i=0; i < length; i++){
            if((int)AQueueObject(l) == GetCurrentPid()){
                AQueueRemove(&l);
                break;
            }

            l = AQueueNext(l);
        }

    }

    if(AQueueEmpty(&mboxs[handle].pids)){
        while(!AQueueEmpty(&mboxs[handle].messages)){
            l = AQueueFirst(&mboxs[handle].messages);
            AQueueRemove(&l);
        }

        mboxs[handle].inuse = 0;
    }

    return MBOX_SUCCESS;

}
コード例 #24
0
//---------------------------------------------------------------------------
//	LockHandleAcquire
//
//	This routine acquires a lock given its handle. The handle must be a 
//	valid handle for this routine to succeed. In that case this routine 
//	returns SYNC_FAIL. Otherwise the routine returns SYNC_SUCCESS.
//
//	Your implementation should be such that if a process that already owns
//	the lock calls LockHandleAcquire for that lock, it should not block.
//---------------------------------------------------------------------------
int LockAcquire(Lock *k) {
  Link	*l;
  int		intrval;
    
  if (!k) return SYNC_FAIL;

  // Locks are atomic
  intrval = DisableIntrs ();
  dbprintf ('I', "LockAcquire: Old interrupt value was 0x%x.\n", intrval);

  // Check to see if the current process owns the lock
  if (k->pid == GetCurrentPid()) {
    dbprintf('s', "LockAcquire: Proc %d already owns lock %d\n", GetCurrentPid(), (int)(k-locks));
    RestoreIntrs(intrval);
    return SYNC_SUCCESS;
  }

  dbprintf ('s', "LockAcquire: Proc %d asking for lock %d.\n", GetCurrentPid(), (int)(k-locks));
  if (k->pid >= 0) { // Lock is already in use by another process
    dbprintf('s', "LockAcquire: putting process %d to sleep\n", GetCurrentPid());
    if ((l = AQueueAllocLink ((void *)currentPCB)) == NULL) {
      printf("FATAL ERROR: could not allocate link for lock queue in LockAcquire!\n");
      exitsim();
    }
    if (AQueueInsertLast (&k->waiting, l) != QUEUE_SUCCESS) {
      printf("FATAL ERROR: could not insert new link into lock waiting queue in LockAcquire!\n");
      exitsim();
    }
    ProcessSleep();
  } else {
    dbprintf('s', "LockAcquire: lock is available, assigning to proc %d\n", GetCurrentPid());
    k->pid = GetCurrentPid();
  }
  RestoreIntrs(intrval);
  return SYNC_SUCCESS;
}
コード例 #25
0
ファイル: mbox.c プロジェクト: zhan1182/OS-Design
//-------------------------------------------------------
//
// 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 ct;
  unsigned int curr_pid = GetCurrentPid();
  int system_buffer_index = system_mbox[handle].mbox_buffer_index_array[system_mbox[handle].mbox_buffer_tail];
  
  // Check if the length of the message can fit into the buffer slot
  if(maxlength < 0 || maxlength >  MBOX_MAX_MESSAGE_LENGTH){
    return MBOX_FAIL;
  }
  
  // Check if handle is a valid number
  if(handle < 0 || handle >= MBOX_NUM_MBOXES){
    return MBOX_FAIL;
  }
  
  // Check if the mbox is reserved (activated). If not, return FAIL
  if(system_mbox[handle].num_of_pid_inuse < 0){
    return MBOX_FAIL;
  }

  // Check if the mbox is opened. If the mbox is not opened, return FAIL
  if(system_mbox[handle].mbox_pid_list[curr_pid] == 0){
    printf("Mbox Send Error: The mbox %d hasn't been opened yet\n", handle);
    return MBOX_FAIL;
  }


  // Acquire the lock of the mbox
  if(LockHandleAcquire(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Acquire lock for the mbox %d!\n", handle);
    exitsim();
  }
  
  
  // Else, check if the mbox is empty. If so, wait
  while(system_mbox[handle].mbox_buffer_slot_used == 0){
    if(CondHandleWait(system_mbox[handle].mbox_buffer_fill) != SYNC_SUCCESS){
      printf("FATAL ERROR: Wait on CV empty for mbox %d!\n", handle);
      exitsim();
    }
  }
  
  // Acquire the lock of the mbox message buffer
  if(LockHandleAcquire(system_mbox_message.system_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Acquire lock for the mbox %d!\n", handle);
    exitsim();
  }

  // Receive the message from the mbox
  for(ct = 0; ct < maxlength; ct++){
    *((char *) message + ct) = system_mbox_message.system_message_buffer[system_buffer_index][ct];
  }

  // Make the system buffer slot available again
  system_mbox_message.system_buffer_index_array[system_mbox[handle].mbox_buffer_tail] = 0;
  system_mbox_message.system_buffer_slot_used -= 1;

  // Update mbox used and mbox buffer tail info
  system_mbox[handle].mbox_buffer_slot_used -= 1;
  system_mbox[handle].mbox_buffer_tail = (system_mbox[handle].mbox_buffer_tail + 1) % MBOX_MAX_BUFFERS_PER_MBOX;


  // Signal system buffer empty CV
  if(CondHandleSignal(system_mbox_message.system_buffer_empty) != SYNC_SUCCESS){
    printf("FATAL ERROR: Signal on CV empty for system buffer!\n");
    exitsim();
  }


  // Release the lock of the mbox message buffer
  if(LockHandleRelease(system_mbox_message.system_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Release lock for the system buffer!\n");
    exitsim();
  }

  // Signal mbox empty CV
  if(CondHandleSignal(system_mbox[handle].mbox_buffer_empty) != SYNC_SUCCESS){
    printf("FATAL ERROR: Signal on CV empty for mbox %d!\n", handle);
    exitsim();
  }

  
  // Release the lock of the mbox
  if(LockHandleRelease(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Release lock for the mbox %d!\n", handle);
    exitsim();
  }



  return MBOX_SUCCESS;
}
コード例 #26
0
ファイル: mbox.c プロジェクト: zhan1182/OS-Design
//-------------------------------------------------------
//
// 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 ct;
  int system_buffer_index;
  unsigned int curr_pid = GetCurrentPid();

  // Check if the length of the message can fit into the buffer slot
  if(length < 0 || length >  MBOX_MAX_MESSAGE_LENGTH){
    return MBOX_FAIL;
  }

  // Check if handle is a valid number
  if(handle < 0 || handle >= MBOX_NUM_MBOXES){
    return MBOX_FAIL;
  }
  
  // Check if the mbox is reserved (activated)
  if(system_mbox[handle].num_of_pid_inuse < 0){
    return MBOX_FAIL;
  }

  // Check if the mbox is opened
  if(system_mbox[handle].mbox_pid_list[curr_pid] == 0){
    printf("Mbox Send Error: The mbox %d hasn't been opened yet\n", handle);
    return MBOX_FAIL;
  }
  
  // Acquire the lock of the mbox
  if(LockHandleAcquire(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Acquire lock for the mbox %d!\n", handle);
    exitsim();
  }
  
  // Else, check if the mbox is full. If so, wait
  while(system_mbox[handle].mbox_buffer_slot_used == MBOX_MAX_BUFFERS_PER_MBOX){
    if(CondHandleWait(system_mbox[handle].mbox_buffer_empty) != SYNC_SUCCESS){
      printf("FATAL ERROR: Wait on CV empty for mbox %d!\n", handle);
      exitsim();
    }
  }

  // Acquire the lock of the mbox message buffer
  if(LockHandleAcquire(system_mbox_message.system_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Acquire lock for the system buffer!\n");
    exitsim();
  }

  // Check if the system buffer is full. If so, wait 
  while(system_mbox_message.system_buffer_slot_used == MBOX_NUM_BUFFERS){
    // First Release the lock of the mbox
    if(LockHandleRelease(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
      printf("FATAL ERROR: Release lock for the mbox %d!\n", handle);
      exitsim();
    }

    // Wait on the system CV
    if(CondHandleWait(system_mbox_message.system_buffer_empty) != SYNC_SUCCESS){
      printf("FATAL ERROR: Wait on CV empty for system buffer!\n");
      exitsim();
    }

    // Re-Acquire the lock of the mbox
    if(LockHandleAcquire(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
      printf("FATAL ERROR: Acquire lock for the mbox %d!\n", handle);
      exitsim();
    }
  }

  // Find out an available slot in the system message buffer for the message
  for(system_buffer_index = 0; system_buffer_index < MBOX_NUM_BUFFERS; system_buffer_index++){
    if(system_mbox_message.system_buffer_index_array[system_buffer_index] == 0){
      system_mbox_message.system_buffer_index_array[system_buffer_index] = 1; // Reserved the slot
      break;
    }
  }
  
  // Double check if the index is valid
  if(system_buffer_index == MBOX_NUM_BUFFERS){
    printf("FATAL ERROR: System buffer sync error\n");
    exitsim();
  }


  // Put the message into the system message slot 
  for(ct = 0; ct < length; ct++){
    system_mbox_message.system_message_buffer[system_buffer_index][ct] = *((char *) message + ct);
  }

  // Set the mbox linking
  system_mbox[handle].mbox_buffer_index_array[system_mbox[handle].mbox_buffer_head] = system_buffer_index;
  
  // Update head and used info
  system_mbox_message.system_buffer_slot_used += 1;

  system_mbox[handle].mbox_buffer_slot_used += 1;
  system_mbox[handle].mbox_buffer_head = (system_mbox[handle].mbox_buffer_head + 1) % MBOX_MAX_BUFFERS_PER_MBOX;


  // Release the lock of the mbox message buffer
  if(LockHandleRelease(system_mbox_message.system_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Release lock for the system buffer %d!\n", handle);
    exitsim();
  }

  
  // Signal mbox fill CV
  if(CondHandleSignal(system_mbox[handle].mbox_buffer_fill) != SYNC_SUCCESS){
    printf("FATAL ERROR: Signal on CV fill for mbox %d!\n", handle);
    exitsim();
  }
  
  // Release the lock of the mbox
  if(LockHandleRelease(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Release lock for the mbox %d!\n", handle);
    exitsim();
  }


  return MBOX_SUCCESS;
}
コード例 #27
0
ファイル: mbox.c プロジェクト: zhan1182/OS-Design
//-------------------------------------------------------
//
// int MboxClose(mbox_t);
//
// Close the mailbox for use to the current process.
// If the number of processes using the given mailbox
// is zero, then disable the mailbox structure and
// return it to the set of available mboxes.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//-------------------------------------------------------
int MboxClose(mbox_t handle) {

  int clear_ct;
  unsigned int curr_pid = GetCurrentPid();
  int mbox_pid_status = system_mbox[handle].mbox_pid_list[curr_pid];

  // Check if handle is a valid number
  if(handle < 0 || handle >= MBOX_NUM_MBOXES){
    return MBOX_FAIL;
  }
  
  // Check if the mbox is reserved (activated)
  if(system_mbox[handle].num_of_pid_inuse < 0){
    return MBOX_FAIL;
  }

  // Acquire the lock
  if(LockHandleAcquire(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Acquire lock for the mbox %d!\n", handle);
    exitsim();
  }


  if(mbox_pid_status == 0){
    printf("The mbox %d has already been closed for process %d\n", handle, curr_pid);
  }
  else if(mbox_pid_status == 1){
    // Update the number of pid used
    system_mbox[handle].num_of_pid_inuse -= 1;
    system_mbox[handle].mbox_pid_list[curr_pid] = 0;
  }
  else{
    printf("FATAL ERROR: Unkown Pid %d for mbox %d\n", curr_pid, handle);
    // Release the lock
    if(LockHandleRelease(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
      printf("FATAL ERROR: Release lock for the mbox %d!\n", handle);
      exitsim();
    }
    return MBOX_FAIL;
  }
  
  // Return the mbox to the pool of available mboxes for the system
  // Reset this mbox, clear rest of messages in this mbox (clear the linkings in the system)
  if(system_mbox[handle].num_of_pid_inuse == 0){
    system_mbox[handle].num_of_pid_inuse = -1;

    for(clear_ct = 0; clear_ct < system_mbox[handle].mbox_buffer_slot_used; clear_ct++){
      // Make the system buffer slot available again
      system_mbox_message.system_buffer_index_array[system_mbox[handle].mbox_buffer_tail] = 0;
      system_mbox_message.system_buffer_slot_used -= 1;
      system_mbox[handle].mbox_buffer_tail = (system_mbox[handle].mbox_buffer_tail + 1) % MBOX_MAX_BUFFERS_PER_MBOX;
    }

  }


  // Release the lock
  if(LockHandleRelease(system_mbox[handle].mbox_buffer_lock) != SYNC_SUCCESS){
    printf("FATAL ERROR: Release lock for the mbox %d!\n", handle);
    exitsim();
  }

  return MBOX_SUCCESS;
}
コード例 #28
0
ファイル: traps.c プロジェクト: Nelson0409/DLX-OS
//----------------------------------------------------------------------
//
//	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 ();
}
コード例 #29
0
ファイル: process.c プロジェクト: yfeleke/ece469g05
//--------------------------------------------------------------------------
// ProcessKill destroys the current process and then calls ProcessSchedule.
// Therefore, you can only call ProcessKill from inside of a trap.
//--------------------------------------------------------------------------
void ProcessKill() {
  dbprintf('m', "ProcessKill: killing processid %d\n", GetCurrentPid());
  ProcessDestroy(currentPCB);
  ProcessSchedule();
}
コード例 #30
0
ファイル: mbox.c プロジェクト: tashanicole56/ECE469
//-------------------------------------------------------
//
// 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;


}