From f5c44e043d75d08fe849d17bddf8f547e79f0ad2 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Thu, 9 Jan 2020 08:10:44 +0100 Subject: [PATCH] Implement threads for key search. --- CMakeLists.txt | 12 ++++++++++- src/main.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 801413c..d68844a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.4) project(eosio-keygen VERSION 0.1.0) +option(USE_THREADS "Compile with support for threads (if available)." ON) + set( CMAKE_CXX_STANDARD 11 ) set( CMAKE_CXX_STANDARD_REQUIRED ON ) set( CMAKE_CXX_EXTENSIONS OFF ) @@ -10,6 +12,14 @@ set( INSTALL_SHARE_DIR share/${CMAKE_PROJECT_NAME} ) find_package(OpenSSL 1.1 REQUIRED) +if (USE_THREADS) + find_package(Threads) + if (Threads_FOUND) + # Add preprocessor flag + add_definitions( "-DHAVE_THREADS=1" ) + endif (Threads_FOUND) +endif (USE_THREADS) + include_directories( ${OPENSSL_INCLUDE_DIR} ) add_executable( ${CMAKE_PROJECT_NAME} @@ -22,7 +32,7 @@ add_executable( ${CMAKE_PROJECT_NAME} src/main.cpp ) -target_link_libraries( ${CMAKE_PROJECT_NAME} PUBLIC ${OPENSSL_LIBRARIES} ) +target_link_libraries( ${CMAKE_PROJECT_NAME} PUBLIC ${OPENSSL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) if (WIN32) if (CMAKE_SIZEOF_VOID_P EQUAL 8) diff --git a/src/main.cpp b/src/main.cpp index 45ad125..c035c48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,20 +30,74 @@ #include "ec.h" #include "key_search.h" +#ifdef HAVE_THREADS +#include +#include + +// Minium number of threads. +#define MIN_THREADS 2 + +// Number of threads to use. +static int n_threads; + +#define search_func thread_search +static void thread_search(const strlist_t& words, int n) { + + // create n_threads - 1 as we use main process also. + std::vector t(n_threads - 1); + // divide the number of results for all threads. + int d = n / n_threads; + // Also calculate the reminder (will be assigned to the main thread) + int m = n % n_threads; + + // Launch threads. + for(int i = 0; i < t.size(); i++) { + t[i] = std::thread(key_search, words, d); + } + + // Use main thread for 1 search + key_search(words, d + m); + + // Wait for all threads to compelete. + for(int i = 0; i < t.size(); i++) { + t[i].join(); + } +} +#else +#define search_func key_search +#endif + int main(int argc, char **argv) { // search [ ] if (argc > 2 && !strcmp(argv[1], "search")) { int n = 100; std::string search(argv[2]); + strlist_t words = strsplitwords(strtolower(search)); if (argc > 3) { n = atoi(argv[3]); } - std::cout << "Searching for " << n << " keys containing: " << search << std::endl; +#ifdef HAVE_THREADS + if (argc > 4) { + n_threads = atoi(argv[4]); + // Make sure we never go under min threads. + if (n_threads < MIN_THREADS) { + n_threads = MIN_THREADS; + } + } +# endif /* HAVE_THREADS */ + +std::cout << "Searching for " << n + << " keys containing: " << search +#ifdef HAVE_THREADS + << ", Using: " << n_threads << " threads" +#endif /* HAVE_THREADS */ + << std::endl; + + search_func(words, n); - key_search(strsplitwords(strtolower(search)), n); } else { struct ec_keypair pair; ec_generate_key(&pair);