⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proc.c

📁 MINIX2.0操作系统源码 MINIX2.0操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
 */

  register struct proc *rp;	/* process to run */

  if ( (rp = rdy_head[TASK_Q]) != NIL_PROC) {
	proc_ptr = rp;
	return;
  }
  if ( (rp = rdy_head[SERVER_Q]) != NIL_PROC) {
	proc_ptr = rp;
	return;
  }
  if ( (rp = rdy_head[USER_Q]) != NIL_PROC) {
	proc_ptr = rp;
	bill_ptr = rp;
	return;
  }
  /* No one is ready.  Run the idle task.  The idle task might be made an
   * always-ready user task to avoid this special case.
   */
  bill_ptr = proc_ptr = proc_addr(IDLE);
}

/*===========================================================================*
 *				ready					     * 
 *===========================================================================*/
PRIVATE void ready(rp)
register struct proc *rp;	/* this process is now runnable */
{
/* Add 'rp' to the end of one of the queues of runnable processes. Three
 * queues are maintained:
 *   TASK_Q   - (highest priority) for runnable tasks
 *   SERVER_Q - (middle priority) for MM and FS only
 *   USER_Q   - (lowest priority) for user processes
 */

  if (istaskp(rp)) {
	if (rdy_head[TASK_Q] != NIL_PROC)
		/* Add to tail of nonempty queue. */
		rdy_tail[TASK_Q]->p_nextready = rp;
	else {
		proc_ptr =		/* run fresh task next */
		rdy_head[TASK_Q] = rp;	/* add to empty queue */
	}
	rdy_tail[TASK_Q] = rp;
	rp->p_nextready = NIL_PROC;	/* new entry has no successor */
	return;
  }
  if (!isuserp(rp)) {		/* others are similar */
	if (rdy_head[SERVER_Q] != NIL_PROC)
		rdy_tail[SERVER_Q]->p_nextready = rp;
	else
		rdy_head[SERVER_Q] = rp;
	rdy_tail[SERVER_Q] = rp;
	rp->p_nextready = NIL_PROC;
	return;
  }
#if (SHADOWING == 1)
  if (isshadowp(rp)) {		/* others are similar */
	if (rdy_head[SHADOW_Q] != NIL_PROC)
		rdy_tail[SHADOW_Q]->p_nextready = rp;
	else
		rdy_head[SHADOW_Q] = rp;
	rdy_tail[SHADOW_Q] = rp;
	rp->p_nextready = NIL_PROC;
	return;
  }
#endif
  if (rdy_head[USER_Q] == NIL_PROC)
	rdy_tail[USER_Q] = rp;
  rp->p_nextready = rdy_head[USER_Q];
  rdy_head[USER_Q] = rp;
/*
  if (rdy_head[USER_Q] != NIL_PROC)
	rdy_tail[USER_Q]->p_nextready = rp;
  else
	rdy_head[USER_Q] = rp;
  rdy_tail[USER_Q] = rp;
  rp->p_nextready = NIL_PROC;
*/
}

/*===========================================================================*
 *				unready					     * 
 *===========================================================================*/
PRIVATE void unready(rp)
register struct proc *rp;	/* this process is no longer runnable */
{
/* A process has blocked. */

  register struct proc *xp;
  register struct proc **qtail;  /* TASK_Q, SERVER_Q, or USER_Q rdy_tail */

  if (istaskp(rp)) {
	/* task stack still ok? */
	if (*rp->p_stguard != STACK_GUARD)
		panic("stack overrun by task", proc_number(rp));

	if ( (xp = rdy_head[TASK_Q]) == NIL_PROC) return;
	if (xp == rp) {
		/* Remove head of queue */
		rdy_head[TASK_Q] = xp->p_nextready;
		if (rp == proc_ptr) pick_proc();
		return;
	}
	qtail = &rdy_tail[TASK_Q];
  }
  else if (!isuserp(rp)) {
	if ( (xp = rdy_head[SERVER_Q]) == NIL_PROC) return;
	if (xp == rp) {
		rdy_head[SERVER_Q] = xp->p_nextready;
#if (CHIP == M68000)
		if (rp == proc_ptr)
#endif
		pick_proc();
		return;
	}
	qtail = &rdy_tail[SERVER_Q];
  } else
#if (SHADOWING == 1)
  if (isshadowp(rp)) {
	if ( (xp = rdy_head[SHADOW_Q]) == NIL_PROC) return;
	if (xp == rp) {
		rdy_head[SHADOW_Q] = xp->p_nextready;
		if (rp == proc_ptr)
			pick_proc();
		return;
	}
	qtail = &rdy_tail[SHADOW_Q];
  } else
#endif
  {
	if ( (xp = rdy_head[USER_Q]) == NIL_PROC) return;
	if (xp == rp) {
		rdy_head[USER_Q] = xp->p_nextready;
#if (CHIP == M68000)
		if (rp == proc_ptr)
#endif
		pick_proc();
		return;
	}
	qtail = &rdy_tail[USER_Q];
  }

  /* Search body of queue.  A process can be made unready even if it is
   * not running by being sent a signal that kills it.
   */
  while (xp->p_nextready != rp)
	if ( (xp = xp->p_nextready) == NIL_PROC) return;
  xp->p_nextready = xp->p_nextready->p_nextready;
  if (*qtail == rp) *qtail = xp;
}

