📄 proc.c
字号:
*/
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 + -