mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-15 05:16:30 +00:00
Make getentropy() faster
This commit is contained in:
parent
17a85e4790
commit
000d6dbb0f
2 changed files with 19 additions and 19 deletions
|
@ -17,17 +17,16 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/blockcancel.internal.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/strace.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_getentropy(void *, size_t) asm("sys_getrandom");
|
||||
|
||||
/**
|
||||
* Returns random seeding bytes, the XNU/OpenBSD way.
|
||||
* Returns random seeding bytes, the POSIX way.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @raise EFAULT if the `n` bytes at `p` aren't valid memory
|
||||
|
@ -41,17 +40,23 @@ int getentropy(void *p, size_t n) {
|
|||
} else if ((!p && n)) {
|
||||
rc = efault();
|
||||
} else if (IsXnu() || IsOpenbsd()) {
|
||||
if (sys_getentropy(p, n))
|
||||
notpossible;
|
||||
rc = 0;
|
||||
rc = sys_getentropy(p, n);
|
||||
} else {
|
||||
BLOCK_SIGNALS;
|
||||
ssize_t got;
|
||||
BLOCK_CANCELATION;
|
||||
if (__getrandom(p, n, 0) != n)
|
||||
notpossible;
|
||||
ALLOW_CANCELATION;
|
||||
ALLOW_SIGNALS;
|
||||
rc = 0;
|
||||
for (size_t i = 0; i < n; i += got) {
|
||||
got = __getrandom(p + i, n - i, 0);
|
||||
if (got == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR) {
|
||||
got = 0;
|
||||
} else {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ALLOW_CANCELATION;
|
||||
}
|
||||
STRACE("getentropy(%p, %'zu) → %'ld% m", p, n, rc);
|
||||
return rc;
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#ifndef __aarch64__
|
||||
// TODO(jart): Make this test less resource intensive.
|
||||
// TODO(jart): Why can EINTR happen on Windows?
|
||||
|
||||
atomic_int done;
|
||||
atomic_int ready;
|
||||
|
@ -51,11 +49,9 @@ void *TortureWorker(void *arg) {
|
|||
ASSERT_SYS(0, 0, sigprocmask(SIG_SETMASK, &ss, 0));
|
||||
ready = true;
|
||||
while (!done) {
|
||||
if (!IsWindows())
|
||||
pthread_kill(parent, SIGUSR1);
|
||||
pthread_kill(parent, SIGUSR1);
|
||||
usleep(1);
|
||||
if (!IsWindows())
|
||||
pthread_kill(parent, SIGUSR2);
|
||||
pthread_kill(parent, SIGUSR2);
|
||||
usleep(1);
|
||||
}
|
||||
return 0;
|
||||
|
@ -100,8 +96,7 @@ TEST(getentropy, test) {
|
|||
}
|
||||
done = true;
|
||||
ASSERT_EQ(0, pthread_join(child, 0));
|
||||
if (!IsWindows())
|
||||
ASSERT_GT(gotsome, 0);
|
||||
ASSERT_GT(gotsome, 0);
|
||||
}
|
||||
|
||||
#endif /* __aarch64__ */
|
||||
|
|
Loading…
Add table
Reference in a new issue