From b8f841599cfdbeac35a9abc0ec50c6130f5e19e0 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 10 Feb 2021 17:14:17 +0100 Subject: [PATCH] Add --enable-error-queue-per-thread --- configure.ac | 12 ++++++++++ tests/api.c | 52 +++++++++++++++++++++++++++++++++++++++++ wolfcrypt/src/logging.c | 27 +++++++++++++++++---- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index dd8a6ac74..10c9b4a36 100644 --- a/configure.ac +++ b/configure.ac @@ -938,6 +938,18 @@ then AM_CFLAGS="-DWOLFSSL_EKU_OID -DWOLFSSL_MULTI_ATTRIB $AM_CFLAGS" fi +# One Error Queue per Thread +AC_ARG_ENABLE([error-queue-per-thread], +[AS_HELP_STRING([--enable-error-queue-per-thread],[Enable one error queue per thread. Requires thread local storage. (default: disabled)])], +[ ENABLED_ERRORQUEUEPERTHREAD=$enableval ], +[ ENABLED_ERRORQUEUEPERTHREAD=no ] +) + +if test "$ENABLED_ERRORQUEUEPERTHREAD" = "yes" +then + AM_CFLAGS="-DERROR_QUEUE_PER_THREAD $AM_CFLAGS" +fi + # High Strength Build AC_ARG_ENABLE([maxstrength], [AS_HELP_STRING([--enable-maxstrength],[Enable Max Strength build, allows TLSv1.2-AEAD-PFS ciphers only (default: disabled)])], diff --git a/tests/api.c b/tests/api.c index 6b3af3092..5a9cddc94 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30221,6 +30221,57 @@ static void test_wolfSSL_PKCS8_d2i(void) #endif /* HAVE_FIPS */ } +#if defined(ERROR_QUEUE_PER_THREAD) && !defined(NO_ERROR_QUEUE) && \ + defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL) +#define LOGGING_THREADS 5 +#define ERROR_COUNT 10 +static volatile int loggingThreadsReady; +static THREAD_RETURN WOLFSSL_THREAD test_logging(void* args) +{ + const char* file; + int line; + int err; + int errorCount = 0; + int i; + + (void)args; + + while (!loggingThreadsReady); + for (i = 0; i < ERROR_COUNT; i++) + ERR_put_error(ERR_LIB_PEM, SYS_F_ACCEPT, -990 - i, __FILE__, __LINE__); + + while ((err = ERR_get_error_line(&file, &line))) { + AssertIntEQ(err, 990 + errorCount); + errorCount++; + } + AssertIntEQ(errorCount, ERROR_COUNT); + + return 0; +} +#endif + +static void test_error_queue_per_thread(void) +{ +#if defined(ERROR_QUEUE_PER_THREAD) && !defined(NO_ERROR_QUEUE) && \ + defined(OPENSSL_EXTRA) && defined(DEBUG_WOLFSSL) + THREAD_TYPE loggingThreads[LOGGING_THREADS]; + int i; + + printf(testingFmt, "error_queue_per_thread()"); + + ERR_clear_error(); /* clear out any error nodes */ + + loggingThreadsReady = 0; + for (i = 0; i < LOGGING_THREADS; i++) + start_thread(test_logging, NULL, &loggingThreads[i]); + loggingThreadsReady = 1; + for (i = 0; i < LOGGING_THREADS; i++) + join_thread(loggingThreads[i]); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_ERR_put_error(void) { #if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \ @@ -40435,6 +40486,7 @@ void ApiTest(void) test_wolfSSL_pseudo_rand(); test_wolfSSL_PKCS8_Compat(); test_wolfSSL_PKCS8_d2i(); + test_error_queue_per_thread(); test_wolfSSL_ERR_put_error(); #ifndef NO_BIO test_wolfSSL_ERR_print_errors(); diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index f6fc1fca1..5a9908831 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -34,11 +34,19 @@ #endif #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) -static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */ +static +#ifdef ERROR_QUEUE_PER_THREAD +THREAD_LS_T +#endif +wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */ /* accessing any node from the queue should be wrapped in a lock of * debug_mutex */ -static void* wc_error_heap; +static +#ifdef ERROR_QUEUE_PER_THREAD +THREAD_LS_T +#endif +void* wc_error_heap; struct wc_error_queue { void* heap; /* the heap hint used with nodes creation */ struct wc_error_queue* next; @@ -48,9 +56,20 @@ struct wc_error_queue { int value; int line; }; +#ifdef ERROR_QUEUE_PER_THREAD +THREAD_LS_T +#endif volatile struct wc_error_queue* wc_errors; -static struct wc_error_queue* wc_current_node; -static struct wc_error_queue* wc_last_node; +static +#ifdef ERROR_QUEUE_PER_THREAD +THREAD_LS_T +#endif +struct wc_error_queue* wc_current_node; +static +#ifdef ERROR_QUEUE_PER_THREAD +THREAD_LS_T +#endif +struct wc_error_queue* wc_last_node; /* pointer to last node in queue to make insertion O(1) */ #endif