Skip to content

Commit f0d9532

Browse files
author
dsl
committed
cache rs.i and rs.j in arc4random_buf() since the compiler can't be
told that buf[] dosn't alias them. Reduces the number of instructions inside the loop. All the other functions are ok.
1 parent 1e09d27 commit f0d9532

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

lib/libc/gen/arc4random.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: arc4random.c,v 1.16 2012/08/18 15:04:53 dsl Exp $ */
1+
/* $NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $ */
22
/* $OpenBSD: arc4random.c,v 1.6 2001/06/05 05:05:38 pvalchev Exp $ */
33

44
/*
@@ -27,7 +27,7 @@
2727

2828
#include <sys/cdefs.h>
2929
#if defined(LIBC_SCCS) && !defined(lint)
30-
__RCSID("$NetBSD: arc4random.c,v 1.16 2012/08/18 15:04:53 dsl Exp $");
30+
__RCSID("$NetBSD: arc4random.c,v 1.17 2012/08/18 15:55:07 dsl Exp $");
3131
#endif /* LIBC_SCCS and not lint */
3232

3333
#include "namespace.h"
@@ -150,20 +150,26 @@ arc4_stir(struct arc4_stream *as)
150150
arc4_getbyte(as);
151151
}
152152

153-
static inline uint8_t
154-
arc4_getbyte(struct arc4_stream *as)
153+
static __always_inline uint8_t
154+
arc4_getbyte_ij(struct arc4_stream *as, uint8_t *i, uint8_t *j)
155155
{
156156
uint8_t si, sj;
157157

158-
as->i = (as->i + 1);
159-
si = as->s[as->i];
160-
as->j = (as->j + si);
161-
sj = as->s[as->j];
162-
as->s[as->i] = sj;
163-
as->s[as->j] = si;
158+
*i = *i + 1;
159+
si = as->s[*i];
160+
*j = *j + si;
161+
sj = as->s[*j];
162+
as->s[*i] = sj;
163+
as->s[*j] = si;
164164
return (as->s[(si + sj) & 0xff]);
165165
}
166166

167+
static inline uint8_t
168+
arc4_getbyte(struct arc4_stream *as)
169+
{
170+
return arc4_getbyte_ij(as, &as->i, &as->j);
171+
}
172+
167173
static inline uint32_t
168174
arc4_getword(struct arc4_stream *as)
169175
{
@@ -210,17 +216,25 @@ arc4random_buf(void *buf, size_t len)
210216
{
211217
uint8_t *bp = buf;
212218
uint8_t *ep = bp + len;
219+
uint8_t i, j;
213220
int skip;
214221

215222
LOCK(&rs);
216223
arc4_check_init(&rs);
217224

218-
skip = arc4_getbyte(&rs) % 3;
225+
/* cache i and j - compiler can't know 'buf' doesn't alias them */
226+
i = rs.i;
227+
j = rs.j;
228+
229+
skip = arc4_getbyte_ij(&rs, &i, &j) % 3;
219230
while (skip--)
220-
(void)arc4_getbyte(&rs);
231+
(void)arc4_getbyte_ij(&rs, &i, &j);
221232

222233
while (bp < ep)
223-
*bp++ = arc4_getbyte(&rs);
234+
*bp++ = arc4_getbyte_ij(&rs, &i, &j);
235+
rs.i = i;
236+
rs.j = j;
237+
224238
UNLOCK(&rs);
225239
}
226240

0 commit comments

Comments
 (0)