示例#1
0
文件: frame.c 项目: xuruiyang/CS5600
struct frame_table_entry* frame_get_new_page (bool zero){
	uint8_t *kpage;
	struct frame_table_entry *fte = NULL;
redo:
	if(zero){
		kpage = palloc_get_page (PAL_USER|PAL_ZERO);
	}else{
		kpage = palloc_get_page (PAL_USER);
	}
	if(kpage!=NULL){
	ASSERT (is_kernel_vaddr (kpage));
		/*
		 * TODO:
		 * add new page into frame control here,
		 * after all info be recorded, return the
		 * page table entry. uaddr should be added
		 * by latter...
		 */
		fte = malloc(sizeof(struct frame_table_entry));
		fte->kpg_vaddr = kpage;
		fte->owner = thread_current();
		fte->pinned = true;
		list_push_back (&frame_table, &fte->elem);
//		printf("thread %d released frame_lock\n",thread_current()->tid);
		return fte;
	}else{
		//evict a page to swap(0)
		frame_evict_page();
		goto redo;
	}
}
示例#2
0
文件: frame.c 项目: chutchUCD/OS
/**
 * An (internal, private) method --
 * Deallocates a frame or page (internal procedure)
 * MUST BE CALLED with 'frame_lock' held.
 */
void
vm_frame_do_free (void *kpage, bool free_page)
{
  ASSERT (lock_held_by_current_thread(&frame_lock) == true);
  ASSERT (is_kernel_vaddr(kpage));
  ASSERT (pg_ofs (kpage) == 0); // should be aligned

  // hash lookup : a temporary entry
  struct frame_table_entry f_tmp;
  f_tmp.kpage = kpage;

  struct hash_elem *h = hash_find (&frame_map, &(f_tmp.helem));
  if (h == NULL) {
    PANIC ("The page to be freed is not stored in the table");
  }

  struct frame_table_entry *f;
  f = hash_entry(h, struct frame_table_entry, helem);

  hash_delete (&frame_map, &f->helem);
  list_remove (&f->lelem);

  // Free resources
  if(free_page) palloc_free_page(kpage);
  free(f);
}
示例#3
0
文件: frame.c 项目: hammouse/pintos2
struct frame* frame_table_set (void* upage, void* kpage){
	struct frame* frame_new;

	ASSERT(is_user_vaddr(upage));
	ASSERT(is_kernel_vaddr(kpage));

	// TODO: now, frame_find also use frame_lock. This is bad for speed
	// if kpage frame is already exist, go to else statement
	lock_acquire(&frame_lock);
	if(!frame_find(kpage)){
		frame_new = malloc(sizeof(struct frame));
		frame_new->process = thread_current();
		frame_new->upage = (void*)((int)upage&PAGE_MASK);
		frame_new->kpage = (void*)((int)kpage&PAGE_MASK);
		list_push_back(&frame_table, &(frame_new->table_elem));
		//printf("**** [frame_table_set] frame '%x', upage '%x', kpage '%x'\n",frame_new, frame_new->upage, frame_new->kpage);
		lock_release(&frame_lock);
		return frame_new;
	}
	else{
		lock_release(&frame_lock);
		return NULL;
	}
}
示例#4
0
文件: syscall.c 项目: posijon/PintOS
static void
syscall_handler (struct intr_frame *f)
{
  int32_t* esp = (int32_t*)f->esp;
  /*
    Any parameters passed to syscall will be above ESP, see illustration below.
    Number of arguments each syscall expects is in argc[] array above.

    syscall number is pointed to by ESP.
    --------------------------------------
    PHYS_BASE
    .................
    <param>
    <param>
    ESP --->    <syscall_number>

    --------------------------------------
  */

  // verify esp pointer is ok, first parameter: current thread
   if(esp == NULL || verify_fix_length(esp, sizeof(esp)) == false){
	sys_exit(-1);
   }

   // esp adress belongs to thread
  if(pagedir_get_page(thread_current()->pagedir, esp) == NULL){
	sys_exit(-1);
   } 

  // ok syscall nr
  int32_t syscall_nr = *esp;
  if(syscall_nr < 0 || syscall_nr >= SYS_NUMBER_OF_CALLS){
	sys_exit(-1);
  }

  // Make sure our data is not overwriting PHYS_BASE.
  int expected_args = argc[syscall_nr];
  unsigned long highest_addr = esp + (expected_args * sizeof(int));
  if(highest_addr >= PHYS_BASE){
	sys_exit(-1);
  }
  
  if(pagedir_get_page(thread_current()->pagedir, highest_addr) == NULL){
	sys_exit(-1);
  }

  /*
  int i = 1;
  for(; i <= expected_args; i++){
	if(verify_fix_length(&esp[i], sizeof(int) ) == false){
		sys_exit(-1);
	}
      
  }
	*/

  DEBUG_SYSCALL("# SYSCALL received = %s\n", get_system_call_name(syscall_nr));
  
  
  switch (syscall_nr)
    {
  
    case SYS_HALT:
      power_off();
      break;
    case SYS_EXEC:
    {

      	f->eax = SYS_EXEC_handler(esp);
    }
    break;
  
    case SYS_WAIT:
    {
      
      int child_pid = *(esp + 1);
      
      f->eax = process_wait (child_pid);
      break; 
    }
  
    case SYS_EXIT:
    {
      if(is_kernel_vaddr(pg_round_up((void*)esp[1]) )){
	sys_exit(-1);
      }
      int exit_status = *(esp + 1);
      process_exit(exit_status);
      thread_exit();
      break;
    }
    case SYS_PLIST:
        process_print_list();
    break;
    case SYS_CREATE:
      {
        bool success = false;

        char *name = (char*)*(esp + 1);
	if(name == NULL){
		sys_exit(-1);
	}
        unsigned initial_size = *(esp + 2);

	if(verify_fix_length(esp[1], initial_size) == false){
		sys_exit(-1);
	}
	if(verify_variable_length(esp[1]) == false){
		sys_exit(-1);
	}
        success = filesys_create(name, initial_size);

        if(success) {
          DEBUG_SYSCALL("#SYS_CREATE - File with name: %s created. \n", name);

        } else {
          DEBUG_SYSCALL("#SYS_CREATE - filesys_create failed: file named \'%s\' already exists  or internal memory allocation failed \n", name);
        }

        f->eax = success;
        break;
      }
    case SYS_OPEN:
      {
        char *name = (char*)*(esp + 1);
	if(name == NULL){
		sys_exit(-1);
	}
	if(verify_variable_length(esp[1]) == false){
		sys_exit(-1);
	}


        struct file *file;
        file = filesys_open(name);


	int retVal = -1;
        if(file != NULL) {
          DEBUG_SYSCALL("# SYS_OPEN - File with name: '%s' created. \n", name);

	  int fd = flist_add_file(file);
	  retVal = fd;
        } else {
          DEBUG_SYSCALL("# SYS_OPEN - filesys_open failed: no file named \'%s\' exists or internal memory allocation failed \n", name);
          retVal = -1;

        }
	f->eax = retVal;
        break;
      }
    case SYS_READ:
      {
        int retVal = SYS_READ_handler(esp);

        f->eax = retVal;
        break;
      }
    case SYS_CLOSE:
	{
	int retVal = SYS_CLOSE_handler(esp);
	f->eax = retVal;
	
	break;
	}
    case SYS_REMOVE:
	{
		int retVal = SYS_REMOVE_handler(esp);
		f->eax = retVal;
		break;
	}
    case SYS_WRITE:
      {
        int retVal = SYS_WRITE_handler(esp);
        f->eax = retVal;
        break;
      }
    case SYS_SEEK:
	{
	f->eax = SYS_SEEK_handler(esp);
	break;
	}
    case SYS_TELL:

	f->eax = SYS_TELL_handler(esp);
	break;
	

    case SYS_FILESIZE:
	f->eax = SYS_FILESIZE_handler(esp);
	break;
    default:
      {
        DEBUG_SYSCALL ("Executed an unknown system call (nr: %i)!\n", syscall_nr);
        DEBUG_SYSCALL ("Stack top + 0: %d\n", esp[0]);
        DEBUG_SYSCALL ("Stack top + 1: %d\n", esp[1]);

        thread_exit ();
      }
    }
}