linux/drivers/gpu/drm/lib/drm_random.c
Chris Wilson a33d42dd03 drm: Add a simple generator of random permutations
When testing, we want a random but yet reproducible order in which to
process elements. Here we create an array which is a random (using the
Tausworthe PRNG) permutation of the order in which to execute.

Note these are simple helpers intended to be merged upstream in lib/

v2: Tidier code by David Herrmann
v3: Add reminder that this code is intended to be temporary, with at
least the bulk of the prandom changes going to lib/

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161222083641.2691-6-chris@chris-wilson.co.uk
2016-12-27 12:34:00 +01:00

42 lines
949 B
C

#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/types.h>
#include "drm_random.h"
static inline u32 drm_prandom_u32_max_state(u32 ep_ro, struct rnd_state *state)
{
return upper_32_bits((u64)prandom_u32_state(state) * ep_ro);
}
void drm_random_reorder(unsigned int *order, unsigned int count,
struct rnd_state *state)
{
unsigned int i, j;
for (i = 0; i < count; ++i) {
BUILD_BUG_ON(sizeof(unsigned int) > sizeof(u32));
j = drm_prandom_u32_max_state(count, state);
swap(order[i], order[j]);
}
}
EXPORT_SYMBOL(drm_random_reorder);
unsigned int *drm_random_order(unsigned int count, struct rnd_state *state)
{
unsigned int *order, i;
order = kmalloc_array(count, sizeof(*order), GFP_TEMPORARY);
if (!order)
return order;
for (i = 0; i < count; i++)
order[i] = i;
drm_random_reorder(order, count, state);
return order;
}
EXPORT_SYMBOL(drm_random_order);