FreeBSD/sys/dev/random/random_harvestq.c
/* XXXRW: get_cyclecount() is cheap on most modern hardware, where cycle
 * counters are built in, but on older hardware it will do a real time clock
 * read which can be quite expensive.
 */
get_cyclecount() is cheap on most modern hardware, where cycle
counters are built in, but on older hardware it will do a real time clock
read which can be quite expensive.
get_cyclecount () is cheap on most modern hardware where cycle counters are built in but on older hardware it will do a real time clock read which can be quite expensive .
void
random_harvest_queue(const void *entropy, u_int size, u_int bits, enum random_entropy_source origin)
{
	struct harvest_event *event;
	u_int ring_in;
	KASSERT(origin >= RANDOM_START && origin < ENTROPYSOURCE, ("%s: origin %d invalid\n", __func__, origin));
	if (!(harvest_context.hc_source_mask & (1 << origin)))
		return;
	RANDOM_HARVEST_LOCK();
	ring_in = (harvest_context.hc_entropy_ring.in + 1)%RANDOM_RING_MAX;
	if (ring_in != harvest_context.hc_entropy_ring.out) {
		event = harvest_context.hc_entropy_ring.ring + ring_in;
		event->he_somecounter = (uint32_t)get_cyclecount();
		event->he_source = origin;
		event->he_destination = harvest_context.hc_destination[origin]++;
		event->he_bits = bits;
		if (size <= sizeof(event->he_entropy)) {
			event->he_size = size;
			memcpy(event->he_entropy, entropy, size);
		}
		else {
			event->he_size = sizeof(event->he_entropy[0]);
			event->he_entropy[0] = jenkins_hash(entropy, size, (uint32_t)(uintptr_t)event);
		}
		harvest_context.hc_entropy_ring.in = ring_in;
	}
	RANDOM_HARVEST_UNLOCK();
}
void random_harvest_queue ( const void * entropy , u_int size , u_int bits , enum random_entropy_source origin ) { struct harvest_event * event ; u_int ring_in ; KASSERT ( origin >= RANDOM_START && origin < ENTROPYSOURCE , ( " \n " , __func__ , origin ) ) ; if ( ! ( harvest_context . hc_source_mask & ( 1 << origin ) ) ) return ; RANDOM_HARVEST_LOCK ( ) ; ring_in = ( harvest_context . hc_entropy_ring . in + 1 ) % RANDOM_RING_MAX ; if ( ring_in != harvest_context . hc_entropy_ring . out ) { event = harvest_context . hc_entropy_ring . ring + ring_in ; event -> he_somecounter = ( uint32_t ) get_cyclecount ( ) ; event -> he_source = origin ; event -> he_destination = harvest_context . hc_destination [ origin ] ++ ; event -> he_bits = bits ; if ( size <= sizeof ( event -> he_entropy ) ) { event -> he_size = size ; memcpy ( event -> he_entropy , entropy , size ) ; } else { event -> he_size = sizeof ( event -> he_entropy [ 0 ] ) ; event -> he_entropy [ 0 ] = jenkins_hash ( entropy , size , ( uint32_t ) ( uintptr_t ) event ) ; } harvest_context . hc_entropy_ring . in = ring_in ; } RANDOM_HARVEST_UNLOCK ( ) ; }
XXXRW: get_cyclecount() is cheap on most modern hardware, where cycle
 counters are built in, but on older hardware it will do a real time clock
 read which can be quite expensive.
XXXRW : get_cyclecount () is cheap on most modern hardware where cycle counters are built in but on older hardware it will do a real time clock read which can be quite expensive .
/* The ring is not full */ /* Big event, so squash it */