plan 9 kernel history: overview | file list | diff list

1999/0430/alphapc/clock.c (diff list | history)

1999/0415/sys/src/9/alphapc/clock.c:4,91999/0429/sys/src/9/alphapc/clock.c:4,10 (short | long)
1999/0415    
#include	"dat.h" 
#include	"fns.h" 
#include	"io.h" 
1999/0429    
#include	"axp.h" 
1999/0415    
 
#include	"ureg.h" 
 
1999/0415/sys/src/9/alphapc/clock.c:34,901999/0429/sys/src/9/alphapc/clock.c:35,103
1999/0415    
	iunlock(&clock0lock); 
} 
 
                 
/* 
 *  delay for l milliseconds more or less.  delayloop is set by 
 *  clockinit() to match the actual CPU speed. 
 */ 
void 
delay(int l) 
1999/0429    
clockinit(void) 
1999/0415    
{ 
	ulong i, j; 
1999/0429    
} 
1999/0415    
 
	j = m->delayloop; 
	while(l-- > 0) 
		for(i=0; i < j; i++) 
			; 
1999/0429    
uvlong 
cycletimer(void) 
{ 
	ulong pcc; 
 
	pcc = rpcc(nil) & 0xFFFFFFFF; 
	if(m->cpuhz == 0){ 
		/* 
		 * pcclast is needed to detect wraparound of 
		 * the cycle timer which is only 32-bits. 
		 * m->cpuhz is set from the info passed from 
		 * the firmware. 
		 * This could be in clockinit if can 
		 * guarantee no wraparound between then and now. 
		 * 
		 * All the clock stuff needs work. 
		 */ 
		m->cpuhz = hwrpb->cfreq; 
		m->pcclast = pcc; 
	} 
	if(pcc < m->pcclast) 
		m->fastclock += 0x100000000LL; 
	m->fastclock += pcc; 
	m->pcclast = pcc; 
 
	return MACHP(0)->fastclock; 
1999/0415    
} 
 
void 
microdelay(int l) 
1999/0429    
vlong 
fastticks(uvlong* hz) 
1999/0415    
{ 
	ulong i, j; 
1999/0429    
	uvlong ticks; 
	int x; 
1999/0415    
 
//	j = m->delayloop/1000; 
j = 10000; 
	while(l-- > 0) 
		for(i=0; i < j; i++) 
			; 
1999/0429    
	x = splhi(); 
	ticks = cycletimer(); 
	splx(x); 
 
	if(hz) 
		*hz = m->cpuhz; 
 
	return (vlong)ticks; 
1999/0415    
} 
 
void 
clockinit(void) 
1999/0429    
microdelay(int us) 
1999/0415    
{ 
m->delayloop = 250*1000;	/* BUG */ 
#ifdef	NOTYET 
	long x; 
1999/0429    
	uvlong eot; 
1999/0415    
 
	m->delayloop = m->speed*100; 
	do { 
		x = rdcount(); 
		delay(10); 
		x = rdcount() - x; 
	} while(x < 0); 
1999/0429    
	eot = cycletimer() + (m->cpuhz/1000000)*us; 
	while(cycletimer() < eot) 
		; 
} 
1999/0415    
 
	/* 
	 *  fix count 
	 */ 
	m->delayloop = (m->delayloop*m->speed*1000*10)/x; 
	if(m->delayloop == 0) 
		m->delayloop = 1; 
                 
/*	wrcompare(rdcount()+(m->speed*1000000)/HZ); */ 
#endif 
1999/0429    
void 
/*milli*/delay(int ms) 
{ 
	microdelay(ms*1000); 
1999/0415    
} 
 
void 
1999/0415/sys/src/9/alphapc/clock.c:135,1461999/0429/sys/src/9/alphapc/clock.c:148,151
1999/0415    
		(*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); 
		segclock(ur->pc); 
	} 
} 
                 
