コード例 #1
0
ファイル: mm2_mmap.cpp プロジェクト: mallardtheduck/osdev
	void mm2_closemap(uint64_t id){
		hold_lock hl(mmap_lock, false);
		if(mmappings->has_key(id)){
			mmapping m = (*mmappings)[id];
			pid_t curpid = proc_current_pid;
			proc_switch(m.pid);
			flush_mapping(m);
			if(m.size > MM2_Page_Size){
				for(size_t i = 0; i < m.pages; ++i){
					char *pageaddr = m.page_addr + (i * MM2_Page_Size);
					if(!current_pagedir->is_mapped(pageaddr)){
						uint32_t flags = MM2_PageFlags::Present | MM2_PageFlags::Writable;
						if((uint32_t)m.addr >= MM2_Kernel_Boundary) flags = MM2_PageFlags::Present | MM2_PageFlags::Writable | MM2_PageFlags::Usermode;
						current_pagedir->map_page_at(pageaddr, flags);
					}
				}
			}
			if(m.size > MM2_Page_Size){
				if((uint32_t)m.addr < MM2_Kernel_Boundary){
					kernel_pagedir->remove_region(m.page_addr);
				}else{
					current_pagedir->remove_region(m.page_addr);
				}
			}
			mmappings->erase(id);
			if(mmappings->has_key(id)) panic("(MM2) Mapping removal failed!");
			proc_switch(curpid);
		}
	}
コード例 #2
0
ファイル: module.c プロジェクト: grahamedgecombe/arc
void module_init(multiboot_t *multiboot)
{
  /*
   * disable interrupts, module loading messes around with address space
   * switches so we don't want to confuse the scheduler
   */
  intr_lock();

  /* keep a copy of the old process */
  proc_t *old_proc = proc_get();

  multiboot_tag_t *tag = multiboot_get(multiboot, MULTIBOOT_TAG_MODULE);
  while (tag)
  {
    module_load(tag);
    tag = multiboot_get_after(multiboot, tag, MULTIBOOT_TAG_MODULE);
  }

  /* switch back to the correct address space */
  if (old_proc)
    proc_switch(old_proc);

  /* enable interrupts again */
  intr_unlock();
}
コード例 #3
0
ファイル: module.c プロジェクト: grahamedgecombe/arc
static void module_load(multiboot_tag_t *tag)
{
  /* calculate size and phy32 pointer */
  size_t size = tag->module.mod_end - tag->module.mod_start;
  elf64_ehdr_t *elf = (elf64_ehdr_t *) aphy32_to_virt(tag->module.mod_start);

  /* make a new process */
  proc_t *proc = proc_create();
  if (!proc)
    panic("couldn't create process for module");

  /* switch our address space */
  proc_switch(proc);

  /* load the ELF file */
  if (!elf64_load(elf, size))
    panic("couldn't load elf64 file");

  /* make a new thread */
  thread_t *thread = thread_create(proc, 0);
  if (!thread)
    panic("couldn't create thread for module");

  /* set entry point of the thread */
  thread->rip = elf->e_entry;

  /* add thread to the scheduler's ready queue */
  thread_resume(thread);
}
コード例 #4
0
ファイル: shm.cpp プロジェクト: mallardtheduck/osdev
	void shm_close_map(uint64_t id){
		hold_lock(shm_lock, false);
		
		if(mappings->has_key(id)){
			shm_mapping *mapping = (*mappings)[id];
			bt_pid_t pid = proc_current_pid;
			proc_switch(mapping->pid);
			current_pagedir->remove_region(mapping->addr);
			void *addr = mapping->addr;
			for(uint32_t i = (uint32_t)addr; i < (uint32_t)addr + (mapping->pages * MM2_Page_Size); i += MM2_Page_Size){
				current_pagedir->map_page_at((void*)i, MM2_PageFlags::Present | MM2_PageFlags::Writable | MM2_PageFlags::Usermode);
			}
			delete mapping;
			mappings->erase(id);
			proc_switch(pid);
		}
	}
コード例 #5
0
ファイル: mm2_mmap.cpp プロジェクト: mallardtheduck/osdev
	static void flush_mapping(mmapping &m){
		pid_t curpid = proc_current_pid;
		proc_switch(m.pid);
		bt_filesize_t pos = fs_seek(m.file, 0, FS_Relative);
		
		if(m.size <= MM2_Page_Size){
			fs_seek(m.file, m.offset, FS_Set);
			fs_write(m.file, m.size, m.addr);
			fs_seek(m.file, pos, FS_Set);
			proc_switch(curpid);
			return;
		}
		
		if(m.pre){
			fs_seek(m.file, m.offset, FS_Set);
			fs_write(m.file, m.pre, m.addr);
		}
		
		if(m.post){
			bt_filesize_t postoffset = m.page_offset + (m.pages * MM2_Page_Size);
			char *postaddr = (char*)((uint32_t)m.page_addr + (m.pages * MM2_Page_Size));
			fs_seek(m.file, postoffset, FS_Set);
			fs_write(m.file, m.post, postaddr);
		}
		
		for(size_t i = 0; i < m.pages; ++i){
			char *pageaddr = m.page_addr + (i * MM2_Page_Size);
			if(current_pagedir->is_mapped(pageaddr)){
				bt_filesize_t fileoffset = m.page_offset + (i * MM2_Page_Size);
				fs_seek(m.file, fileoffset, FS_Set);
				fs_write(m.file, MM2_Page_Size, pageaddr);
				current_pagedir->free_pages(pageaddr, 1);
			}
			current_pagedir->guard_page_at(pageaddr);
		}
		fs_seek(m.file, pos, FS_Set);
		proc_switch(curpid);
	}
