summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-01-27 10:21:56 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2017-03-06 22:24:33 +0100
commit1677f1ac06beecb2fb23f0f49d89260f86131a5c (patch)
tree66f93eaf204c51510629188c6557f12473671d2b
parente8ff21bd972097cf4163ee710bbfc2817dc45d98 (diff)
downloadgnutls-1677f1ac06beecb2fb23f0f49d89260f86131a5c.tar.gz
Use a thread local random generator.
This allows accessing the per-thread random generator in a lock-free way, at the cost of additional memory per thread. The default random generator imposes around 640 bytes per thread on 64-bit architectures. Resolves: #141 Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--configure.ac3
-rw-r--r--lib/random.c41
-rw-r--r--lib/random.h1
3 files changed, 12 insertions, 33 deletions
diff --git a/configure.ac b/configure.ac
index 5779d2d584..23cbd5b7f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -192,6 +192,9 @@ dnl Need netinet/tcp.h for TCP_FASTOPEN
AC_CHECK_HEADERS([netinet/tcp.h])
AC_CHECK_HEADERS([stdatomic.h])
+dnl We use its presence to detect C11 threads
+AC_CHECK_HEADERS([threads.h])
+
AC_ARG_ENABLE(padlock,
AS_HELP_STRING([--disable-padlock], [unconditionally disable padlock acceleration]),
use_padlock=$enableval)
diff --git a/lib/random.c b/lib/random.c
index ba7333dc85..73fb143d7f 100644
--- a/lib/random.c
+++ b/lib/random.c
@@ -29,57 +29,34 @@
#include "locks.h"
#include <fips.h>
-void *gnutls_rnd_ctx;
-GNUTLS_STATIC_MUTEX(gnutls_rnd_init_mutex);
+#ifdef HAVE_THREADS_H
+# include <threads.h>
+#elif defined(__GNUC__)
+# define _Thread_local __thread
+#else
+# error Unsupported platform
+#endif
-#ifdef HAVE_STDATOMIC_H
-static atomic_uint rnd_initialized = 0;
+static _Thread_local void *gnutls_rnd_ctx;
-inline static int _gnutls_rnd_init(void)
-{
- if (unlikely(!rnd_initialized)) {
- if (_gnutls_rnd_ops.init == NULL) {
- rnd_initialized = 1;
- return 0;
- }
-
- GNUTLS_STATIC_MUTEX_LOCK(gnutls_rnd_init_mutex);
- if (!rnd_initialized) {
- if (_gnutls_rnd_ops.init(&gnutls_rnd_ctx) < 0) {
- gnutls_assert();
- GNUTLS_STATIC_MUTEX_UNLOCK(gnutls_rnd_init_mutex);
- return GNUTLS_E_RANDOM_FAILED;
- }
- rnd_initialized = 1;
- }
- GNUTLS_STATIC_MUTEX_UNLOCK(gnutls_rnd_init_mutex);
- }
- return 0;
-}
-#else
-static unsigned rnd_initialized = 0;
+static _Thread_local unsigned rnd_initialized = 0;
inline static int _gnutls_rnd_init(void)
{
- GNUTLS_STATIC_MUTEX_LOCK(gnutls_rnd_init_mutex);
if (unlikely(!rnd_initialized)) {
if (_gnutls_rnd_ops.init == NULL) {
rnd_initialized = 1;
- GNUTLS_STATIC_MUTEX_UNLOCK(gnutls_rnd_init_mutex);
return 0;
}
if (_gnutls_rnd_ops.init(&gnutls_rnd_ctx) < 0) {
gnutls_assert();
- GNUTLS_STATIC_MUTEX_UNLOCK(gnutls_rnd_init_mutex);
return GNUTLS_E_RANDOM_FAILED;
}
rnd_initialized = 1;
}
- GNUTLS_STATIC_MUTEX_UNLOCK(gnutls_rnd_init_mutex);
return 0;
}
-#endif
int _gnutls_rnd_preinit(void)
{
diff --git a/lib/random.h b/lib/random.h
index e89efb9c34..a76c8c07f6 100644
--- a/lib/random.h
+++ b/lib/random.h
@@ -28,7 +28,6 @@
#include "nettle/rnd-common.h"
extern int crypto_rnd_prio;
-extern void *gnutls_rnd_ctx;
extern gnutls_crypto_rnd_st _gnutls_rnd_ops;
void _gnutls_rnd_deinit(void);