vlong 
fastticks(uvlong *hz) 
{ 
	if (hz) 
		*hz = 100; 
	return m->ticks; 
} 
1999/0429/sys/src/9/alphapc/clock.c:44,491999/0430/sys/src/9/alphapc/clock.c:44,50 (short | long)
1999/0429    
cycletimer(void) 
{ 
	ulong pcc; 
1999/0430    
	vlong delta; 
1999/0429    
 
	pcc = rpcc(nil) & 0xFFFFFFFF; 
	if(m->cpuhz == 0){ 
1999/0429/sys/src/9/alphapc/clock.c:60,691999/0430/sys/src/9/alphapc/clock.c:61,71
1999/0429    
		m->cpuhz = hwrpb->cfreq; 
		m->pcclast = pcc; 
	} 
	if(pcc < m->pcclast) 
		m->fastclock += 0x100000000LL; 
	m->fastclock += pcc; 
1999/0430    
	delta = pcc - m->pcclast; 
	if(delta < 0) 
		delta += 0x100000000LL; 
1999/0429    
	m->pcclast = pcc; 
1999/0430    
	m->fastclock += delta; 
1999/0429    
 
	return MACHP(0)->fastclock; 
1999/0415    
} 
1999/0429/sys/src/9/alphapc/clock.c:106,1111999/0430/sys/src/9/alphapc/clock.c:108,114
1999/0415    
	Clock0link *lp; 
	static int count; 
 
1999/0430    
	cycletimer(); 
1999/0415    
	/* HZ == 100, timer == 1024Hz.  error < 1ms */ 
	count += 100; 
	if (count < 1024) 
1999/0430/sys/src/9/alphapc/clock.c:91,981999/0501/sys/src/9/alphapc/clock.c:91,98 (short | long)
1999/0415    
{ 
1999/0429    
	uvlong eot; 
1999/0415    
 
1999/0429    
	eot = cycletimer() + (m->cpuhz/1000000)*us; 
	while(cycletimer() < eot) 
1999/0501    
	eot = fastticks(nil) + (m->cpuhz/1000000)*us; 
	while(fastticks(nil) < eot) 
1999/0429    
		; 
} 
1999/0415    
 
1999/0501/sys/src/9/alphapc/clock.c:5,412001/0727/sys/src/9/alphapc/clock.c:5,13 (short | long)
1999/0415    
#include	"fns.h" 
#include	"io.h" 
1999/0429    
#include	"axp.h" 
1999/0415    
                 
#include	"ureg.h" 
 
void (*kproftimer)(ulong); 
                 
typedef struct Clock0link Clock0link; 
typedef struct Clock0link { 
	void		(*clock)(void); 
	Clock0link*	link; 
} Clock0link; 
                 
static Clock0link *clock0link; 
static Lock clock0lock; 
                 
void 
addclock0link(void (*clock)(void)) 
{ 
	Clock0link *lp; 
                 
	if((lp = malloc(sizeof(Clock0link))) == 0){ 
		print("addclock0link: too many links\n"); 
		return; 
	} 
	ilock(&clock0lock); 
	lp->clock = clock; 
	lp->link = clock0link; 
	clock0link = lp; 
	iunlock(&clock0lock); 
} 
                 
void 
1999/0429    
clockinit(void) 
1999/0415    
{ 
1999/0429    
} 
1999/0501/sys/src/9/alphapc/clock.c:97,1142001/0727/sys/src/9/alphapc/clock.c:69,86
1999/0429    
} 
1999/0415    
 
1999/0429    
void 
/*milli*/delay(int ms) 
2001/0727    
delay(int millisecs) 
1999/0429    
{ 
	microdelay(ms*1000); 
2001/0727    
	microdelay(millisecs*1000); 
1999/0415    
} 
 
