Пример #1
0
int DfsFreeBlock(int blocknum) {
    int fbvnum;
    int bitnum;
    int i;
    if((blocknum<0)||(blocknum>sb.filesys_blocknum)){
       printf("Invalid blocknum = %d\n",blocknum);
       return DFS_FAIL;
    }

     fbvnum = (blocknum)/32;
     bitnum = (blocknum)%32;
    
//    printf("In DfsFreeBlock\n");
    if (sb.valid == 0){
        printf("File system not open!\n");
        return DFS_FAIL;
    }
    LockHandleAcquire(lock_fbv);
    fbv[fbvnum] = (fbv[fbvnum] & invert(1<<bitnum))|(1 << bitnum);
    LockHandleRelease(lock_fbv);
    
//    for(i=0;i<10;i++){
//     printf("fbv[%d] : 0x%x\n",i,fbv[i]);
//    }
    return DFS_SUCCESS;

}
Пример #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) {


//	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;
}
Пример #3
0
//-----------------------------------------------------------------
// DfsInodeOpen: search the list of all inuse inodes for the
// specified filename. If the filename exists, return the handle
// of the inode. If it does not, allocate a new inode for this
// filename and return its handle. Return DFS_FAIL on failure.
// Remember to use locks whenever you allocate a new inode.
//-----------------------------------------------------------------
uint32 DfsInodeOpen(char *filename) {
    uint32 i;
    if(!sb.valid) {
        printf("DfsInodeOpen: invalid file system\n");
        return DFS_FAIL;
    }
    i = DfsInodeFilenameExists(filename);
    if(i != DFS_FAIL) {
        printf("[DEBUG] Opened inode:%d\n", i);
        return i;
    }
    while(LockHandleAcquire(dfs_inode_lock) != SYNC_SUCCESS);
    for(i = 0; i < sb.total_inodes; i++) {
        if(inodes[i].valid) {
            continue;
        }
        inodes[i].valid = 1;
        inodes[i].filesize = 0;
        dstrncpy(inodes[i].filename, filename, DFS_FILENAME_LENGTH);
        break;
    }
    LockHandleRelease(dfs_inode_lock);
    printf("[DEBUG] Opened inode:%d\n", i);
    return i;
}
Пример #4
0
int DfsAllocateBlock() {
// Check that file system has been validly loaded into memory
// Find the first free block using the free block vector (FBV), mark it in use
// Return handle to block
   int fbvnum;
   int bitnum;
   int block;
   uint32 v;
   int i;
 //  printf("In DfsAllocateBlock\n");
   if(sb.valid ==0){
      printf("Filesystem not open!\n");
      return DFS_FAIL;
   }
   LockHandleAcquire(lock_fbv);
   block = sb.filesys_datastart;
   fbvnum = block/32;
   while(fbv[fbvnum] == 0){
       fbvnum+=1;
       if(fbvnum>=(DFS_FBV_MAX_NUM)){
          fbvnum = block/32;
       }
   }
   v = fbv[fbvnum];
   for (bitnum = 0;(v & (1 << bitnum)) == 0; bitnum++);
   fbv[fbvnum] &= invert(1 << bitnum);
   v = (fbvnum * 32) + bitnum;
   LockHandleRelease(lock_fbv);
   
//   for(i=0;i<10;i++){
//   printf("fbv[%d]: 0x%x\n",i,fbv[i]);
//   }
   return (int)v;    
}
Пример #5
0
uint32 DfsAllocateBlock() {
    int i;
    uint32 bitnum;
    uint32 vector;
// Check that file system has been validly loaded into memory
    if(!sb.valid) {
        printf("DfsAllocateBlock: Filesystem is not validly loaded into memory\n");
        return DFS_FAIL;
    }
    while(LockHandleAcquire(dfs_fbv_lock) != SYNC_SUCCESS);
// Find the first free block using the free block vector (FBV), mark it in use
    for(i = 0; i < sb.fbv_num_words; i++) {
        if(fbv[i] != 0) {
            break;
        }
    }
    if(i == sb.fbv_num_words) {
        printf("DfsAllocateBlock: Could not allocate block\n");
        return DFS_FAIL;
    }
    vector = fbv[i];
    for(bitnum = 0; (vector & (1 << bitnum)) == 0; bitnum++) {}
    fbv[i]  &= invert(1 << bitnum);
    vector = (i * 32) + bitnum;
    dbprintf('d', "DfsAllocateBlock: Allocated block %d\n", vector);
    LockHandleRelease(dfs_fbv_lock);
// Return handle to block
    return vector;
}
Пример #6
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) {

  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;
}
Пример #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 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;
}
Пример #8
0
int DfsInodeDelete(int handle) {
    int i;
    dfs_block indirect_table;
    uint32 *table;
  //  printf("In DfsInodeDelete\n");
    if (sb.valid == 0){
       printf("File system not open!\n");
       return DFS_FAIL;
    }
    if((handle<0)||(handle>DFS_INODE_MAX_NUM)){
       printf("Invalid inode handle = %d\n",handle);
       return DFS_FAIL;
    }
     if(inodes[handle].inuse == 0){
       printf("Inode not allocated!\n");
       return DFS_FAIL;
    }
    LockHandleAcquire(lock_inode);
    //Free direct table then check if there is indirect address
    for(i=0;i<10;i++){
      if(inodes[handle].direct[i]!=0){
      if(DfsFreeBlock((int)inodes[handle].direct[i])==DFS_FAIL){
         printf("Cannot free blocks in direct table!\n");
         return DFS_FAIL;
      }
      inodes[handle].direct[i]=0;
     }
    }
   //Free the indirect table
    if(inodes[handle].indirect != 0){
      table =(uint32 *)(&indirect_table);
      DfsReadBlock(inodes[handle].indirect,&indirect_table);
        for(i=0;i<(sb.filesys_blocksize)/sizeof(uint32);i++){
           if(table[i]!=0){
             if (DfsFreeBlock((int)table[i])== DFS_FAIL){
                 printf("Cannot free blocks in indirect table\n");
                 return DFS_FAIL;
               }
           }
        }
       if(DfsFreeBlock((int)inodes[handle].indirect)==DFS_FAIL){
          printf("Cannot free blocks in indirect table\n");
       }
       inodes[handle].indirect=0;
     }

    FreeEntry(handle);
    inodes[handle].filesize = 0;
  //  for(i=0;i< FILENAME_LENGTH;i++){
 //       inodes[handle].filename[i]='\0';
 //   }
    inodes[handle].permission = 0;
    inodes[handle].type = 0;
    inodes[handle].ownerid = 0;
    inodes[handle].inuse = 0;
    LockHandleRelease(lock_inode);
    return DFS_SUCCESS;
}
Пример #9
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;
}
Пример #10
0
//-----------------------------------------------------------------
// DfsFreeBlock deallocates a DFS block.
//-----------------------------------------------------------------
int DfsFreeBlock(uint32 blocknum) {
    if(!sb.valid) {
        printf("DfsFreeBlock: Filesystem is not validly loaded into memory\n");
        return DFS_FAIL;
    }
    while(LockHandleAcquire(dfs_fbv_lock) != SYNC_SUCCESS);
    SetFreeVector(blocknum, 1);
    LockHandleRelease(dfs_fbv_lock);
    dbprintf('d', "DfsFreeBlock: Freed block %d\n", blocknum);
    return DFS_SUCCESS;
}
Пример #11
0
//-----------------------------------------------------------------
// DfsInodeDelete de-allocates any data blocks used by this inode,
// including the indirect addressing block if necessary, then mark
// the inode as no longer in use. Use locks when modifying the
// "inuse" flag in an inode.Return DFS_FAIL on failure, and
// DFS_SUCCESS on success.
//-----------------------------------------------------------------
int DfsInodeDelete(uint32 handle) {
    int i;
    dfs_block dfsb;
    int* inints = (int*) dfsb.data;
    if(!sb.valid) {
        printf("DfsInodeDelete: invalid file system\n");
        return DFS_FAIL;
    }
    if(!inodes[handle].valid) {
        printf("DfsInodeDelete: invalid inode\n");
        return DFS_FAIL;
    }
    while(LockHandleAcquire(dfs_fbv_lock) != SYNC_SUCCESS);
    if(DFS_IS_BLOCK_ENTRY_VALID(inodes[handle].indir_block_entry)) {
        DfsReadBlock(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), &dfsb);
        for(i = 0; i < (sb.blocksize / sizeof(int)); i++) {
            if(DFS_IS_BLOCK_ENTRY_VALID(inints[i])) {
                SetFreeVector(DFS_GET_BLOCK_NUM(inints[i]), 1);
            }
        }
        // clear out the indirect block entry table
        bzero(dfsb.data, sb.blocksize);
        DfsWriteBlock(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), &dfsb);
        SetFreeVector(DFS_GET_BLOCK_NUM(inodes[handle].indir_block_entry), 1);
        inodes[handle].indir_block_entry = DFS_SET_BLOCK_ENTRY(0, 0);
    }
    for(i = 0; i < 10; i++) {
        if(DFS_IS_BLOCK_ENTRY_VALID(inodes[handle].direct_block_entries[i])) {
            SetFreeVector(DFS_GET_BLOCK_NUM(inodes[handle].direct_block_entries[i]), 1);
            inodes[handle].direct_block_entries[i] = DFS_SET_BLOCK_ENTRY(0, 0);
        }
    }
    LockHandleRelease(dfs_fbv_lock);

    while(LockHandleAcquire(dfs_inode_lock) != SYNC_SUCCESS);
    inodes[handle].valid = 0;
    LockHandleRelease(dfs_inode_lock);
    return DFS_SUCCESS;
}
Пример #12
0
int DfsInodeOpen(char *filename,int handle,int type,int ownerid,unsigned char permission) {
     int i,j;
     int handler;
  //   printf("In DfsInodeOpen\n");
     if(sb.valid == 0){
        printf("File system not open!\n");
        return DFS_FAIL;
     }
     if((handler = DfsInodeFilenameExists(filename,handle))!= DFS_FAIL){
         printf("Open existing file!\n");
         return handler;
       }
     else{
      for(i=0;i<sb.inodenum;i++){
         if(inodes[i].inuse == 0){
           LockHandleAcquire(lock_inode);
            inodes[i].inuse = 1;
            inodes[i].filesize = 0;
            for(j=0;j<sb.dirnum;j++){
                if(dir[j].inuse == 0){
                   inodes[i].dir = &dir[j];
                    break;
               }
             }
            inodes[i].permission = permission;
            inodes[i].type = type;
            inodes[i].ownerid = ownerid;
            handler=i;
           LockHandleRelease(lock_inode);
          if(InsertEntry(filename,handle,handler)== DFS_FAIL){
             printf ("Error: Cannot insert inode %d into dir of inode %d\n",handler,handle);
            return DFS_FAIL;
          }
            return handler;
          }  
       }
    }
   printf("No free inodes!\n");
   return DFS_FAIL;
}
Пример #13
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;
}
Пример #14
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 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;
}
Пример #15
0
//--------------------------------------------------------------------------------
// 
// int MboxCloseAllByPid(int pid);
//
// Scans through all mailboxes and removes this pid from their "open procs" list.
// If this was the only open process, then it makes the mailbox available.  Call
// this function in ProcessFreeResources in process.c.
//
// Returns MBOX_FAIL on failure.
// Returns MBOX_SUCCESS on success.
//
//--------------------------------------------------------------------------------
int MboxCloseAllByPid(int pid) {

  int ct;
  int clear_ct;
  int mbox_pid_status;

  // Check if the pid is valid
  if(pid < 0 || pid >= PROCESS_MAX_PROCS){
    return MBOX_FAIL;
  }

  // Go througth all the mboxes
  for(ct = 0; ct < MBOX_NUM_MBOXES; ct++){
    // Acquire the lock of the mbox
    if(LockHandleAcquire(system_mbox[ct].mbox_buffer_lock) != SYNC_SUCCESS){
      printf("FATAL ERROR: Acquire lock for the mbox %d!\n", ct);
      exitsim();
    }
  
    // Check if the pid is in the mbox's "open procs" list. 
    // If so, remove the pid and make the mailbox available if no other proc opens the mbox
    // Else, do nothing
    mbox_pid_status = system_mbox[ct].mbox_pid_list[pid];

    if(mbox_pid_status == 0){
      // Do nothing
    }
    else if(mbox_pid_status == 1){
      // Update the number of pid used
      system_mbox[ct].num_of_pid_inuse -= 1;
      system_mbox[ct].mbox_pid_list[pid] = 0;
    }
    else{
      printf("FATAL ERROR: Unkown Pid %d for mbox %d\n", pid, ct);
      // Release the lock
      if(LockHandleRelease(system_mbox[ct].mbox_buffer_lock) != SYNC_SUCCESS){
	printf("FATAL ERROR: Release lock for the mbox %d!\n", ct);
	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[ct].num_of_pid_inuse == 0){
      system_mbox[ct].num_of_pid_inuse = -1;
      for(clear_ct = 0; clear_ct < system_mbox[ct].mbox_buffer_slot_used; clear_ct++){
	// Make the system buffer slot available again
	system_mbox_message.system_buffer_index_array[system_mbox[ct].mbox_buffer_tail] = 0;
	system_mbox_message.system_buffer_slot_used -= 1;
	system_mbox[ct].mbox_buffer_tail = (system_mbox[ct].mbox_buffer_tail + 1) % MBOX_MAX_BUFFERS_PER_MBOX;
    }
    }

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

  }

  return MBOX_SUCCESS;
}
Пример #16
0
//-------------------------------------------------------
//
// 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;
}
Пример #17
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 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;
}
Пример #18
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 intrs;
	int wasEmpty = 0;
	Link * mbuffer_link;

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

	if(MailBox[handle].procs_link[GetCurrentPid()] == false)
	{
		printf("Mailbox : %d not already opened by calling proces :%d\n", handle, GetCurrentPid());
		return MBOX_FAIL;
	}

	intrs = DisableIntrs();

	LockHandleAcquire(MailBox[handle].lock);

	while(AQueueLength(&MailBox[handle].buffers) == MBOX_MAX_BUFFERS_PER_MBOX || used_buffers == MBOX_NUM_BUFFERS)
	{
		CondHandleWait(MailBox[handle].moreSpace);
	}

	//printf("Buffer size of queue before inserting messager by : %d is : %d\n", GetCurrentPid(), AQueueLength(&MailBox[handle].buffers));

	if(AQueueLength(&MailBox[handle].buffers) == 0)
		wasEmpty = 1;

	if(AQueueLength(&MailBox[handle].buffers) != MBOX_MAX_BUFFERS_PER_MBOX)
	{
		if(length > MBOX_MAX_MESSAGE_LENGTH)
		{
			printf("Messge passed by user process : %d larger than accepted message length (Messge length sent - %d)", GetCurrentPid(), length);
			return MBOX_FAIL;
		}
	
		bcopy(message, Messg_Buffers[used_buffers++].message, 8); 
		
		Messg_Buffers[used_buffers - 1].size = length;

		//printf("Original Message : %s Copied  : %s in : %d\n", (char *)message, (char *)(Messg_Buffers[used_buffers - 1].message), handle);

		if((mbuffer_link = AQueueAllocLink(&Messg_Buffers[used_buffers - 1])) == QUEUE_FAIL)
		{
			printf("FATAL Error : Link object could not be created for message buffer : %d in process : %d",used_buffers - 1, GetCurrentPid());
			exitsim();
		}

		if(AQueueInsertLast(&MailBox[handle].buffers, mbuffer_link) != QUEUE_SUCCESS)
		{
			printf("FATAL Error : Link object could not be created for message buffer : %d in process : %d",used_buffers - 1, GetCurrentPid());
			exitsim();	
		}
	}

	//printf("Message inserted by process : %d using buffer : %d with current count : %d\n", GetCurrentPid(), buffer_no, AQueueLength(&MailBox[handle].buffers));

	//if(wasEmpty)
	CondHandleSignal(MailBox[handle].moreData);

	LockHandleRelease(MailBox[handle].lock);

	RestoreIntrs(intrs);

  return MBOX_SUCCESS;
}
Пример #19
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 ();
}
Пример #20
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 intrs;
	int wasFull = 0, buffersSaturated = 0;
	mbox_message * user_mesg;
	Link *l;
	
	if(MailBox[handle].inuse == false)
	{
		printf("Currently passed mailbox handle : %d by calling process : %d is unallocated\n", handle, GetCurrentPid());
		return MBOX_FAIL;
	}

	if(MailBox[handle].procs_link[GetCurrentPid()] == false)
	{
		printf("Mailbox : %d not already opened by calling proces :%d\n", handle, GetCurrentPid());
		return MBOX_FAIL;
	}

	intrs = DisableIntrs();

	LockHandleAcquire(MailBox[handle].lock);

	while(AQueueLength(&MailBox[handle].buffers) == 0)
	{
		//printf("Waiting for mailbox to have more messages\n");
		CondHandleWait(MailBox[handle].moreData);
	}

	//printf("Received mailbox lock by calling process : %d with mailbox buffer count : %d\n", GetCurrentPid(), AQueueLength(&MailBox[handle].buffers));

	if(AQueueLength(&MailBox[handle].buffers) == MBOX_MAX_BUFFERS_PER_MBOX)
		wasFull = 1;

	if(AQueueLength(&MailBox[handle].buffers) < MBOX_MAX_BUFFERS_PER_MBOX && used_buffers == MBOX_NUM_BUFFERS)
		buffersSaturated = 1;

	//printf("Obtained message in receiver : %d from buffer index : %d\n", user_mesg->size, (user_mesg - Messg_Buffers));

	if((user_mesg = (mbox_message *)AQueueObject(MailBox[handle].buffers.first)) == NULL)
	{
		printf("Undefined/unallocated Link pointer obtained from mailbox queue with handle :%d in process : %d\n", handle, GetCurrentPid());
		//printf("MailBox buffer size : %d\n", AQueueLength(&MailBox[handle].buffers));
		return MBOX_FAIL;
	}
		
	if(maxlength < user_mesg->size)
	{
		printf("Message : %s requested by user process : %d larger than acceptable message length : %d (Messge length received : %d)\n", user_mesg->message, GetCurrentPid(), maxlength, user_mesg->size);
		return MBOX_FAIL;
	}

	bcopy(user_mesg->message, message, user_mesg->size); 

	l = MailBox[handle].buffers.first;
	MailBox[handle].buffers.first = AQueueNext(MailBox[handle].buffers.first);
	if(AQueueRemove(&l) == QUEUE_FAIL)
	{
		printf("FATAL Error : Message object Link for buffer : %d received by process : %d could not be removed from queue of mailbox handle : %d",used_buffers, GetCurrentPid(), handle);
		exitsim();
	}

	used_buffers--;

	//if(wasFull || buffersSaturated)
	CondHandleSignal(MailBox[handle].moreSpace);

	LockHandleRelease(MailBox[handle].lock);

	RestoreIntrs(intrs);

  return user_mesg;
}
Пример #21
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;

}
Пример #22
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;


}