gno/kern/gno/sleep.c

181 lines
4.3 KiB
C

/* $Id: sleep.c,v 1.1 1998/02/02 08:19:00 taubert Exp $ */
/*
* sleep.c
*
* sleep/wakeup handling routines
*/
extern void sleepbusy(void);
#ifndef KERNEL
#include "tests/testsleep.c"
#else
/* Building it into the kernel */
#pragma databank 1
#pragma optimize 79
/*segment "KERN2 ";*/
#include "proc.h"
#include "sys.h"
#include "kernel.h"
#include "/lang/orca/libraries/orcacdefs/stdio.h"
extern kernelStructPtr kp;
void dosleep(int pid)
{
kp->procTable[pid].processState = procSLEEP;
}
static void ready(int pid, int resch)
{
kp->procTable[pid].processState = procREADY;
if (resch) _resched();
}
#endif
typedef struct hash_entry {
unsigned pid; /* first pool entry on the wait list */
} hash_entry;
#define NUM_HVENTRIES 64
hash_entry hv_tab[NUM_HVENTRIES];
#if 0
void init_sleep_hash(void)
{
unsigned i;
for (i = 0; i < NUM_HVENTRIES; i++) {
hv_tab[i].vector = 0l;
hv_tab[i].pid = 0;
}
}
#endif
static unsigned hash_vector(unsigned long vec)
{
return (unsigned)(vec & 0x3F);
}
#define BUSY_FLAG ((byte *)0xE100FFl)
/* no longer used; this code is now in assembly language */
#if 0
int k_sleepold(unsigned long vec, int pri, int pid)
{
unsigned hv;
struct proc *p;
unsigned last;
unsigned cur;
byte oldBusy;
disableps();
hv = hash_vector(vec);
/*PROC->p_pri = pri;*/
/*PROC->p_waitvec = vec;*/
kp->procTable[pid].p_waitvec = vec;
/* Add this process to the END of this wait queue. This gives us a
FIFO action on the sleep queues */
last = hv_tab[hv].pid;
if (last == 0) {
hv_tab[hv].pid = pid;
} else {
while (kp->procTable[last].p_slink != 0) {
last = kp->procTable[last].p_slink;
}
kp->procTable[last].p_slink = pid;
}
kp->procTable[pid].p_slink = 0;
/*fprintf(stderr,"process %d going to sleep on vec %06lX\n",pid,vec);*/
dosleep(pid);
sleepbusy();
enableps();
}
#endif
/* Remove a single process from a sleep vector */
void k_remove(unsigned long vec, int pid, int readyq)
{
unsigned last = 0;
unsigned hv;
unsigned cur,link;
/*fprintf(stderr,"removing %d from %06lX\n",pid,vec);*/
disableps();
hv = hash_vector(vec);
cur = hv_tab[hv].pid;
while (cur != 0) {
link = kp->procTable[cur].p_slink;
if ((kp->procTable[cur].p_waitvec == vec) && (cur == pid)) {
/* Remove an item from the list. If the item is the first,
last == 0, and we set the hash vector to the follower
of the item */
if (last == 0) {
hv_tab[hv].pid = link;
}
/* Otherwise, the item is not the first; last != 0; we set
last's link to the current link, removing the curproc
from the list */
else {
kp->procTable[last].p_slink = kp->procTable[cur].p_slink;
last = cur;
}
if (readyq) ready(cur,0);
kp->procTable[cur].p_waitvec = 0l;
cur = link;
} else {
last = cur;
cur = link;
}
}
enableps();
/* if priority of a proc we awakened was higher than current priority
we need to _resched() */
}
/* Remove all processes from a sleep vector */
void k_wakeup(unsigned long vec)
{
unsigned last = 0;
unsigned hv;
unsigned cur,link;
/*fprintf(stderr,"waking up %06lX\n",vec);*/
disableps();
hv = hash_vector(vec);
cur = hv_tab[hv].pid;
while (cur != 0) {
link = kp->procTable[cur].p_slink;
if (kp->procTable[cur].p_waitvec == vec) {
/* Remove an item from the list. If the item is the first,
last == 0, and we set the hash vector to the follower
of the item */
if (last == 0) {
hv_tab[hv].pid = link;
}
/* Otherwise, the item is not the first; last != 0; we set
last's link to the current link, removing the curproc
from the list */
else {
kp->procTable[last].p_slink = kp->procTable[cur].p_slink;
last = cur;
}
ready(cur,0);
kp->procTable[cur].p_waitvec = 0l;
cur = link;
} else {
last = cur;
cur = link;
}
}
enableps();
/* if priority of a proc we awakened was higher than current priority
we need to _resched() */
}