<commit_before>/*
 * Copyright (c) 2016 Nordic Semiconductor ASA
 * Copyright (c) 2016 <NAME>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <soc.h>

#include "hal/rand.h"

#include "common/log.h"
#include "hal/debug.h"

struct rand {
	u8_t count;
	u8_t threshold;
	u8_t first;
	u8_t last;
	u8_t rand[1];
};

static struct rand *rng_isr;
static struct rand *rng_thr;

static void init(struct rand **rng, u8_t *context, u8_t len, u8_t threshold)
{
	struct rand *p;

	LL_ASSERT(len > (offsetof(struct rand, rand) + threshold));

	*rng = (struct rand *)context;

	p = *rng;
	p->count = len - offsetof(struct rand, rand);
	p->threshold = threshold;
	p->first = p->last = 0;

	if (!rng_isr || !rng_thr) {
		NRF_RNG->CONFIG = RNG_CONFIG_DERCEN_Msk;
		NRF_RNG->EVENTS_VALRDY = 0;
		NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Msk;

		NRF_RNG->TASKS_START = 1;
	}
}

void rand_init(u8_t *context, u8_t context_len, u8_t threshold)
{
	init(&rng_thr, context, context_len, threshold);
}

void rand_isr_init(u8_t *context, u8_t context_len, u8_t threshold)
{
	init(&rng_isr, context, context_len, threshold);
}

static size_t get(struct rand *rng, size_t octets, u8_t *rand)
{
	u8_t first;
	u8_t avail;

	LL_ASSERT(rng);

	while (octets) {
		if (rng->first == rng->last) {
			break;
		}

		rand[--octets] = rng->rand[rng->first];

		first = rng->first + 1;
		if (first == rng->count) {
			first = 0;
		}
		rng->first = first;
	}

	if (rng->first <= rng->last) {
		avail = rng->last - rng->first;
	} else {
		avail = rng->count - rng->first + rng->last;
	}

	if (avail < rng->threshold) {
		NRF_RNG->TASKS_START = 1;
	}

	return octets;
}

size_t rand_get(size_t octets, u8_t *rand)
{
	return get(rng_thr, octets, rand);
}

size_t rand_isr_get(size_t octets, u8_t *rand)
{
	return get(rng_isr, octets, rand);<commit_msg>Bluetooth: controller: Optimize the loop in nRF5 hal rand get()<commit_after>/*
 * Copyright (c) 2016 Nordic Semiconductor ASA
 * Copyright (c) 2016 <NAME>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <soc.h>

#include "hal/rand.h"

#include "common/log.h"
#include "hal/debug.h"

struct rand {
	u8_t count;
	u8_t threshold;
	u8_t first;
	u8_t last;
	u8_t rand[1];
};

static struct rand *rng_isr;
static struct rand *rng_thr;

static void init(struct rand **rng, u8_t *context, u8_t len, u8_t threshold)
{
	struct rand *p;

	LL_ASSERT(len > (offsetof(struct rand, rand) + threshold));

	*rng = (struct rand *)context;

	p = *rng;
	p->count = len - offsetof(struct rand, rand);
	p->threshold = threshold;
	p->first = p->last = 0;

	if (!rng_isr || !rng_thr) {
		NRF_RNG->CONFIG = RNG_CONFIG_DERCEN_Msk;
		NRF_RNG->EVENTS_VALRDY = 0;
		NRF_RNG->INTENSET = RNG_INTENSET_VALRDY_Msk;

		NRF_RNG->TASKS_START = 1;
	}
}

void rand_init(u8_t *context, u8_t context_len, u8_t threshold)
{
	init(&rng_thr, context, context_len, threshold);
}

void rand_isr_init(u8_t *context, u8_t context_len, u8_t threshold)
{
	init(&rng_isr, context, context_len, threshold);
}

static size_t get(struct rand *rng, size_t octets, u8_t *rand)
{
	u8_t first, last, remaining;

	LL_ASSERT(rng);

	first = rng->first;
	last = rng->last;

	if (first <= last) {
		u8_t *d, *s;
		u8_t avail;

		d = &rand[octets];
		s = &rng->rand[first];

		avail = last - first;
		if (octets < avail) {
			remaining = avail - octets;
			avail = octets;
		} else {
			remaining = 0;
		}

		first += avail;
		octets -= avail;

		while (avail--) {
			*(--d) = *s++;
		}

		rng->first = first;
	} else {
		u8_t *d, *s;
		u8_t avail;

		d = &rand[octets];
		s = &rng->rand[first];

		avail = rng->count - first;
		if (octets < avail) {
			remaining = avail + last - octets;
			avail = octets;
			first += avail;
		} else {
			remaining = last;
			first = 0;
		}

		octets -= avail;

		while (avail--) {
			*(--d) = *s++;
		}

		if (octets && last) {
			s = &rng->rand[0];

			if (octets < last) {
				remaining = last - octets;
				last = octets;
			} else {
				remaining = 0;
			}

			first = last;
			octets -= last;

			while (last--) {
				*(--d) = *s++;
			}
		}

		rng->first = first;
	}

	if (remaining < rng->threshold) {
		NRF_RNG->TASKS_START = 1;
	}

	return octets;
}

size_t rand_get(size_t octets, u8_t *rand)
{
	return get(rng_thr, octets, rand);
}

size_t rand_isr_get(size_t octets, u8_t *rand)
{
	return get(rng_isr, octets, rand);
{'fraction_non_alphanumeric': 0.15606936416184972, 'fraction_numerical': 0.018034682080924857, 'mean_word_length': 3.3918781725888323, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6261109', 'n_tokens_mistral': 2092, 'n_tokens_neox': 1918, 'n_words': 434}