random.c

来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 139 行

C
139
字号
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"../port/error.h"struct Rb{	QLock;	Rendez	producer;	Rendez	consumer;	ulong	randomcount;	uchar	buf[1024];	uchar	*ep;	uchar	*rp;	uchar	*wp;	uchar	next;	uchar	wakeme;	ushort	bits;	ulong	randn;} rb;static intrbnotfull(void*){	int i;	i = rb.rp - rb.wp;	return i != 1 && i != (1 - sizeof(rb.buf));}static intrbnotempty(void*){	return rb.wp != rb.rp;}static voidgenrandom(void*){	up->basepri = PriNormal;	up->priority = up->basepri;	for(;;){		for(;;)			if(++rb.randomcount > 100000)				break;		if(anyhigher())			sched();		if(!rbnotfull(0))			sleep(&rb.producer, rbnotfull, 0);	}}/* *  produce random bits in a circular buffer */static voidrandomclock(void){	if(rb.randomcount == 0 || !rbnotfull(0))		return;	rb.bits = (rb.bits<<2) ^ rb.randomcount;	rb.randomcount = 0;	rb.next++;	if(rb.next != 8/2)		return;	rb.next = 0;	*rb.wp ^= rb.bits;	if(rb.wp+1 == rb.ep)		rb.wp = rb.buf;	else		rb.wp = rb.wp+1;	if(rb.wakeme)		wakeup(&rb.consumer);}voidrandominit(void){	addclock0link(randomclock, 1000/HZ);	rb.ep = rb.buf + sizeof(rb.buf);	rb.rp = rb.wp = rb.buf;	kproc("genrandom", genrandom, 0);}/* *  consume random bytes from a circular buffer */ulongrandomread(void *xp, ulong n){	uchar *e, *p;	ulong x;	p = xp;	if(waserror()){		qunlock(&rb);		nexterror();	}	qlock(&rb);	for(e = p + n; p < e; ){		if(rb.wp == rb.rp){			rb.wakeme = 1;			wakeup(&rb.producer);			sleep(&rb.consumer, rbnotempty, 0);			rb.wakeme = 0;			continue;		}		/*		 *  beating clocks will be precictable if		 *  they are synchronized.  Use a cheap pseudo		 *  random number generator to obscure any cycles.		 */		x = rb.randn*1103515245 ^ *rb.rp;		*p++ = rb.randn = x;		if(rb.rp+1 == rb.ep)			rb.rp = rb.buf;		else			rb.rp = rb.rp+1;	}	qunlock(&rb);	poperror();	wakeup(&rb.producer);	return n;}

⌨️ 快捷键说明

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