コード例 #1
0
void G1PageBasedVirtualSpace::initialize_with_page_size(ReservedSpace rs, size_t used_size, size_t page_size) {
  guarantee(rs.is_reserved(), "Given reserved space must have been reserved already.");

  vmassert(_low_boundary == NULL, "VirtualSpace already initialized");
  vmassert(page_size > 0, "Page size must be non-zero.");

  guarantee(is_ptr_aligned(rs.base(), page_size),
            "Reserved space base " PTR_FORMAT " is not aligned to requested page size " SIZE_FORMAT, p2i(rs.base()), page_size);
  guarantee(is_size_aligned(used_size, os::vm_page_size()),
            "Given used reserved space size needs to be OS page size aligned (%d bytes) but is " SIZE_FORMAT, os::vm_page_size(), used_size);
  guarantee(used_size <= rs.size(),
            "Used size of reserved space " SIZE_FORMAT " bytes is smaller than reservation at " SIZE_FORMAT " bytes", used_size, rs.size());
  guarantee(is_size_aligned(rs.size(), page_size),
            "Expected that the virtual space is size aligned, but " SIZE_FORMAT " is not aligned to page size " SIZE_FORMAT, rs.size(), page_size);

  _low_boundary  = rs.base();
  _high_boundary = _low_boundary + used_size;

  _special = rs.special();
  _executable = rs.executable();

  _page_size = page_size;

  vmassert(_committed.size() == 0, "virtual space initialized more than once");
  BitMap::idx_t size_in_pages = rs.size() / page_size;
  _committed.initialize(size_in_pages);
  if (_special) {
    _dirty.initialize(size_in_pages);
  }

  _tail_size = used_size % _page_size;
}
コード例 #2
0
ファイル: proc.c プロジェクト: egall/OS-code
/*===========================================================================*
 *				schedcheck				     * 
 *===========================================================================*/
