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

📄 portclock.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "ureg.h"struct Timers{	Lock;	Timer	*head;};static Timers timers[MAXMACH];ulong intrcount[MAXMACH];ulong fcallcount[MAXMACH];static vlongtadd(Timers *tt, Timer *nt){	Timer *t, **last;	/* Called with tt locked */	assert(nt->tt == nil);	switch(nt->tmode){	default:		panic("timer");		break;	case Trelative:		if(nt->tns <= 0)			nt->tns = 1;		nt->twhen = fastticks(nil) + ns2fastticks(nt->tns);		break;	case Tperiodic:		assert(nt->tns >= 100000);	/* At least 100 µs period */		if(nt->twhen == 0){			/* look for another timer at same frequency for combining */			for(t = tt->head; t; t = t->tnext){				if(t->tmode == Tperiodic && t->tns == nt->tns)					break;			}			if (t)				nt->twhen = t->twhen;			else				nt->twhen = fastticks(nil);		}		nt->twhen += ns2fastticks(nt->tns);		break;	}	for(last = &tt->head; t = *last; last = &t->tnext){		if(t->twhen > nt->twhen)			break;	}	nt->tnext = *last;	*last = nt;	nt->tt = tt;	if(last == &tt->head)		return nt->twhen;	return 0;}static uvlongtdel(Timer *dt){	Timer *t, **last;	Timers *tt;	tt = dt->tt;	if (tt == nil)		return 0;	for(last = &tt->head; t = *last; last = &t->tnext){		if(t == dt){			assert(dt->tt);			dt->tt = nil;			*last = t->tnext;			break;		}	}	if(last == &tt->head && tt->head)		return tt->head->twhen;	return 0;}/* add or modify a timer */voidtimeradd(Timer *nt){	Timers *tt;	vlong when;	/* Must lock Timer struct before Timers struct */	ilock(nt);	if(tt = nt->tt){		ilock(tt);		tdel(nt);		iunlock(tt);	}	tt = &timers[m->machno];	ilock(tt);	when = tadd(tt, nt);	if(when)		timerset(when);	iunlock(tt);	iunlock(nt);}voidtimerdel(Timer *dt){	Timers *tt;	uvlong when;	ilock(dt);	if(tt = dt->tt){		ilock(tt);		when = tdel(dt);		if(when && tt == &timers[m->machno])			timerset(tt->head->twhen);		iunlock(tt);	}	iunlock(dt);}voidhzclock(Ureg *ur){	m->ticks++;	if(m->proc)		m->proc->pc = ur->pc;	if(m->flushmmu){		if(up)			flushmmu();		m->flushmmu = 0;	}	accounttime();	kmapinval();	if(kproftimer != nil)		kproftimer(ur->pc);	if((active.machs&(1<<m->machno)) == 0)		return;	if(active.exiting) {		print("someone's exiting\n");		exit(0);	}	checkalarms();	if(up && up->state == Running)		hzsched();	/* in proc.c */}voidtimerintr(Ureg *u, uvlong){	Timer *t;	Timers *tt;	uvlong when, now;	int callhzclock;	static int sofar;	intrcount[m->machno]++;	callhzclock = 0;	tt = &timers[m->machno];	now = fastticks(nil);	ilock(tt);	while(t = tt->head){		/*		 * No need to ilock t here: any manipulation of t		 * requires tdel(t) and this must be done with a		 * lock to tt held.  We have tt, so the tdel will		 * wait until we're done		 */		when = t->twhen;		if(when > now){			timerset(when);			iunlock(tt);			if(callhzclock)				hzclock(u);			return;		}		tt->head = t->tnext;		assert(t->tt == tt);		t->tt = nil;		fcallcount[m->machno]++;		iunlock(tt);		if(t->tf)			(*t->tf)(u, t);		else			callhzclock++;		ilock(tt);		if(t->tmode == Tperiodic)			tadd(tt, t);	}	iunlock(tt);}voidtimersinit(void){	Timer *t;	/*	 * T->tf == nil means the HZ clock for this processor.	 */	todinit();	t = malloc(sizeof(*t));	t->tmode = Tperiodic;	t->tt = nil;	t->tns = 1000000000/HZ;	t->tf = nil;	timeradd(t);}Timer*addclock0link(void (*f)(void), int ms){	Timer *nt;	uvlong when;	/* Synchronize to hztimer if ms is 0 */	nt = malloc(sizeof(Timer));	if(ms == 0)		ms = 1000/HZ;	nt->tns = (vlong)ms*1000000LL;	nt->tmode = Tperiodic;	nt->tt = nil;	nt->tf = (void (*)(Ureg*, Timer*))f;	ilock(&timers[0]);	when = tadd(&timers[0], nt);	if(when)		timerset(when);	iunlock(&timers[0]);	return nt;}/* *  This tk2ms avoids overflows that the macro version is prone to. *  It is a LOT slower so shouldn't be used if you're just converting *  a delta. */ulongtk2ms(ulong ticks){	uvlong t, hz;	t = ticks;	hz = HZ;	t *= 1000L;	t = t/hz;	ticks = t;	return ticks;}ulongms2tk(ulong ms){	/* avoid overflows at the cost of precision */	if(ms >= 1000000000/HZ)		return (ms/1000)*HZ;	return (ms*HZ+500)/1000;}

⌨️ 快捷键说明

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