From b9faa9c21522d9a6e98a892c0cbaab3db3c83521 Mon Sep 17 00:00:00 2001 From: Krzysztof Jackiewicz Date: Tue, 17 Feb 2015 14:42:34 +0100 Subject: [PATCH] Optimize openssl initialization [Issue#] N/A [Feature/Bug] N/A [Problem] Each time Manager or PKCS12 object is created initCryptoLib is called and mutex is locked inside it. [Cause] N/A [Solution] Once openssl is initialized the initalization function pointer is switched to empty one, thus mutex is not used any more. [Verification] Run tests. Alternatively check in gdb that client calls initOpenSSL() only once Change-Id: I733e4ca6c88a6a51d69ebb0606f560a9b4828e4c --- src/manager/common/crypto-init.cpp | 39 +++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/manager/common/crypto-init.cpp b/src/manager/common/crypto-init.cpp index 5ae1849..47f99b7 100644 --- a/src/manager/common/crypto-init.cpp +++ b/src/manager/common/crypto-init.cpp @@ -22,23 +22,52 @@ #include "crypto-init.h" #include #include +#include namespace CKM { namespace { -bool isCryptoInitialized = false; std::mutex cryptoInitMutex; -} -void initCryptoLib() { +void initOpenSSL(); + +typedef void(*initFnPtr)(); + +// has to be atomic as storing function pointer is not an atomic operation on armv7l +std::atomic initFn (&initOpenSSL); + +void initEmpty() {} + +void initOpenSSL() { + // DCLP std::lock_guard lock(cryptoInitMutex); - if(!isCryptoInitialized) + /* + * We don't care about memory ordering here. Current thread will order it correctly and for + * other threads only store matters. Also only one thread can be here at once because of lock. + */ + if(initFn.load(std::memory_order_relaxed) != &initEmpty) { - isCryptoInitialized = true; OpenSSL_add_all_ciphers(); OpenSSL_add_all_algorithms(); OpenSSL_add_all_digests(); + + /* + * Synchronizes with load. Everything that happened before this store in this thread is + * visible to everything that happens after load in another thread. We switch to an empty + * function here. + */ + initFn.store(&initEmpty, std::memory_order_release); } } +} // namespace anonymous + +void initCryptoLib() { + /* + * Synchronizes with store. Everything that happened before store in another thread will be + * visible in this thread after load. + */ + initFn.load(std::memory_order_acquire)(); +} + } /* namespace CKM */ -- 2.7.4