#include "src/include/pmix_config.h"
#include <string.h>
#include "pmix_alfg.h"
#define MASK 0x80000057U
#define TAP1 127
#define TAP2 97
#define CBIT 21
static uint32_t galois(unsigned int *seed)
{
uint32_t lsb;
lsb = (*seed & 1) ? 1 : 0;
*seed >>= 1;
*seed = *seed ^ (lsb * MASK);
return lsb;
}
static pmix_rng_buff_t alfg_buffer;
int pmix_srand(pmix_rng_buff_t *buff, uint32_t seed)
{
int i, j;
uint32_t seed_cpy = seed;
buff->tap1 = TAP1 - 1;
buff->tap2 = TAP2 - 1;
for (i = 0; i < TAP1; i++) {
buff->alfg[i] = 0;
}
buff->alfg[CBIT] = 1;
for (j = 1; j < TAP1; j++) {
for (i = 1; i < 32; i++) {
buff->alfg[j] = buff->alfg[j] ^ ((galois(&seed_cpy)) << i);
}
}
memcpy(&alfg_buffer, buff, sizeof(alfg_buffer));
return 1;
}
uint32_t pmix_rand(pmix_rng_buff_t *buff)
{
int *tap1 = &(buff->tap1);
int *tap2 = &(buff->tap2);
uint64_t overflow;
uint32_t temp;
overflow = (uint64_t) buff->alfg[*tap1] + (uint64_t) buff->alfg[*tap2];
temp = (*tap1 + 1) == TAP1 ? 0 : (*tap1 + 1);
buff->alfg[temp] = (uint32_t)(overflow & ((1ULL << 32) - 1));
*tap1 = (*tap1 + 1) % TAP1;
*tap2 = (*tap2 + 1) % TAP1;
return buff->alfg[temp];
}
int pmix_random(void)
{
return (int) (pmix_rand(&alfg_buffer) & 0x7FFFFFFF);
}