You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
2.5 KiB

/* $Id: kern_synch.c,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/map.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/syslog.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
void idle __P((void));
void endtsleep __P((void *));
int
tsleep (chan, pri, mesg, timo)
void *chan;
int pri, timo;
char *mesg;
{
struct proc *p = curproc;
int catch = pri & PCATCH;
int sig = 0;
int s = splhigh ();
if (!chan) {
extern void _pmon_break(void);
printf("chan = 0!\n");
_pmon_break();
panic ("tsleep !chan");
}
if (p->p_wchan || !chan) {
panic ("tsleep");
}
p->p_wmesg = mesg;
p->p_wchan = chan;
p->p_pri = pri;
if (timo) {
timeout(endtsleep, (void *)p, timo);
}
if (catch) {
p->p_flag |= SSINTR;
if ((sig = CURSIG(p)) != 0) {
unsleep (p);
p->p_stat = SRUN;
goto resume;
}
}
p->p_stat = SSLEEP;
do {
idle ();
} while (p->p_wchan);
resume:
(void) splx (s);
p->p_flag &= ~SSINTR;
if (p->p_flag & STIMO) {
p->p_flag &= ~STIMO;
if (catch == 0 || sig == 0) {
return (EWOULDBLOCK);
}
}
if (timo) {
untimeout(endtsleep, (void *)p);
}
if (catch && (sig || CURSIG(p))) {
if (p->p_sigacts->ps_sigintr & sigmask(sig)) {
return (EINTR);
}
return (ERESTART);
}
return (0);
}
void
sleep (chan, pri)
void *chan;
int pri;
{
tsleep (chan, pri, 0, 0);
}
void
unsleep (p)
struct proc *p;
{
int s = splhigh ();
if (p->p_wchan) {
p->p_wchan = 0;
}
(void) splx (s);
}
void
setrunnable (p)
struct proc *p;
{
int s = splhigh();
if (p->p_stat != SSLEEP)
panic ("setrunnable");
unsleep (p);
p->p_stat = SRUN;
splx (s);
}
void
endtsleep(sp)
void *sp;
{
struct proc *p = sp;
int s = splhigh();
if (p->p_wchan) {
setrunnable(p);
p->p_flag |= STIMO;
}
splx(s);
}
void
wakeup (chan)
void *chan;
{
int s = splhigh ();
if (curproc && curproc->p_wchan == chan) {
unsleep (curproc);
}
(void) splx (s);
}
void
idle ()
{
int s = spl0 ();
scandevs ();
(void) splx (s);
}
#include "../net/netisr.h"
#define DOISR(isr, handler) \
if (netisr & (1 << (isr))) { \
netisr &= ~(1 << (isr)); \
handler (); \
}
void
softnet ()
{
#ifdef INET
DOISR(NETISR_ARP, arpintr);
DOISR(NETISR_IP, ipintr);
#endif
#ifdef NS
DOISR(NETISR_NS, nsintr);
#endif
#ifdef ISO
DOISR(NETISR_ISO, clnlintr);
#endif
#ifdef CCITT
DOISR(NETISR_CCITT, hdintr);
#endif
#ifdef NETISR_SCLK
DOISR(NETISR_SCLK, softclock);
#endif
}