[comp.sys.dec] Resetting the Clock

ane@hal.UUCP (06/19/87)

Background:
According to my VAX Hardware Handbook, the VAX-11/750 has two clocks,
a programmable realtime clock and a time-of-year clock.  The realtime
clock is based on a crystal oscillator with an accuracy of 0.01% and a
resolution of 1 microsecond.  This is the clock that UNIX 4.3 BSD uses
to keep track of time.  The time-of-year clock provides the correct
time to the system in the event of a power failure or other system
crash.

Here is the question:
How can I get the computer to reset the realtime clock using the 
time-of-year clock without taking down the system?

Aydin Edguer

WORK PHONE: 216-368-3970
USENET    : cbosgd!hal!ane  or {sun,decvax}!cwruecmp!hal!ane
INTERNET  : edguer@cwru.EDU

chris@mimsy.UUCP (06/19/87)

In article <132@hal.UUCP> ane@hal.UUCP (Aydin "Bif" Edguer) writes:
>How can I get the [Vax 11/750 running 4.3BSD] to reset the realtime
>clock using the time-of-year clock without taking down the system?

Without changing the kernel, you cannot.  But why would you want to?
4.3BSD resets the time-of-year clock to track the realtime clock,
since that is the one you adjust with `adjtime' and `date'.

Incidentally, here is an adjtime command for 4.3BSD.

#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>

struct	timeval delta, olddelta;

main(argc, argv)
	int argc;
	char **argv;
{

	if (argc < 2) {
		timerclear(&delta);
		if (adjtime(&delta, &olddelta))
			error(1, -1, "adjtime");
		if (adjtime(&olddelta, &delta)) {
			showdelta("current adjustment", &olddelta);
			error(1, -1, "adjtime (readjust)");
		}
		showdelta("current adjustment", &olddelta);
		exit(0);
	}
	if (convtime(&delta, argv[1]))
		error(1, 0, "invalid time spec %s (should be sec.usec)\n",
			argv[1]);
	if (adjtime(&delta, &olddelta))
		error(1, -1, "adjtime");
	showdelta("old adjustment", &olddelta);
	showdelta("new adjustment", &delta);
	exit(0);
}

convtime(tvp, s)
	register struct timeval *tvp;
	register char *s;
{
	char *usec, *index();
	int neg = 0;

	if (*s == '-') {
		neg++;
		s++;
	}
	usec = index(s, '.');
	if (usec != NULL) {
		*usec++ = 0;
		if (convone(&tvp->tv_usec, usec))
			return (-1);
		if (tvp->tv_usec > 999999)
			return (-1);
	} else
		tvp->tv_usec = 0;
	if (convone(&tvp->tv_sec, s))
		return (-1);
	if (neg) {
		tvp->tv_usec = -tvp->tv_usec;
		tvp->tv_sec = -tvp->tv_sec;
	}
	return (0);
}

convone(lp, s)
	long *lp;
	register char *s;
{
	register long l = 0;
	register int c;

	while ((c = *s++) != 0) {
		if (!isdigit(c))
			return (-1);
		l *= 10;
		if (l < 0)
			return (-1);
		l += c - '0';
		if (l < 0)
			return (-1);
	}
	*lp = l;
	return (0);
}

showdelta(what, tvp)
	char *what;
	struct timeval *tvp;
{
	char *p = "";

	if (tvp->tv_usec < 0) {
		tvp->tv_usec = -tvp->tv_usec;
		if (tvp->tv_sec == 0)
			p = "-";
	}
	printf("%s: %s%ld.%06ld seconds\n", what, p, tvp->tv_sec, tvp->tv_usec);
}

#include <varargs.h>

char *_argv0;			/* argv[0], set by C startup code */

/*
 * error - University of Maryland specific (sigh)
 *
 * Useful for printing error messages.  Will print the program name
 * and (optionally) the system error associated with the values in
 * <errno.h>.
 */
error(quit, e, fmt, va_alist)
	int quit;
	register int e;
	char *fmt;
	va_dcl
{
	extern char *sys_errlist[];
	extern int sys_nerr, errno;
	va_list l;
	register char *p = _argv0;

	if (e < 0)
		e = errno;
	(void) fflush(stdout);		/* somewhat gratuitous */
	if (p != NULL)
		(void) fprintf(stderr, "%s: ", p);
	(void) vfprintf(stderr, fmt, l);
	if (e > 0) {
		if (e < sys_nerr)
			(void) fprintf(stderr, ": %s", sys_errlist[e]);
		else
			(void) fprintf(stderr, ": unknown error number %d", e);
	}
	(void) putc('\n', stderr);
	(void) fflush(stderr);
	if (quit)
		exit(quit);
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	seismo!mimsy!chris

mouse@mcgill-vision.UUCP (der Mouse) (06/26/87)

In article <132@hal.UUCP>, ane@hal.UUCP (Aydin "Bif" Edguer) writes:
> According to my VAX Hardware Handbook, the VAX-11/750 has two clocks,
As does the 780, but not, I regret to have to inform you, MicroVAX-II.
(The uVAXII has a pale imitation of them; see below.)
> a programmable realtime clock and a time-of-year clock.

> How can I get the computer to reset the realtime clock using the
> time-of-year clock without taking down the system?

You already mentioned 4.3BSD (in text I deleted), so I assume that's
what you're running.  Answer:  you can't, not without kernel hacking.

The pale imitation mentioned above for the MicroVAX-II is that they
have a clock chip, presumably as accurate as any good digital watch,
for time-of-year.  They have something which interrupts every 10 ms for
an interval timer, in contrast to the big VAXen, on which the interrupt
rate is variable, and on which you can read the current count if you
need a really precise time.  WHY, WHY, couldn't they have provided a
real interval timer?  Or some way to access the time of year without
standing on your head?

					der Mouse

				(mouse@mcgill-vision.uucp)