Coherent4.2.10/coh.386/misc.c

Compare this file to the similar file:
Show the results in this format:

/* $Header: /ker/coh.386/RCS/misc.c,v 2.5 93/10/29 00:55:20 nigel Exp Locker: nigel $ */
/*
 * $Log:	misc.c,v $
 * Revision 2.5  93/10/29  00:55:20  nigel
 * R98 (aka 4.2 Beta) prior to removing System Global memory
 * 
 * Revision 2.4  93/08/19  03:26:34  nigel
 * Nigel's r83 (Stylistic cleanup)
 */

#include <kernel/proc_lib.h>
#include <sys/cmn_err.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/cred.h>
#include <stddef.h>

#define	_KERNEL		1

#include <sys/uproc.h>
#include <sys/proc.h>
#include <sys/acct.h>
#include <sys/ino.h>


/*
 * Make sure we are the super user.
 */

int
super ()
{
	if (SELF->p_credp->cr_uid != 0) {
		set_user_error (EPERM);
		return 0;
	}
	u.u_flag |= ASU;
	return 1;
}


/*
 * Make sure we are the given 'uid' or the super user.
 */

int
owner (uid)
n_uid_t		uid;
{
	if (SELF->p_credp->cr_uid == uid)
		return 1;
	return super ();
}


/*
 * Use printf to generate a call-trace.
 */

void
backtrace (dummy)
long		dummy;
{
	long	      *	bp = (& dummy) - 2;

	cmn_err (CE_CONT, "Call backtrace: ");
	do {
		bp = (long *) * bp;
		cmn_err (CE_CONT, " -> %x", * (bp + 1));
	} while (* bp != NULL);
	cmn_err (CE_CONT, "\n");
}

/*
 * Panic.
 */

void
panic(a1)
char *a1;
{
	static panflag;

	sphi ();

	if (panflag ++ == 0) {
		printf ("Panic: %r", &a1);
		putchar ('\n');
		backtrace ();
		for (;;)
			/* DO NOTHING */ ;
		usync ();
	}
	halt ();

	-- panflag;
}

/*
 * Print a message from a device driver.
 */

void
devmsg(dev, a1)
dev_t dev;
char *a1;
{
	printf ("(%d,%d): %r", major(dev), minor(dev), &a1);
	printf ("\n");
}

/*
 * Wait up to "ticks" clock ticks for an event to occur.
 * A tick is 1/HZ seconds (10 msec).
 * Works whether interrupts are enabled or not.
 * Busy-waits the system.
 * The event occurs when (*fn)() returns a nonzero value.
 * If fn is NULL, delay unconditionally.
 *
 * Return 0 if timeout occurred, 1 if the desired event occurred.
 */

#define THRESH (T0_RATE/2)	/* half of 11932 */

int
busyWait(fn, ticks)
int (*fn)();
int ticks;
{
	/*
	 * p0, p1 are 0 if in low half of counting cycle, else 1.
	 * flips counts the number of changes from low-to-high or vice versa.
	 * tickCt counts the number of clock ticks at rate HZ.
	 */

	int tickCt = 0;
	int flips = 0;
	int p0 = read_t0 () < THRESH ? 0 : 1;
	int p1;

	for (;;) {
		if (fn && (* fn) ())
			return 1;

		/* did we change halves of counter cycle? */
		p1 = read_t0 () < THRESH ? 0 : 1;
		if (p0 != p1) {
			p0 = p1;
			flips ++;

			/* two phase flips make a tick */
			if (flips >= 2) {
				flips = 0;
				tickCt ++;
				if (tickCt > ticks)
					return 0;
			}
		}
		
	}
}

/*
 * busyWait2() has finer granularity than busyWait().
 *
 * Wait up to "counts" clock counts for an event to occur.
 * A count is 1/(11932*HZ) seconds (about 0.84 usec).
 * Works whether interrupts are enabled or not.
 * Busy-waits the system.
 * The event occurs when (*fn)() returns a nonzero value.
 * If fn is NULL, delay unconditionally.
 *
 * Return 0 if timeout occurred, 1 if the desired event occurred.
 */

int
busyWait2 (fn, counts)
int (*fn)();
unsigned int counts;
{
	/*
	 * ct0 is previous t0 reading, ct1 is current reading.
	 * We have timer rollover when ct1 < ct0.
	 */

	unsigned int totCt = 0;
	unsigned int ct0 = read_t0 ();
	unsigned int ct1;

	for (;;) {
		if (fn && (* fn) ())
			return 1;

		ct1 = read_t0 ();
		if (ct1 > ct0) {
			/* no timer 0 rollover */
			totCt += ct1 - ct0;
		} else {
			/* timer 0 rollover */
			totCt += ct1 + T0_RATE - ct0;
		}
		if (totCt > counts)
			return 0;
		ct0 = ct1;
	}
}