void 
clock(Ureg *ur) 
2001/0727    
clock(Ureg *ureg) 
1999/0415    
{ 
	Clock0link *lp; 
	static int count; 
 
1999/0430    
	cycletimer(); 
2001/0727    
 
1999/0415    
	/* HZ == 100, timer == 1024Hz.  error < 1ms */ 
	count += 100; 
	if (count < 1024) 
1999/0501/sys/src/9/alphapc/clock.c:115,1542001/0727/sys/src/9/alphapc/clock.c:87,91
1999/0415    
		return; 
	count -= 1024; 
 
	m->ticks++; 
	if(m->proc) 
		m->proc->pc = ur->pc; 
                 
	accounttime(); 
                 
	if(kproftimer != nil) 
		kproftimer(ur->pc); 
                 
	if((active.machs&(1<<m->machno)) == 0) 
		return; 
                 
	if(active.exiting && (active.machs & (1<<m->machno))) { 
		print("someone's exiting\n"); 
		exit(0); 
	} 
                 
	checkalarms(); 
	if(m->machno == 0){ 
		lock(&clock0lock); 
		for(lp = clock0link; lp; lp = lp->link) 
			lp->clock(); 
		unlock(&clock0lock); 
	} 
                 
	if(up == 0 || up->state != Running) 
		return; 
                 
	if(anyready()) 
		sched(); 
                 
	/* user profiling clock */ 
	if(ur->status & UMODE) { 
		(*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); 
		segclock(ur->pc); 
	} 
2001/0727    
	portclock(ureg); 
1999/0415    
} 
2001/0727/sys/src/9/alphapc/clock.c:89,912001/1023/sys/src/9/alphapc/clock.c:89,104 (short | long)
1999/0415    
 
2001/0727    
	portclock(ureg); 
1999/0415    
} 
2001/1023    
 
ulong 
TK2MS(ulong ticks) 
{ 
	uvlong t, hz; 
 
	t = ticks; 
	hz = HZ; 
	t *= 1000L; 
	t = t/hz; 
	ticks = t; 
	return ticks; 
} 
2001/1023/sys/src/9/alphapc/clock.c:42,482002/0410/sys/src/9/alphapc/clock.c:42,48 (short | long)
1999/0429    
	return MACHP(0)->fastclock; 
1999/0415    
} 
 
1999/0429    
vlong 
2002/0410    
uvlong 
1999/0429    
fastticks(uvlong* hz) 
1999/0415    
{ 
1999/0429    
	uvlong ticks; 
2001/1023/sys/src/9/alphapc/clock.c:55,642002/0410/sys/src/9/alphapc/clock.c:55,69
1999/0429    
	if(hz) 
		*hz = m->cpuhz; 
 
	return (vlong)ticks; 
2002/0410    
	return ticks; 
1999/0415    
} 
 
void 
2002/0410    
timerset(uvlong) 
{ 
} 
 
void 
1999/0429    
microdelay(int us) 
1999/0415    
{ 
1999/0429    
	uvlong eot; 
2001/1023/sys/src/9/alphapc/clock.c:87,932002/0410/sys/src/9/alphapc/clock.c:92,98
1999/0415    
		return; 
	count -= 1024; 
 
2001/0727    
	portclock(ureg); 
2002/0410    
	timerintr(ureg, 0); 
1999/0415    
} 
2001/1023    
 
ulong 
2002/0410/sys/src/9/alphapc/clock.c:94,1092002/0710/sys/src/9/alphapc/clock.c:94,96 (short | long)
1999/0415    
 
2002/0410    
	timerintr(ureg, 0); 
1999/0415    
} 
2001/1023    
                 
ulong 
TK2MS(ulong ticks) 
{ 
	uvlong t, hz; 
                 
	t = ticks; 
	hz = HZ; 
	t *= 1000L; 
	t = t/hz; 
	ticks = t; 
	return ticks; 
} 
2002/0710/sys/src/9/alphapc/clock.c:58,632002/0822/sys/src/9/alphapc/clock.c:58,73 (short | long)
2002/0410    
	return ticks; 
1999/0415    
} 
 
2002/0822    
/*   
 *  performance measurement ticks.  must be low overhead. 
 *  doesn't have to count over a second. 
 */ 
ulong 
perfticks(void) 
{ 
	return rpcc(nil); 
} 
 
1999/0415    
void 
2002/0410    
timerset(uvlong) 
{ 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)