📄 random.c
字号:
#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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -