⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kern.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
字号:
/* * This program simulates a first-order, type-II phase-lock loop using * actual code segments from modified kernel distributions for SunOS, * Ultrix and OSF/1 kernels. These segments do not use any licensed code. */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include <ctype.h>#include <math.h>#include <sys/time.h>#ifdef HAVE_TIMEX_H# include "timex.h"#endif/* * Phase-lock loop definitions */#define HZ 100			/* timer interrupt frequency (Hz) */#define MAXPHASE 512000		/* max phase error (us) */#define MAXFREQ 200		/* max frequency error (ppm) */#define TAU 2			/* time constant (shift 0 - 6) */#define POLL 16			/* interval between updates (s) */#define MAXSEC 1200		/* max interval between updates (s) *//* * Function declarations */void hardupdate();void hardclock();void second_overflow();/* * Kernel variables */int tick;			/* timer interrupt period (us) */int fixtick;			/* amortization constant (ppm) */struct timeval timex;		/* ripoff of kernel time variable *//* * Phase-lock loop variables */int time_status = TIME_BAD;	/* clock synchronization status */long time_offset = 0;		/* time adjustment (us) */long time_constant = 0;		/* pll time constant */long time_tolerance = MAXFREQ;	/* frequency tolerance (ppm) */long time_precision = 1000000 / HZ; /* clock precision (us) */long time_maxerror = MAXPHASE;	/* maximum error (us) */long time_esterror = MAXPHASE;	/* estimated error (us) */long time_phase = 0;		/* phase offset (scaled us) */long time_freq = 0;		/* frequency offset (scaled ppm) */long time_adj = 0;		/* tick adjust (scaled 1 / HZ) */long time_reftime = 0;		/* time at last adjustment (s) *//* * Simulation variables */double timey = 0;		/* simulation time (us) */long timez = 0;			/* current error (us) */long poll_interval = 0;		/* poll counter *//* * Simulation test program */intmain(	int argc,	char *argv[]	){	tick = 1000000 / HZ;	fixtick = 1000000 % HZ;	timex.tv_sec = 0;	timex.tv_usec = MAXPHASE;	time_freq = 0;	time_constant = TAU;	printf("tick %d us, fixtick %d us\n", tick, fixtick);	printf("      time    offset      freq   _offset     _freq      _adj\n");	/*	 * Grind the loop until ^C	 */	while (1) {		timey += (double)(1000000) / HZ;		if (timey >= 1000000)		    timey -= 1000000;		hardclock();		if (timex.tv_usec >= 1000000) {			timex.tv_usec -= 1000000;			timex.tv_sec++;			second_overflow();			poll_interval++;			if (!(poll_interval % POLL)) {				timez = (long)timey - timex.tv_usec;				if (timez > 500000)				    timez -= 1000000;				if (timez < -500000)				    timez += 1000000;				hardupdate(timez);				printf("%10li%10li%10.2f  %08lx  %08lx  %08lx\n",				       timex.tv_sec, timez,				       (double)time_freq / (1 << SHIFT_KF),				       time_offset, time_freq, time_adj);			}		}	}}/* * This routine simulates the ntp_adjtime() call * * For default SHIFT_UPDATE = 12, offset is limited to +-512 ms, the * maximum interval between updates is 4096 s and the maximum frequency * offset is +-31.25 ms/s. */voidhardupdate(	long offset	){	long ltemp, mtemp;	time_offset = offset << SHIFT_UPDATE;	mtemp = timex.tv_sec - time_reftime;	time_reftime = timex.tv_sec;	if (mtemp > MAXSEC)	    mtemp = 0;	/* ugly multiply should be replaced */	if (offset < 0)	    time_freq -= (-offset * mtemp) >>		    (time_constant + time_constant);	else	    time_freq += (offset * mtemp) >>		    (time_constant + time_constant);	ltemp = time_tolerance << SHIFT_KF;	if (time_freq > ltemp)	    time_freq = ltemp;	else if (time_freq < -ltemp)	    time_freq = -ltemp;	if (time_status == TIME_BAD)	    time_status = TIME_OK;}/* * This routine simulates the timer interrupt */voidhardclock(void){	int ltemp, time_update;	time_update = tick;	/* computed by adjtime() */	time_phase += time_adj;	if (time_phase < -FINEUSEC) {		ltemp = -time_phase >> SHIFT_SCALE;		time_phase += ltemp << SHIFT_SCALE;		time_update -= ltemp;	}	else if (time_phase > FINEUSEC) {		ltemp = time_phase >> SHIFT_SCALE;		time_phase -= ltemp << SHIFT_SCALE;		time_update += ltemp;	}	timex.tv_usec += time_update;}/* * This routine simulates the overflow of the microsecond field * * With SHIFT_SCALE = 23, the maximum frequency adjustment is +-256 us * per tick, or 25.6 ms/s at a clock frequency of 100 Hz. The time * contribution is shifted right a minimum of two bits, while the frequency * contribution is a right shift. Thus, overflow is prevented if the * frequency contribution is limited to half the maximum or 15.625 ms/s. */voidsecond_overflow(void){	int ltemp;	time_maxerror += time_tolerance;	if (time_offset < 0) {		ltemp = -time_offset >>			(SHIFT_KG + time_constant);		time_offset += ltemp;		time_adj = -(ltemp <<			     (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE));	} else {		ltemp = time_offset >>			(SHIFT_KG + time_constant);		time_offset -= ltemp;		time_adj = ltemp <<			(SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);	}	if (time_freq < 0)	    time_adj -= -time_freq >> (SHIFT_KF + SHIFT_HZ - SHIFT_SCALE);	else	    time_adj += time_freq >> (SHIFT_KF + SHIFT_HZ - SHIFT_SCALE);	time_adj += fixtick << (SHIFT_SCALE - SHIFT_HZ);	/* ugly divide should be replaced */	if (timex.tv_sec % 86400 == 0) {		switch (time_status) {		    case TIME_INS:			timex.tv_sec--; /* !! */			time_status = TIME_OOP;			break;		    case TIME_DEL:			timex.tv_sec++;			time_status = TIME_OK;			break;		    case TIME_OOP:			time_status = TIME_OK;			break;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -