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

📄 proc.c

📁 一个简单的操作系统minix的核心代码
💻 C
📖 第 1 页 / 共 2 页
字号:
07158	        return(OK);
07159	    }
07160	  }
07161	
07162	  /* No suitable message is available.  Block the process trying to receive. */
07163	  caller_ptr->p_getfrom = src;
07164	  caller_ptr->p_messbuf = m_ptr;
07165	  if (caller_ptr->p_flags == 0) unready(caller_ptr);
07166	  caller_ptr->p_flags |= RECEIVING;
07167	
07168	  /* If MM has just blocked and there are kernel signals pending, now is the
07169	   * time to tell MM about them, since it will be able to accept the message.
07170	   */
07171	  if (sig_procs > 0 && proc_number(caller_ptr) == MM_PROC_NR && src == ANY)
07172	        inform();
07173	  return(OK);
07174	}
	
07176	/*===========================================================================*
07177	 *                              pick_proc                                    * 
07178	 *===========================================================================*/
07179	PRIVATE void pick_proc()
07180	{
07181	/* Decide who to run now.  A new process is selected by setting 'proc_ptr'.
07182	 * When a fresh user (or idle) process is selected, record it in 'bill_ptr',
07183	 * so the clock task can tell who to bill for system time.
07184	 */
07185	
07186	  register struct proc *rp;     /* process to run */
07187	
07188	  if ( (rp = rdy_head[TASK_Q]) != NIL_PROC) {
07189	        proc_ptr = rp;
07190	        return;
07191	  }
07192	  if ( (rp = rdy_head[SERVER_Q]) != NIL_PROC) {
07193	        proc_ptr = rp;
07194	        return;
07195	  }
07196	  if ( (rp = rdy_head[USER_Q]) != NIL_PROC) {
07197	        proc_ptr = rp;
07198	        bill_ptr = rp;
07199	        return;
07200	  }
07201	  /* No one is ready.  Run the idle task.  The idle task might be made an
07202	   * always-ready user task to avoid this special case.
07203	   */
07204	  bill_ptr = proc_ptr = proc_addr(IDLE);
07205	}
	
07207	/*===========================================================================*
07208	 *                              ready                                        * 
07209	 *===========================================================================*/
07210	PRIVATE void ready(rp)
07211	register struct proc *rp;       /* this process is now runnable */
07212	{
07213	/* Add 'rp' to the end of one of the queues of runnable processes. Three
07214	 * queues are maintained:
07215	 *   TASK_Q   - (highest priority) for runnable tasks
07216	 *   SERVER_Q - (middle priority) for MM and FS only
07217	 *   USER_Q   - (lowest priority) for user processes
07218	 */
07219	
07220	  if (istaskp(rp)) {
07221	        if (rdy_head[TASK_Q] != NIL_PROC)
07222	                /* Add to tail of nonempty queue. */
07223	                rdy_tail[TASK_Q]->p_nextready = rp;
07224	        else {
07225	                proc_ptr =              /* run fresh task next */
07226	                rdy_head[TASK_Q] = rp;  /* add to empty queue */
07227	        }
07228	        rdy_tail[TASK_Q] = rp;
07229	        rp->p_nextready = NIL_PROC;     /* new entry has no successor */
07230	        return;
07231	  }
07232	  if (!isuserp(rp)) {           /* others are similar */
07233	        if (rdy_head[SERVER_Q] != NIL_PROC)
07234	                rdy_tail[SERVER_Q]->p_nextready = rp;
07235	        else
07236	                rdy_head[SERVER_Q] = rp;
07237	        rdy_tail[SERVER_Q] = rp;
07238	        rp->p_nextready = NIL_PROC;
07239	        return;
07240	  }
07241	  if (rdy_head[USER_Q] == NIL_PROC)
07242	        rdy_tail[USER_Q] = rp;
07243	  rp->p_nextready = rdy_head[USER_Q];
07244	  rdy_head[USER_Q] = rp;
07245	/*
07246	  if (rdy_head[USER_Q] != NIL_PROC)
07247	        rdy_tail[USER_Q]->p_nextready = rp;
07248	  else
07249	        rdy_head[USER_Q] = rp;
07250	  rdy_tail[USER_Q] = rp;
07251	  rp->p_nextready = NIL_PROC;
07252	*/
07253	}
	