/*===========================================================================*
 *				sched					     * 
 *===========================================================================*/
PRIVATE void sched()
{
/* The current process has run too long.  If another low priority (user)
 * process is runnable, put the current process on the end of the user queue,
 * possibly promoting another user to head of the queue.
 */

  if (rdy_head[USER_Q] == NIL_PROC) return;

  /* One or more user processes queued. */
  rdy_tail[USER_Q]->p_nextready = rdy_head[USER_Q];
  rdy_tail[USER_Q] = rdy_head[USER_Q];
  rdy_head[USER_Q] = rdy_head[USER_Q]->p_nextready;
  rdy_tail[USER_Q]->p_nextready = NIL_PROC;
  pick_proc();
}

/*==========================================================================*
 *				lock_mini_send				    *
 *==========================================================================*/
PUBLIC int lock_mini_send(caller_ptr, dest, m_ptr)
struct proc *caller_ptr;	/* who is trying to send a message? */
int dest;			/* to whom is message being sent? */
message *m_ptr;			/* pointer to message buffer */
{
/* Safe gateway to mini_send() for tasks. */

  int result;

  switching = TRUE;
  result = mini_send(caller_ptr, dest, m_ptr);
  switching = FALSE;
  return(result);
}

/*==========================================================================*
 *				lock_pick_proc				    *
 *==========================================================================*/
PUBLIC void lock_pick_proc()
{
/* Safe gateway to pick_proc() for tasks. */

  switching = TRUE;
  pick_proc();
  switching = FALSE;
}

/*==========================================================================*
 *				lock_ready				    *
 *==========================================================================*/
PUBLIC void lock_ready(rp)
struct proc *rp;		/* this process is now runnable */
{
/* Safe gateway to ready() for tasks. */

  switching = TRUE;
  ready(rp);
  switching = FALSE;
}

/*==========================================================================*
 *				lock_unready				    *
 *==========================================================================*/
PUBLIC void lock_unready(rp)
struct proc *rp;		/* this process is no longer runnable */
{
/* Safe gateway to unready() for tasks. */

  switching = TRUE;
  unready(rp);
  switching = FALSE;
}

/*==========================================================================*
 *				lock_sched				    *
 *==========================================================================*/
PUBLIC void lock_sched()
{
/* Safe gateway to sched() for tasks. */

  switching = TRUE;
  sched();
  switching = FALSE;
}

/*==========================================================================*
 *				unhold					    *
 *==========================================================================*/
PUBLIC void unhold()
{
/* Flush any held-up interrupts.  k_reenter must be 0.  held_head must not
 * be NIL_PROC.  Interrupts must be disabled.  They will be enabled but will
 * be disabled when this returns.
 */

  register struct proc *rp;	/* current head of held queue */

  if (switching) return;
  rp = held_head;
  do {
	if ( (held_head = rp->p_nextheld) == NIL_PROC) held_tail = NIL_PROC;
	rp->p_int_held = FALSE;
	unlock();		/* reduce latency; held queue may change! */
	interrupt(proc_number(rp));
	lock();			/* protect the held queue again */
  }
  while ( (rp = held_head) != NIL_PROC);
}

#if (CHIP == M68000)
/*==========================================================================*
 *				cp_mess					    *
 *==========================================================================*/
PRIVATE void cp_mess(src, src_p, src_m, dst_p, dst_m)
int src;			/* sender process */
register struct proc *src_p;	/* source proc entry */
message *src_m;			/* source message */
register struct proc *dst_p;	/* destination proc entry */
message *dst_m;			/* destination buffer */
{
#if (SHADOWING == 0)
  /* convert virtual address to physical address */
  /* The caller has already checked if all addresses are within bounds */
  
  src_m = (message *)((char *)src_m + (((phys_bytes)src_p->p_map[D].mem_phys
				- src_p->p_map[D].mem_vir) << CLICK_SHIFT));
  dst_m = (message *)((char *)dst_m + (((phys_bytes)dst_p->p_map[D].mem_phys
				- dst_p->p_map[D].mem_vir) << CLICK_SHIFT));
#else
  register phys_bytes correction;

  if (correction = src_p->p_shadow) {
	correction = (correction - src_p->p_map[D].mem_phys) << CLICK_SHIFT;
	src_m = (message *)((char *)src_m + correction);
  }
  if (correction = dst_p->p_shadow) {
	correction = (correction - dst_p->p_map[D].mem_phys) << CLICK_SHIFT;
	dst_m = (message *)((char *)dst_m + correction);
  }
#endif
#ifdef NEEDFSTRUCOPY
  phys_copy(src_m,dst_m,(phys_bytes) sizeof(message));
#else
  *dst_m = *src_m;
#endif
  dst_m->m_source = src;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -