Skip to contentSkip to conversation

R: Re: [PATCH 1/2] btrfs-progs: utils: Introduce new pseudo random API

DISCUSSION [email protected] 2 participants 2 messages May 26, 2016 – May 27, 2016 Btrfs file system

lore
Share & tools
lore
#0 lore raw
Quoted 11 lines

----Messaggio originale----
Da: "Qu Wenruo" <[email protected]>
Data: 26/05/2016 2.38
A: <[email protected]>
Ogg: Re: [PATCH 1/2] btrfs-progs: utils: Introduce new pseudo random API

Quoted 38 lines

Goffredo Baroncelli wrote on 2016/05/25 18:15 +0200:

Quoted 37 lines · Qu Wenruo
Quoted 23 lines
(quoted diff) +23 -0
+void rand_seed(u64 seed)
+{
+	int i;
+	/* only use the last 48 bits */
+	for (i = 0; i < 3; i++) {
+		seeds[i] = (unsigned short)(seed ^ (unsigned short)(-1));
+		seed >>= 16;
+	}
+	seed_initlized = 1;
+}
+
+u32 rand_u32(void)
+{
+	struct timeval tv;
+
+	if (seed_initlized)
+		return nrand48(seeds);
+
+	/*
+	 * It's possible to use /dev/random, but we don't need that true
+	 * random number nor want to wait for entropy,
+	 * since we're only using random API to do corruption to test.
+	 * Time and pid/ppid based seed would be good enough, and won't

Review

Quoted 10 lines
(quoted diff) +10 -0
+	 * cause sleep for entropy pool.
+	 */
+	gettimeofday(&tv, 0);
+	seeds[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
+	seeds[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
+	seeds[2] = (tv.tv_sec ^ tv.tv_usec) >> 16;
+	seed_initlized = 1;
+
+	return (u32)nrand48(seeds);
+}

Just for my curiosity, which is the advantage of rand48() respect to rand()

if we utilize only the

Quoted 9 lines
Quoted 1 line

lower 32 bit ? It wouldn't be more simple to use:

Of course rand() is my first candidate.

However a quick check on manpage of rand(3) shows, the up limit of RAND_MAX, is not always the same.

In my system, RAND_MAX is 2^31 -1, while example code from rand(3) assumes the up limit is 32767.

In glibc RAND_MAX is always ~2^31: http://www.gnu.
org/software/libc/manual/html_node/ISO-Random.html

If it is true for glibc, it should be true also for the others linux libc (dietlibc[1], musl[2]); I think that assuming in linux RAND_MAX = 2^31-1 should be safe.

BR
Goffredo

[1] https://github.com/ensc/dietlibc/blob/master/include/stdlib.h#L101
[2] https://github.com/cloudius-systems/musl/blob/master/include/stdlib.h#L81

#1 lore raw

[email protected] wrote on 2016/05/26 13:08 +0200:

Quoted 54 lines
Quoted 11 lines

----Messaggio originale----
Da: "Qu Wenruo" <[email protected]>
Data: 26/05/2016 2.38
A: <[email protected]>
Ogg: Re: [PATCH 1/2] btrfs-progs: utils: Introduce new pseudo random API

Quoted 38 lines

Goffredo Baroncelli wrote on 2016/05/25 18:15 +0200:

Quoted 37 lines · Qu Wenruo
Quoted 23 lines
(quoted diff) +23 -0
+void rand_seed(u64 seed)
+{
+	int i;
+	/* only use the last 48 bits */
+	for (i = 0; i < 3; i++) {
+		seeds[i] = (unsigned short)(seed ^ (unsigned short)(-1));
+		seed >>= 16;
+	}
+	seed_initlized = 1;
+}
+
+u32 rand_u32(void)
+{
+	struct timeval tv;
+
+	if (seed_initlized)
+		return nrand48(seeds);
+
+	/*
+	 * It's possible to use /dev/random, but we don't need that true
+	 * random number nor want to wait for entropy,
+	 * since we're only using random API to do corruption to test.
+	 * Time and pid/ppid based seed would be good enough, and won't

Review

Quoted 10 lines
(quoted diff) +10 -0
+	 * cause sleep for entropy pool.
+	 */
+	gettimeofday(&tv, 0);
+	seeds[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
+	seeds[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
+	seeds[2] = (tv.tv_sec ^ tv.tv_usec) >> 16;
+	seed_initlized = 1;
+
+	return (u32)nrand48(seeds);
+}

Just for my curiosity, which is the advantage of rand48() respect to rand()

if we utilize only the

Quoted 4 lines
Quoted 1 line

lower 32 bit ? It wouldn't be more simple to use:

Of course rand() is my first candidate.

Quoted 8 lines
Quoted 5 lines

However a quick check on manpage of rand(3) shows, the up limit of RAND_MAX, is not always the same.

In my system, RAND_MAX is 2^31 -1, while example code from rand(3) assumes the up limit is 32767.

In glibc RAND_MAX is always ~2^31: http://www.gnu.
org/software/libc/manual/html_node/ISO-Random.html

Thanks for the reference on RAND_MAX is alwasy 2^31 - 1.

However, that's still not enough, for 2^31 - 1 case, the highest(sign) bit is always 0.

This doesn't fully use the 32 bits. It's OK for u16 and u8, but not u32 or u64.

On the other hand, jrand48() can return signed result, in range [- 2^31, 2^31). Which fully uses all the 32bits.

Thanks,
Qu

Quoted 18 lines

If it is true for glibc, it should be true also for the others linux libc (dietlibc[1], musl[2]); I think that assuming in linux RAND_MAX = 2^31-1 should be safe.

BR
Goffredo

[1] https://github.com/ensc/dietlibc/blob/master/include/stdlib.h#L101
[2] https://github.com/cloudius-systems/musl/blob/master/include/stdlib.h#L81

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html