PUBLIC struct proc * schedcheck(void)
{
	/* This function is called an instant before proc_ptr is
	 * to be scheduled again.
	 */
  	NOREC_ENTER(schedch);
	vmassert(intr_disabled());

	/*
	 * if the current process is still runnable check the misc flags and let
	 * it run unless it becomes not runnable in the meantime
	 */
	if (proc_is_runnable(proc_ptr))
		goto check_misc_flags;

	/*
	 * if a process becomes not runnable while handling the misc flags, we
	 * need to pick a new one here and start from scratch. Also if the
	 * current process wasn' runnable, we pick a new one here
	 */
not_runnable_pick_new:
	if (proc_is_preempted(proc_ptr)) {
		proc_ptr->p_rts_flags &= ~RTS_PREEMPTED;
		if (proc_is_runnable(proc_ptr))
			enqueue_head(proc_ptr);
	}
	/* this enqueues the process again */
	if (proc_no_quantum(proc_ptr))
		RTS_UNSET(proc_ptr, RTS_NO_QUANTUM);

	/*
	 * if we have no process to run, set IDLE as the current process for
	 * time accounting and put the cpu in and idle state. After the next
	 * timer interrupt the execution resumes here and we can pick another
	 * process. If there is still nothing runnable we "schedule" IDLE again
	 */
	while( !(proc_ptr = pick_proc())) {
		proc_ptr = proc_addr(IDLE);
		if (priv(proc_ptr)->s_flags & BILLABLE)
			bill_ptr = proc_ptr;
		idle();
	}

check_misc_flags:

	vmassert(proc_ptr);
	vmassert(proc_is_runnable(proc_ptr));
	while (proc_ptr->p_misc_flags &
		(MF_DELIVERMSG | MF_SC_DEFER | MF_SC_TRACE | MF_SC_ACTIVE)) {

		vmassert(proc_is_runnable(proc_ptr));
		if (proc_ptr->p_misc_flags & MF_DELIVERMSG) {
			TRACE(VF_SCHEDULING, printf("delivering to %s / %d\n",
				proc_ptr->p_name, proc_ptr->p_endpoint););
			if(delivermsg(proc_ptr) == VMSUSPEND) {
				TRACE(VF_SCHEDULING,
					printf("suspending %s / %d\n",
					proc_ptr->p_name,
					proc_ptr->p_endpoint););
コード例 #3
0
void G1PageBasedVirtualSpace::commit_preferred_pages(size_t start, size_t num_pages) {
  vmassert(num_pages > 0, "No full pages to commit");
  vmassert(start + num_pages <= _committed.size(),
           "Tried to commit area from page " SIZE_FORMAT " to page " SIZE_FORMAT " "
           "that is outside of managed space of " SIZE_FORMAT " pages",
           start, start + num_pages, _committed.size());

  char* start_addr = page_start(start);
  size_t size = num_pages * _page_size;

  os::commit_memory_or_exit(start_addr, size, _page_size, _executable,
                            err_msg("Failed to commit area from " PTR_FORMAT " to " PTR_FORMAT " of length " SIZE_FORMAT ".",
                            p2i(start_addr), p2i(start_addr + size), size));
}
コード例 #4
0
ファイル: debug.cpp プロジェクト: wei-tang/JVM
void controlled_crash(int how) {
  if (how == 0) return;

  // If asserts are disabled, use the corresponding guarantee instead.
  NOT_DEBUG(if (how <= 2) how += 2);

  const char* const str = "hello";
  const size_t      num = (size_t)os::vm_page_size();

  const char* const eol = os::line_separator();
  const char* const msg = "this message should be truncated during formatting";
  char * const dataPtr = NULL;  // bad data pointer
  const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer

  // Keep this in sync with test/runtime/6888954/vmerrors.sh.
  switch (how) {
    case  1: vmassert(str == NULL, "expected null");
    case  2: vmassert(num == 1023 && *str == 'X',
                      err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
    case  3: guarantee(str == NULL, "expected null");
    case  4: guarantee(num == 1023 && *str == 'X',
                       err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
    case  5: fatal("expected null");
    case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
    case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
                           "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
                           "%s%s#    %s%s#    %s%s#    %s%s#    %s",
                           msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
                           msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
                           msg, eol, msg, eol, msg, eol, msg, eol, msg));
    case  8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate");
    case  9: ShouldNotCallThis();
    case 10: ShouldNotReachHere();
    case 11: Unimplemented();
    // There's no guarantee the bad data pointer will crash us
    // so "break" out to the ShouldNotReachHere().
    case 12: *dataPtr = '\0'; break;
    // There's no guarantee the bad function pointer will crash us
    // so "break" out to the ShouldNotReachHere().
    case 13: (*funcPtr)(); break;
    case 14: crash_with_segfault(); break;
    case 15: crash_with_sigfpe(); break;

    default: tty->print_cr("ERROR: %d: unexpected test_num value.", how);
  }
  ShouldNotReachHere();
}
コード例 #5
0
void G1PageBasedVirtualSpace::commit_tail() {
  vmassert(_tail_size > 0, "The size of the tail area must be > 0 when reaching here");

  char* const aligned_end_address = (char*)align_ptr_down(_high_boundary, _page_size);
  os::commit_memory_or_exit(aligned_end_address, _tail_size, os::vm_page_size(), _executable,
                            err_msg("Failed to commit tail area from " PTR_FORMAT " to " PTR_FORMAT " of length " SIZE_FORMAT ".",
                            p2i(aligned_end_address), p2i(_high_boundary), _tail_size));
}
コード例 #6
0
ファイル: proc.c プロジェクト: egall/OS-code
/*===========================================================================*
 *				QueueMess				     * 
 *===========================================================================*/
PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst)
{
	int k;
	phys_bytes addr;
	NOREC_ENTER(queuemess);
	/* Queue a message from the src process (in memory) to the dst
	 * process (using dst process table entry). Do actual copy to
	 * kernel here; it's an error if the copy fails into kernel.
	 */
	vmassert(!(dst->p_misc_flags & MF_DELIVERMSG));	
	vmassert(dst->p_delivermsg_lin);
	vmassert(isokendpt(ep, &k));

#if 0
	if(INMEMORY(dst)) {
		PHYS_COPY_CATCH(msg_lin, dst->p_delivermsg_lin,
			sizeof(message), addr);
		if(!addr) {
			PHYS_COPY_CATCH(vir2phys(&ep), dst->p_delivermsg_lin,
				sizeof(ep), addr);
			if(!addr) {
				NOREC_RETURN(queuemess, OK);
			}
		}
	}
#endif

	PHYS_COPY_CATCH(msg_lin, vir2phys(&dst->p_delivermsg), sizeof(message), addr);
	if(addr) {
		NOREC_RETURN(queuemess, EFAULT);
	}

	dst->p_delivermsg.m_source = ep;
	dst->p_misc_flags |= MF_DELIVERMSG;

	NOREC_RETURN(queuemess, OK);
}
コード例 #7
0
ファイル: system.c プロジェクト: boostsup/minix3
/*===========================================================================*
 *				sys_task				     *
 *===========================================================================*/
PUBLIC void sys_task()
{
/* Main entry point of sys_task.  Get the message and dispatch on type. */
  static message m;
  register int result;
  register struct proc *caller_ptr;
  int s;
  int call_nr;
  int n = 0;

  /* Initialize the system task. */
  initialize();


  while (TRUE) {
      struct proc *restarting;

      restarting = vmrestart_check(&m);

      if(!restarting) {
        int r;
	/* Get work. Block and wait until a request message arrives. */
	if((r=receive(ANY, &m)) != OK)
		minix_panic("receive() failed", r);
      } 

      sys_call_code = (unsigned) m.m_type;
      call_nr = sys_call_code - KERNEL_CALL;	
      who_e = m.m_source;
      okendpt(who_e, &who_p);
      caller_ptr = proc_addr(who_p);

      /* See if the caller made a valid request and try to handle it. */
      if (call_nr < 0 || call_nr >= NR_SYS_CALLS) {	/* check call number */
	  kprintf("SYSTEM: illegal request %d from %d.\n",
		call_nr,m.m_source);
	  result = EBADREQUEST;			/* illegal message type */
      } 
      else if (!GET_BIT(priv(caller_ptr)->s_k_call_mask, call_nr)) {
	  result = ECALLDENIED;			/* illegal message type */
      }
      else {
          result = (*call_vec[call_nr])(&m); /* handle the system call */
      }

      if(result == VMSUSPEND) {
	/* Special case: message has to be saved for handling
	 * until VM tells us it's allowed. VM has been notified
	 * and we must wait for its reply to restart the call.
	 */
        vmassert(RTS_ISSET(caller_ptr, VMREQUEST));
	vmassert(caller_ptr->p_vmrequest.type == VMSTYPE_KERNELCALL);
	memcpy(&caller_ptr->p_vmrequest.saved.reqmsg, &m, sizeof(m));
      } else if (result != EDONTREPLY) {
	/* Send a reply, unless inhibited by a handler function.
	 * Use the kernel function lock_send() to prevent a system
	 * call trap.
	 */
		if(restarting) {
        		vmassert(!RTS_ISSET(restarting, VMREQUEST));
#if 0
        		vmassert(!RTS_ISSET(restarting, VMREQTARGET));
#endif
		}
		m.m_type = result;		/* report status of call */
		if(WILLRECEIVE(caller_ptr, SYSTEM)) {
		  if (OK != (s=lock_send(m.m_source, &m))) {
			kprintf("SYSTEM, reply to %d failed: %d\n",
			m.m_source, s);
		  }
		} else {
			kprintf("SYSTEM: not replying to %d; not ready\n", 
				caller_ptr->p_endpoint);
		}
	}
  }
}
コード例 #8
0
 BitMapView make_view(idx_t bits, bm_word_t value) {
   vmassert(BitMap::calc_size_in_words(bits) <= _words, "invalid request");
   STATIC_ASSERT(sizeof(bm_word_t) == sizeof(HeapWord));
   Copy::fill_to_aligned_words((HeapWord*)_memory, _words, value);
   return BitMapView(_memory, bits);
 }
コード例 #9
0
ファイル: memory.c プロジェクト: 7shi/minix-tools
/*===========================================================================*
 *				lin_lin_copy				     *
 *===========================================================================*/
PRIVATE int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr, 
	struct proc *dstproc, vir_bytes dstlinaddr, vir_bytes bytes)
{
	u32_t addr;
	int procslot;

	NOREC_ENTER(linlincopy);

	vmassert(vm_running);
	vmassert(nfreepdes >= 3);

	vmassert(ptproc);
	vmassert(proc_ptr);
	vmassert(read_cr3() == ptproc->p_seg.p_cr3);

	procslot = ptproc->p_nr;

	vmassert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES);

	while(bytes > 0) {
		phys_bytes srcptr, dstptr;
		vir_bytes chunk = bytes;
		int srcpde, dstpde;
		int srctype, dsttype;

		/* Set up 4MB ranges. */
		inusepde = NOPDE;
		CREATEPDE(srcproc, srcptr, srclinaddr, chunk, bytes, srcpde, srctype);
		CREATEPDE(dstproc, dstptr, dstlinaddr, chunk, bytes, dstpde, dsttype);

		/* Copy pages. */
		PHYS_COPY_CATCH(srcptr, dstptr, chunk, addr);

		DONEPDE(srcpde);
		DONEPDE(dstpde);

		if(addr) {
			/* If addr is nonzero, a page fault was caught. */

			if(addr >= srcptr && addr < (srcptr + chunk)) {
				WIPEPDE(srcpde);
				WIPEPDE(dstpde);
				NOREC_RETURN(linlincopy, EFAULT_SRC);
			}
			if(addr >= dstptr && addr < (dstptr + chunk)) {
				WIPEPDE(srcpde);
				WIPEPDE(dstpde);
				NOREC_RETURN(linlincopy, EFAULT_DST);
			}

			minix_panic("lin_lin_copy fault out of range", NO_NUM);

			/* Not reached. */
			NOREC_RETURN(linlincopy, EFAULT);
		}

		WIPEPDE(srcpde);
		WIPEPDE(dstpde);

		/* Update counter and addresses for next iteration, if any. */
		bytes -= chunk;
		srclinaddr += chunk;
		dstlinaddr += chunk;
	}

	NOREC_RETURN(linlincopy, OK);
}