コード例 #6
0
ファイル: signal.c プロジェクト: mtarek/BeRTOS
/**
 * Sleep until any of the signals in \a sigs occurs.
 * \return the signal(s) that have awoken the process.
 */
sigmask_t sig_wait(sigmask_t sigs)
{
	sigmask_t result;

	/* Sleeping with IRQs disabled or preemption forbidden is illegal */
	IRQ_ASSERT_ENABLED();
	ASSERT(proc_preemptAllowed());

	/*
	 * This is subtle: there's a race condition where a concurrent process
	 * or an interrupt may call sig_send()/sig_post() to set a bit in
	 * Process.sig_recv just after we have checked for it, but before we've
	 * set Process.sig_wait to let them know we want to be awaken.
	 *
	 * In this case, we'd deadlock with the signal bit already set and the
	 * process never being reinserted into the ready list.
	 */
	IRQ_DISABLE;

	/* Loop until we get at least one of the signals */
	while (!(result = current_process->sig_recv & sigs))
	{
		/*
		 * Tell "them" that we want to be awaken when any of these
		 * signals arrives.
		 */
		current_process->sig_wait = sigs;

		/* Go to sleep and proc_switch() to another process. */
		proc_switch();
		/*
		 * When we come back here, the wait mask must have been
		 * cleared by someone through sig_send()/sig_post(), and at
		 * least one of the signals we were expecting must have been
		 * delivered to us.
		 */
		ASSERT(!current_process->sig_wait);
		ASSERT(current_process->sig_recv & sigs);
	}

	/* Signals found: clear them and return */
	current_process->sig_recv &= ~sigs;

	IRQ_ENABLE;
	return result;
}
コード例 #7
0
ファイル: proc.c プロジェクト: amdoolittle/APRS_Projects
/**
 * Terminate the current process
 */
void proc_exit(void)
{
	LOG_INFO("%p:%s", current_process, proc_currentName());

#if CONFIG_KERN_MONITOR
	monitor_remove(current_process);
#endif

	proc_forbid();
#if CONFIG_KERN_HEAP
	/*
	 * Set the task as zombie, its resources will be freed in proc_new() in
	 * a lazy way, when another process will be created.
	 */
	proc_addZombie(current_process);
#endif
	current_process = NULL;
	proc_permit();

	proc_switch();

	/* never reached */
	ASSERT(0);
}
コード例 #8
0
ファイル: sim.c プロジェクト: ckucera3/CS2200
/**
 * Opens the references file, reads in each line, and dispatches the commands
 * specified as appropriate to the CPU and OS modules.
 */
void sim_readdata(void) {
  FILE *fp;
  char buff[512];

  if ((fp = fopen(filename, "r")) == NULL) {
    PERROR(filename);
    exit(EXIT_FAILURE);
  }

  /* For each line in the file... */
  while (fgets(buff, sizeof(buff), fp) != NULL) {
    char *cmd, *arg1, *arg2, *arg3;
    int pid;
    vaddr_t addr;
    word_t val, val2;
    
    /* Parse command and possible arguments */
    cmd  = strtok(buff, WHITESPACE);
    arg1 = strtok(NULL, WHITESPACE);
    arg2 = strtok(NULL, WHITESPACE);
    arg3 = strtok(NULL, WHITESPACE);

    switch (cmd[0]) {

    /* Create a new process */
    case '@':
      pid = atoi(arg1);
      if (pid < max_jobs) {
        printf("Forking new process %s.  Assigning pid: %d.\n\n", arg2, pid);
        proc_fork(pid, arg2);
      } else {
        printf("Too many jobs, not forking new process!\n");
      }
      break;

    /* Load from a memory location */
    case 'l':
      pid = atoi(arg1);
      addr = atoi(arg2);
      val = atoi(arg3) % 256;
      if (pid >= max_jobs) {
        break;
      } else if (current == NULL || current->pid != pid) {
		printf("===================================================\n");
        printf("Switching to process: %s. Corresponding pid: %d.\n", proc_getname(pid), pid);
		printf("===================================================\n\n");
        proc_switch(pid);
      }
      val2 = mem_load(addr);
      printf("Value Loaded:  %d\n", val2);
      if (val2 != val) {
        printf(" ERROR! loaded value did not equal expected!\nValue Expected:  %d\n\n", val);
        /* XXX: Dump a mem image here and quit */
      } else {
        printf("Complete\n\n");
      }
      break;
      
    /* Store to a memory location */
    case 's':
      pid = atoi(arg1);
      addr = atoi(arg2);
      val = atoi(arg3) % 256;
      if (pid >= max_jobs) {
        break;
      } else if (current == NULL || current->pid != pid) {
		printf("===================================================\n");
        printf("Switching to process: %s. Corresponding pid: %d.\n", proc_getname(pid), pid);
		printf("===================================================\n\n");
        proc_switch(pid);
      }
      mem_store(addr, val);
      printf("Complete\n\n");

    /* Ignore other commands (for comments and the like */
    default:
      break;
    }
  }

  fclose(fp);
}