07255	/*===========================================================================*
07256	 *                              unready                                      * 
07257	 *===========================================================================*/
07258	PRIVATE void unready(rp)
07259	register struct proc *rp;       /* this process is no longer runnable */
07260	{
07261	/* A process has blocked. */
07262	
07263	  register struct proc *xp;
07264	  register struct proc **qtail;  /* TASK_Q, SERVER_Q, or USER_Q rdy_tail */
07265	
07266	  if (istaskp(rp)) {
07267	        /* task stack still ok? */
07268	        if (*rp->p_stguard != STACK_GUARD)
07269	                panic("stack overrun by task", proc_number(rp));
07270	
07271	        if ( (xp = rdy_head[TASK_Q]) == NIL_PROC) return;
07272	        if (xp == rp) {
07273	                /* Remove head of queue */
07274	                rdy_head[TASK_Q] = xp->p_nextready;
07275	                if (rp == proc_ptr) pick_proc();
07276	                return;
07277	        }
07278	        qtail = &rdy_tail[TASK_Q];
07279	  }
07280	  else if (!isuserp(rp)) {
07281	        if ( (xp = rdy_head[SERVER_Q]) == NIL_PROC) return;
07282	        if (xp == rp) {
07283	                rdy_head[SERVER_Q] = xp->p_nextready;
07284	                pick_proc();
07285	                return;
07286	        }
07287	        qtail = &rdy_tail[SERVER_Q];
07288	  } else
07289	  {
07290	        if ( (xp = rdy_head[USER_Q]) == NIL_PROC) return;
07291	        if (xp == rp) {
07292	                rdy_head[USER_Q] = xp->p_nextready;
07293	                pick_proc();
07294	                return;
07295	        }
07296	        qtail = &rdy_tail[USER_Q];
07297	  }
07298	
07299	  /* Search body of queue.  A process can be made unready even if it is
07300	   * not running by being sent a signal that kills it.
07301	   */
07302	  while (xp->p_nextready != rp)
07303	        if ( (xp = xp->p_nextready) == NIL_PROC) return;
07304	  xp->p_nextready = xp->p_nextready->p_nextready;
07305	  if (*qtail == rp) *qtail = xp;
07306	}
	
07308	/*===========================================================================*
07309	 *                              sched                                        * 
07310	 *===========================================================================*/
07311	PRIVATE void sched()
07312	{
07313	/* The current process has run too long.  If another low priority (user)
07314	 * process is runnable, put the current process on the end of the user queue,
07315	 * possibly promoting another user to head of the queue.
07316	 */
07317	
07318	  if (rdy_head[USER_Q] == NIL_PROC) return;
07319	
07320	  /* One or more user processes queued. */
07321	  rdy_tail[USER_Q]->p_nextready = rdy_head[USER_Q];
07322	  rdy_tail[USER_Q] = rdy_head[USER_Q];
07323	  rdy_head[USER_Q] = rdy_head[USER_Q]->p_nextready;
07324	  rdy_tail[USER_Q]->p_nextready = NIL_PROC;
07325	  pick_proc();
07326	}
	
07328	/*==========================================================================*
07329	 *                              lock_mini_send                              *
07330	 *==========================================================================*/
07331	PUBLIC int lock_mini_send(caller_ptr, dest, m_ptr)
07332	struct proc *caller_ptr;        /* who is trying to send a message? */
07333	int dest;                       /* to whom is message being sent? */
07334	message *m_ptr;                 /* pointer to message buffer */
07335	{
07336	/* Safe gateway to mini_send() for tasks. */
07337	
07338	  int result;
07339	
07340	  switching = TRUE;
07341	  result = mini_send(caller_ptr, dest, m_ptr);
07342	  switching = FALSE;
07343	  return(result);
07344	}
	
07346	/*==========================================================================*
07347	 *                              lock_pick_proc                              *
07348	 *==========================================================================*/
07349	PUBLIC void lock_pick_proc()
07350	{
07351	/* Safe gateway to pick_proc() for tasks. */
07352	
07353	  switching = TRUE;
07354	  pick_proc();
07355	  switching = FALSE;
07356	}
	
07358	/*==========================================================================*
07359	 *                              lock_ready                                  *
07360	 *==========================================================================*/
07361	PUBLIC void lock_ready(rp)
07362	struct proc *rp;                /* this process is now runnable */
07363	{
07364	/* Safe gateway to ready() for tasks. */
07365	
07366	  switching = TRUE;
07367	  ready(rp);
07368	  switching = FALSE;
07369	}
	
	
07372	/*==========================================================================*
07373	 *                              lock_unready                                *
07374	 *==========================================================================*/
07375	PUBLIC void lock_unready(rp)
07376	struct proc *rp;                /* this process is no longer runnable */
07377	{
07378	/* Safe gateway to unready() for tasks. */
07379	
07380	  switching = TRUE;
07381	  unready(rp);
07382	  switching = FALSE;
07383	}
	
07385	/*==========================================================================*
07386	 *                              lock_sched                                  *
07387	 *==========================================================================*/
07388	PUBLIC void lock_sched()
07389	{
07390	/* Safe gateway to sched() for tasks. */
07391	
07392	  switching = TRUE;
07393	  sched();
07394	  switching = FALSE;
07395	}
	
07397	/*==========================================================================*
07398	 *                              unhold                                      *
07399	 *==========================================================================*/
07400	PUBLIC void unhold()
07401	{
07402	/* Flush any held-up interrupts.  k_reenter must be 0.  held_head must not
07403	 * be NIL_PROC.  Interrupts must be disabled.  They will be enabled but will
07404	 * be disabled when this returns.
07405	 */
07406	
07407	  register struct proc *rp;     /* current head of held queue */
07408	
07409	  if (switching) return;
07410	  rp = held_head;
07411	  do {
07412	        if ( (held_head = rp->p_nextheld) == NIL_PROC) held_tail = NIL_PROC;
07413	        rp->p_int_held = FALSE;
07414	        unlock();               /* reduce latency; held queue may change! */
07415	        interrupt(proc_number(rp));
07416	        lock();                 /* protect the held queue again */
07417	  }
07418	  while ( (rp = held_head) != NIL_PROC);
07419	}

⌨️ 快捷键说明

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