mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-22 04:11:16 -05:00
Add missing files from last commit
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@6273 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
This commit is contained in:
parent
6be4f3d376
commit
00f78dd646
76
lib/init_random_seed.c
Normal file
76
lib/init_random_seed.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include "init_random_seed.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* basic PRNG to use for improving the basic seed selection */
|
||||||
|
static unsigned lcg (uint64_t seed)
|
||||||
|
{
|
||||||
|
if (0 ==seed)
|
||||||
|
{
|
||||||
|
seed = UINT64_C(104729);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
seed %= UINT64_C(4294967296);
|
||||||
|
}
|
||||||
|
seed = (seed * UINT64_C(279470273)) % UINT64_C(4294967291);
|
||||||
|
return seed % UINT64_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate a good PRNG seed value */
|
||||||
|
void init_random_seed(void)
|
||||||
|
{
|
||||||
|
unsigned seed = 0u;
|
||||||
|
int have_seed = 0;
|
||||||
|
|
||||||
|
// try /dev/urandom for an initial seed
|
||||||
|
int random_source;
|
||||||
|
if (0 == (random_source = open ("/dev/urandom", O_RDONLY)))
|
||||||
|
{
|
||||||
|
size_t random_data_length = 0;
|
||||||
|
have_seed = -1;
|
||||||
|
while (random_data_length < sizeof seed)
|
||||||
|
{
|
||||||
|
ssize_t result = read (random_source, &seed + random_data_length, (sizeof seed) - random_data_length);
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
// error, unable to read /dev/random
|
||||||
|
have_seed = 0;
|
||||||
|
}
|
||||||
|
random_data_length += result;
|
||||||
|
}
|
||||||
|
close (random_source);
|
||||||
|
}
|
||||||
|
if (!have_seed)
|
||||||
|
{
|
||||||
|
// fallback to XOR:ing the time and pid
|
||||||
|
seed = time (NULL) ^ getpid ();
|
||||||
|
seed = lcg (seed);
|
||||||
|
}
|
||||||
|
srand (seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main (int argc, char * argv[])
|
||||||
|
{
|
||||||
|
init_random_seed ();
|
||||||
|
int i, j;
|
||||||
|
int r[10][4];
|
||||||
|
for (i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 4; ++j)
|
||||||
|
{
|
||||||
|
printf ("%10d ", rand ());
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
55
lib/init_random_seed.f90
Normal file
55
lib/init_random_seed.f90
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
!
|
||||||
|
! Generate a seed for the RANDOM_NUMBER PRNG that is guaranteed to be
|
||||||
|
! unique even if many processes are started simultaneously
|
||||||
|
!
|
||||||
|
subroutine init_random_seed()
|
||||||
|
use iso_fortran_env, only: int64
|
||||||
|
implicit none
|
||||||
|
integer, allocatable :: seed(:)
|
||||||
|
integer :: i, n, un, istat, dt(8), pid
|
||||||
|
integer(int64) :: t
|
||||||
|
|
||||||
|
call random_seed(size = n)
|
||||||
|
allocate(seed(n))
|
||||||
|
! First try if the OS provides a random number generator
|
||||||
|
open(newunit=un, file="/dev/urandom", access="stream", &
|
||||||
|
form="unformatted", action="read", status="old", iostat=istat)
|
||||||
|
if (istat == 0) then
|
||||||
|
read(un) seed
|
||||||
|
close(un)
|
||||||
|
else
|
||||||
|
! Fallback to XOR:ing the current time and pid. The PID is
|
||||||
|
! useful in case one launches multiple instances of the same
|
||||||
|
! program in parallel.
|
||||||
|
call system_clock(t)
|
||||||
|
if (t == 0) then
|
||||||
|
call date_and_time(values=dt)
|
||||||
|
t = (dt(1) - 1970) * 365_int64 * 24 * 60 * 60 * 1000 &
|
||||||
|
+ dt(2) * 31_int64 * 24 * 60 * 60 * 1000 &
|
||||||
|
+ dt(3) * 24_int64 * 60 * 60 * 1000 &
|
||||||
|
+ dt(5) * 60 * 60 * 1000 &
|
||||||
|
+ dt(6) * 60 * 1000 + dt(7) * 1000 &
|
||||||
|
+ dt(8)
|
||||||
|
end if
|
||||||
|
pid = getpid()
|
||||||
|
t = ieor(t, int(pid, kind(t)))
|
||||||
|
do i = 1, n
|
||||||
|
seed(i) = lcg(t)
|
||||||
|
end do
|
||||||
|
end if
|
||||||
|
call random_seed(put=seed)
|
||||||
|
contains
|
||||||
|
! This simple PRNG might not be good enough for real work, but is
|
||||||
|
! sufficient for seeding a better PRNG.
|
||||||
|
function lcg(s)
|
||||||
|
integer :: lcg
|
||||||
|
integer(int64) :: s
|
||||||
|
if (s == 0) then
|
||||||
|
s = 104729
|
||||||
|
else
|
||||||
|
s = mod(s, 4294967296_int64)
|
||||||
|
end if
|
||||||
|
s = mod(s * 279470273_int64, 4294967291_int64)
|
||||||
|
lcg = int(mod(s, int(huge(0), int64)), kind(0))
|
||||||
|
end function lcg
|
||||||
|
end subroutine init_random_seed
|
20
lib/init_random_seed.h
Normal file
20
lib/init_random_seed.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef INIT_RANDOM_SEED_H__
|
||||||
|
#define INIT_RANDOM_SEED_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
exten "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate a seed for the RANDOM_NUMBER PRNG that is guaranteed to
|
||||||
|
* be unique even if many processes are started simultaneously
|
||||||
|
*
|
||||||
|
* Not suitable for multi-threaded requirements
|
||||||
|
*/
|
||||||
|
void init_random_seed (void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user