From 668b23c5b00e3e6de1e263693222c3af6addd976 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 4 Jun 2017 20:52:21 +0300 Subject: [PATCH 01/92] Initial libuv support build. --- .gitignore | 1 + CMakeLists.txt | 153 ++----- cmake/FindUV.cmake | 8 + {win => res}/app.ico | Bin {win => res}/app.rc | 2 +- .../3rdparty}/jansson/CMakeLists.txt | 2 + {compat => src/3rdparty}/jansson/LICENSE | 0 {compat => src/3rdparty}/jansson/dump.c | 64 ++- {compat => src/3rdparty}/jansson/error.c | 0 {compat => src/3rdparty}/jansson/hashtable.c | 0 {compat => src/3rdparty}/jansson/hashtable.h | 0 .../3rdparty}/jansson/hashtable_seed.c | 4 +- {compat => src/3rdparty}/jansson/jansson.h | 8 +- .../3rdparty}/jansson/jansson_config.h | 0 .../3rdparty}/jansson/jansson_private.h | 1 + .../jansson/jansson_private_config.h | 0 {compat => src/3rdparty}/jansson/load.c | 49 +- {compat => src/3rdparty}/jansson/lookup3.h | 0 {compat => src/3rdparty}/jansson/memory.c | 0 .../3rdparty}/jansson/pack_unpack.c | 0 {compat => src/3rdparty}/jansson/strbuffer.c | 0 {compat => src/3rdparty}/jansson/strbuffer.h | 0 {compat => src/3rdparty}/jansson/strconv.c | 0 {compat => src/3rdparty}/jansson/utf.c | 0 {compat => src/3rdparty}/jansson/utf.h | 0 {compat => src/3rdparty}/jansson/value.c | 0 compat/winansi.c => src/3rdparty/winansi.cpp | 8 +- {compat => src/3rdparty}/winansi.h | 5 +- src/App.cpp | 84 ++++ utils/threads.h => src/App.h | 37 +- src/Console.cpp | 139 ++++++ src/Console.h | 81 ++++ src/Options.cpp | 433 ++++++++++++++++++ src/Options.h | 94 ++++ donate.h => src/donate.h | 0 src/interfaces/IClientListener.h | 40 ++ src/net/Client.cpp | 311 +++++++++++++ src/net/Client.h | 87 ++++ src/net/Network.cpp | 65 +++ src/net/Network.h | 56 +++ src/net/Network_win.cpp | 64 +++ src/net/Url.cpp | 93 ++++ src/net/Url.h | 49 ++ version.h => src/version.h | 8 +- src/xmrig.cpp | 31 ++ utils/applog.c | 151 ------ utils/applog.h | 75 --- 47 files changed, 1819 insertions(+), 384 deletions(-) create mode 100644 cmake/FindUV.cmake rename {win => res}/app.ico (100%) rename {win => res}/app.rc (96%) rename {compat => src/3rdparty}/jansson/CMakeLists.txt (91%) rename {compat => src/3rdparty}/jansson/LICENSE (100%) rename {compat => src/3rdparty}/jansson/dump.c (89%) rename {compat => src/3rdparty}/jansson/error.c (100%) rename {compat => src/3rdparty}/jansson/hashtable.c (100%) rename {compat => src/3rdparty}/jansson/hashtable.h (100%) rename {compat => src/3rdparty}/jansson/hashtable_seed.c (98%) rename {compat => src/3rdparty}/jansson/jansson.h (96%) rename {compat => src/3rdparty}/jansson/jansson_config.h (100%) rename {compat => src/3rdparty}/jansson/jansson_private.h (98%) rename {compat => src/3rdparty}/jansson/jansson_private_config.h (100%) rename {compat => src/3rdparty}/jansson/load.c (96%) rename {compat => src/3rdparty}/jansson/lookup3.h (100%) rename {compat => src/3rdparty}/jansson/memory.c (100%) rename {compat => src/3rdparty}/jansson/pack_unpack.c (100%) rename {compat => src/3rdparty}/jansson/strbuffer.c (100%) rename {compat => src/3rdparty}/jansson/strbuffer.h (100%) rename {compat => src/3rdparty}/jansson/strconv.c (100%) rename {compat => src/3rdparty}/jansson/utf.c (100%) rename {compat => src/3rdparty}/jansson/utf.h (100%) rename {compat => src/3rdparty}/jansson/value.c (100%) rename compat/winansi.c => src/3rdparty/winansi.cpp (98%) rename {compat => src/3rdparty}/winansi.h (92%) create mode 100644 src/App.cpp rename utils/threads.h => src/App.h (62%) create mode 100644 src/Console.cpp create mode 100644 src/Console.h create mode 100644 src/Options.cpp create mode 100644 src/Options.h rename donate.h => src/donate.h (100%) create mode 100644 src/interfaces/IClientListener.h create mode 100644 src/net/Client.cpp create mode 100644 src/net/Client.h create mode 100644 src/net/Network.cpp create mode 100644 src/net/Network.h create mode 100644 src/net/Network_win.cpp create mode 100644 src/net/Url.cpp create mode 100644 src/net/Url.h rename version.h => src/version.h (92%) create mode 100644 src/xmrig.cpp delete mode 100644 utils/applog.c delete mode 100644 utils/applog.h diff --git a/.gitignore b/.gitignore index 796b96d1..189b414f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /build +/CMakeLists.txt.user diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d30acd3..1f485e11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,99 +1,55 @@ cmake_minimum_required(VERSION 3.0) -project(xmrig C) - -option(WITH_LIBCPUID "Use Libcpuid" ON) -option(WITH_AEON "CryptoNight-Lite support" ON) +project(xmrig) set(HEADERS - compat.h - algo/cryptonight/cryptonight.h - algo/cryptonight/cryptonight_aesni.h - algo/cryptonight/cryptonight_softaes.h - elist.h - xmrig.h - version.h - options.h - cpu.h - persistent_memory.h - stratum.h - stats.h - util.h - donate.h - ) - -set(HEADERS_CRYPTO - crypto/c_groestl.h - crypto/c_blake256.h - crypto/c_jh.h - crypto/c_skein.h - ) - -set(HEADERS_COMPAT - compat/winansi.h - ) - -set(HEADERS_UTILS - utils/applog.h - utils/threads.h - utils/summary.h + src/App.h + src/interfaces/IClientListener.h + src/net/Client.h + src/net/Network.h + src/net/Url.h + src/Options.h + src/Console.h + src/version.h ) set(SOURCES - xmrig.c - algo/cryptonight/cryptonight.c - algo/cryptonight/cryptonight_av1_aesni.c - algo/cryptonight/cryptonight_av2_aesni_double.c - algo/cryptonight/cryptonight_av3_softaes.c - algo/cryptonight/cryptonight_av4_softaes_double.c - util.c - options.c - stratum.c - stats.c - memory.c - ) - -set(SOURCES_CRYPTO - crypto/c_keccak.c - crypto/c_groestl.c - crypto/c_blake256.c - crypto/c_jh.c - crypto/c_skein.c - crypto/soft_aes.c - ) - -set(SOURCES_UTILS - utils/applog.c - utils/summary.c + src/App.cpp + src/net/Client.cpp + src/net/Network.cpp + src/net/Url.cpp + src/Options.cpp + src/Console.cpp + src/xmrig.cpp ) if (WIN32) - set(SOURCES_OS win/cpu_win.c win/memory_win.c win/xmrig_win.c win/app.rc compat/winansi.c) - set(EXTRA_LIBS ws2_32) - add_definitions(/D_WIN32_WINNT=0x600) -elseif (APPLE) - set(SOURCES_OS mac/cpu_mac.c mac/memory_mac.c mac/xmrig_mac.c) + set(SOURCES_OS + res/app.rc + src/3rdparty/winansi.cpp + src/3rdparty/winansi.h + src/net/Network_win.cpp + ) + + set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) else() set(SOURCES_OS unix/cpu_unix.c unix/memory_unix.c unix/xmrig_unix.c) set(EXTRA_LIBS pthread) endif() -include_directories(.) -add_definitions(/DUSE_NATIVE_THREADS) add_definitions(/D_GNU_SOURCE) add_definitions(/DUNICODE) +add_definitions(/DAPP_DEBUG) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") + +find_package(UV REQUIRED) if ("${CMAKE_BUILD_TYPE}" STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wno-pointer-to-int-cast") - -if (CMAKE_C_COMPILER_ID MATCHES "Clang") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") -else() - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") -endif() - +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-use -fprofile-correction") @@ -102,45 +58,12 @@ if (WIN32) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") endif() -include_directories(compat/jansson) -add_subdirectory(compat/jansson) +include_directories(src) +include_directories(src/3rdparty) +include_directories(src/3rdparty/jansson) +include_directories(${UV_INCLUDE_DIR}) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") - -find_package(CURL REQUIRED) -include_directories(${CURL_INCLUDE_DIRS}) -add_definitions(/DCURL_STATICLIB) -link_directories(${CURL_LIBRARIES}) - -if (WITH_LIBCPUID) - add_subdirectory(compat/libcpuid) - - include_directories(compat/libcpuid) - set(CPUID_LIB cpuid) - set(SOURCES_CPUID cpu.c) -else() - add_definitions(/DXMRIG_NO_LIBCPUID) - set(SOURCES_CPUID cpu_stub.c) -endif() - -if (WITH_AEON) - set(SOURCES_AEON - algo/cryptonight-lite/cryptonight_lite_av1_aesni.c - algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c - algo/cryptonight-lite/cryptonight_lite_av3_softaes.c - algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c - algo/cryptonight-lite/cryptonight_lite_aesni.h - algo/cryptonight-lite/cryptonight_lite_softaes.h - ) -else() - add_definitions(/DXMRIG_NO_AEON) -endif() - -if (CMAKE_SIZEOF_VOID_P EQUAL 8) - add_executable(xmrig ${HEADERS} ${HEADERS_CRYPTO} ${SOURCES} ${SOURCES_CRYPTO} ${HEADERS_UTILS} ${SOURCES_UTILS} ${HEADERS_COMPAT} ${SOURCES_COMPAT} ${SOURCES_OS} ${SOURCES_CPUID} ${SOURCES_AEON}) - target_link_libraries(xmrig jansson curl ${CPUID_LIB} ${EXTRA_LIBS}) -else() - add_executable(xmrig32 ${HEADERS} ${HEADERS_CRYPTO} ${SOURCES} ${SOURCES_CRYPTO} ${HEADERS_UTILS} ${SOURCES_UTILS} ${HEADERS_COMPAT} ${SOURCES_COMPAT} ${SOURCES_OS} ${SOURCES_CPUID} ${SOURCES_AEON}) - target_link_libraries(xmrig32 jansson curl ${CPUID_LIB} ${EXTRA_LIBS}) -endif() +add_subdirectory(src/3rdparty/jansson) +add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS}) +target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS}) diff --git a/cmake/FindUV.cmake b/cmake/FindUV.cmake new file mode 100644 index 00000000..c8a95e7a --- /dev/null +++ b/cmake/FindUV.cmake @@ -0,0 +1,8 @@ +find_path(UV_INCLUDE_DIR NAMES uv.h) +find_library(UV_LIBRARY NAMES libuv) + +set(UV_LIBRARIES ${UV_LIBRARY}) +set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(UV DEFAULT_MSG UV_LIBRARY UV_INCLUDE_DIR) diff --git a/win/app.ico b/res/app.ico similarity index 100% rename from win/app.ico rename to res/app.ico diff --git a/win/app.rc b/res/app.rc similarity index 96% rename from win/app.rc rename to res/app.rc index cb47aa3c..800ce2dd 100644 --- a/win/app.rc +++ b/res/app.rc @@ -1,5 +1,5 @@ #include -#include "../version.h" +#include "../src/version.h" IDI_ICON1 ICON DISCARDABLE "app.ico" diff --git a/compat/jansson/CMakeLists.txt b/src/3rdparty/jansson/CMakeLists.txt similarity index 91% rename from compat/jansson/CMakeLists.txt rename to src/3rdparty/jansson/CMakeLists.txt index 9a73da22..7bd74c67 100644 --- a/compat/jansson/CMakeLists.txt +++ b/src/3rdparty/jansson/CMakeLists.txt @@ -6,6 +6,8 @@ add_definitions(-DHAVE_CONFIG_H) # Add the lib sources. file(GLOB JANSSON_SRC *.c) +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") + set(JANSSON_HDR_PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/hashtable.h ${CMAKE_CURRENT_SOURCE_DIR}/jansson_private.h diff --git a/compat/jansson/LICENSE b/src/3rdparty/jansson/LICENSE similarity index 100% rename from compat/jansson/LICENSE rename to src/3rdparty/jansson/LICENSE diff --git a/compat/jansson/dump.c b/src/3rdparty/jansson/dump.c similarity index 89% rename from compat/jansson/dump.c rename to src/3rdparty/jansson/dump.c index 6b1aabd4..a23fabb7 100644 --- a/compat/jansson/dump.c +++ b/src/3rdparty/jansson/dump.c @@ -9,13 +9,17 @@ #define _GNU_SOURCE #endif +#include "jansson_private.h" + #include #include #include #include +#ifdef HAVE_UNISTD_H +#include +#endif #include "jansson.h" -#include "jansson_private.h" #include "strbuffer.h" #include "utf.h" @@ -25,11 +29,28 @@ #define FLAGS_TO_INDENT(f) ((f) & 0x1F) #define FLAGS_TO_PRECISION(f) (((f) >> 11) & 0x1F) +struct buffer { + const size_t size; + size_t used; + char *data; +}; + static int dump_to_strbuffer(const char *buffer, size_t size, void *data) { return strbuffer_append_bytes((strbuffer_t *)data, buffer, size); } +static int dump_to_buffer(const char *buffer, size_t size, void *data) +{ + struct buffer *buf = (struct buffer *)data; + + if(buf->used + size <= buf->size) + memcpy(&buf->data[buf->used], buffer, size); + + buf->used += size; + return 0; +} + static int dump_to_file(const char *buffer, size_t size, void *data) { FILE *dest = (FILE *)data; @@ -38,6 +59,16 @@ static int dump_to_file(const char *buffer, size_t size, void *data) return 0; } +static int dump_to_fd(const char *buffer, size_t size, void *data) +{ + int *dest = (int *)data; +#ifdef HAVE_UNISTD_H + if(write(*dest, buffer, size) == (ssize_t)size) + return 0; +#endif + return -1; +} + /* 32 spaces (the maximum indentation size) */ static const char whitespace[] = " "; @@ -168,6 +199,10 @@ static int compare_keys(const void *key1, const void *key2) static int do_dump(const json_t *json, size_t flags, int depth, json_dump_callback_t dump, void *data) { + int embed = flags & JSON_EMBED; + + flags &= ~JSON_EMBED; + if(!json) return -1; @@ -227,11 +262,11 @@ static int do_dump(const json_t *json, size_t flags, int depth, n = json_array_size(json); - if(dump("[", 1, data)) + if(!embed && dump("[", 1, data)) goto array_error; if(n == 0) { array->visited = 0; - return dump("]", 1, data); + return embed ? 0 : dump("]", 1, data); } if(dump_indent(flags, depth + 1, 0, dump, data)) goto array_error; @@ -255,7 +290,7 @@ static int do_dump(const json_t *json, size_t flags, int depth, } array->visited = 0; - return dump("]", 1, data); + return embed ? 0 : dump("]", 1, data); array_error: array->visited = 0; @@ -286,11 +321,11 @@ static int do_dump(const json_t *json, size_t flags, int depth, iter = json_object_iter((json_t *)json); - if(dump("{", 1, data)) + if(!embed && dump("{", 1, data)) goto object_error; if(!iter) { object->visited = 0; - return dump("}", 1, data); + return embed ? 0 : dump("}", 1, data); } if(dump_indent(flags, depth + 1, 0, dump, data)) goto object_error; @@ -386,7 +421,7 @@ static int do_dump(const json_t *json, size_t flags, int depth, } object->visited = 0; - return dump("}", 1, data); + return embed ? 0 : dump("}", 1, data); object_error: object->visited = 0; @@ -416,11 +451,26 @@ char *json_dumps(const json_t *json, size_t flags) return result; } +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags) +{ + struct buffer buf = { size, 0, buffer }; + + if(json_dump_callback(json, dump_to_buffer, (void *)&buf, flags)) + return 0; + + return buf.used; +} + int json_dumpf(const json_t *json, FILE *output, size_t flags) { return json_dump_callback(json, dump_to_file, (void *)output, flags); } +int json_dumpfd(const json_t *json, int output, size_t flags) +{ + return json_dump_callback(json, dump_to_fd, (void *)&output, flags); +} + int json_dump_file(const json_t *json, const char *path, size_t flags) { int result; diff --git a/compat/jansson/error.c b/src/3rdparty/jansson/error.c similarity index 100% rename from compat/jansson/error.c rename to src/3rdparty/jansson/error.c diff --git a/compat/jansson/hashtable.c b/src/3rdparty/jansson/hashtable.c similarity index 100% rename from compat/jansson/hashtable.c rename to src/3rdparty/jansson/hashtable.c diff --git a/compat/jansson/hashtable.h b/src/3rdparty/jansson/hashtable.h similarity index 100% rename from compat/jansson/hashtable.h rename to src/3rdparty/jansson/hashtable.h diff --git a/compat/jansson/hashtable_seed.c b/src/3rdparty/jansson/hashtable_seed.c similarity index 98% rename from compat/jansson/hashtable_seed.c rename to src/3rdparty/jansson/hashtable_seed.c index 751e0e32..8aed5406 100644 --- a/compat/jansson/hashtable_seed.c +++ b/src/3rdparty/jansson/hashtable_seed.c @@ -168,12 +168,12 @@ static uint32_t generate_seed() { int done = 0; #if !defined(_WIN32) && defined(USE_URANDOM) - if (!done && seed_from_urandom(&seed) == 0) + if (seed_from_urandom(&seed) == 0) done = 1; #endif #if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI) - if (!done && seed_from_windows_cryptoapi(&seed) == 0) + if (seed_from_windows_cryptoapi(&seed) == 0) done = 1; #endif diff --git a/compat/jansson/jansson.h b/src/3rdparty/jansson/jansson.h similarity index 96% rename from compat/jansson/jansson.h rename to src/3rdparty/jansson/jansson.h index 591f2a94..a5927bd6 100644 --- a/compat/jansson/jansson.h +++ b/src/3rdparty/jansson/jansson.h @@ -21,11 +21,11 @@ extern "C" { /* version */ #define JANSSON_MAJOR_VERSION 2 -#define JANSSON_MINOR_VERSION 9 +#define JANSSON_MINOR_VERSION 10 #define JANSSON_MICRO_VERSION 0 /* Micro version is omitted if it's 0 */ -#define JANSSON_VERSION "2.9" +#define JANSSON_VERSION "2.10" /* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ @@ -273,6 +273,7 @@ typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data); json_t *json_loads(const char *input, size_t flags, json_error_t *error); json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error); json_t *json_loadf(FILE *input, size_t flags, json_error_t *error); +json_t *json_loadfd(int input, size_t flags, json_error_t *error); json_t *json_load_file(const char *path, size_t flags, json_error_t *error); json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error); @@ -288,11 +289,14 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla #define JSON_ENCODE_ANY 0x200 #define JSON_ESCAPE_SLASH 0x400 #define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11) +#define JSON_EMBED 0x10000 typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data); char *json_dumps(const json_t *json, size_t flags); +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); int json_dumpf(const json_t *json, FILE *output, size_t flags); +int json_dumpfd(const json_t *json, int output, size_t flags); int json_dump_file(const json_t *json, const char *path, size_t flags); int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags); diff --git a/compat/jansson/jansson_config.h b/src/3rdparty/jansson/jansson_config.h similarity index 100% rename from compat/jansson/jansson_config.h rename to src/3rdparty/jansson/jansson_config.h diff --git a/compat/jansson/jansson_private.h b/src/3rdparty/jansson/jansson_private.h similarity index 98% rename from compat/jansson/jansson_private.h rename to src/3rdparty/jansson/jansson_private.h index 4a4927bb..5ed96158 100644 --- a/compat/jansson/jansson_private.h +++ b/src/3rdparty/jansson/jansson_private.h @@ -8,6 +8,7 @@ #ifndef JANSSON_PRIVATE_H #define JANSSON_PRIVATE_H +#include "jansson_private_config.h" #include #include "jansson.h" #include "hashtable.h" diff --git a/compat/jansson/jansson_private_config.h b/src/3rdparty/jansson/jansson_private_config.h similarity index 100% rename from compat/jansson/jansson_private_config.h rename to src/3rdparty/jansson/jansson_private_config.h diff --git a/compat/jansson/load.c b/src/3rdparty/jansson/load.c similarity index 96% rename from compat/jansson/load.c rename to src/3rdparty/jansson/load.c index 7a8f96ec..c212489a 100644 --- a/compat/jansson/load.c +++ b/src/3rdparty/jansson/load.c @@ -9,15 +9,19 @@ #define _GNU_SOURCE #endif +#include "jansson_private.h" + #include #include #include #include #include #include +#ifdef HAVE_UNISTD_H +#include +#endif #include "jansson.h" -#include "jansson_private.h" #include "strbuffer.h" #include "utf.h" @@ -340,7 +344,7 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) /* control character */ lex_unget_unsave(lex, c); if(c == '\n') - error_set(error, lex, "unexpected newline", c); + error_set(error, lex, "unexpected newline"); else error_set(error, lex, "control character 0x%x", c); goto out; @@ -914,7 +918,7 @@ static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) typedef struct { const char *data; - int pos; + size_t pos; } string_data_t; static int string_get(void *data) @@ -1028,6 +1032,45 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) return result; } +static int fd_get_func(int *fd) +{ + uint8_t c; +#ifdef HAVE_UNISTD_H + if (read(*fd, &c, 1) == 1) + return c; +#endif + return EOF; +} + +json_t *json_loadfd(int input, size_t flags, json_error_t *error) +{ + lex_t lex; + const char *source; + json_t *result; + +#ifdef HAVE_UNISTD_H + if(input == STDIN_FILENO) + source = ""; + else +#endif + source = ""; + + jsonp_error_init(error, source); + + if (input < 0) { + error_set(error, NULL, "wrong arguments"); + return NULL; + } + + if(lex_init(&lex, (get_func)fd_get_func, flags, &input)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} + json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { json_t *result; diff --git a/compat/jansson/lookup3.h b/src/3rdparty/jansson/lookup3.h similarity index 100% rename from compat/jansson/lookup3.h rename to src/3rdparty/jansson/lookup3.h diff --git a/compat/jansson/memory.c b/src/3rdparty/jansson/memory.c similarity index 100% rename from compat/jansson/memory.c rename to src/3rdparty/jansson/memory.c diff --git a/compat/jansson/pack_unpack.c b/src/3rdparty/jansson/pack_unpack.c similarity index 100% rename from compat/jansson/pack_unpack.c rename to src/3rdparty/jansson/pack_unpack.c diff --git a/compat/jansson/strbuffer.c b/src/3rdparty/jansson/strbuffer.c similarity index 100% rename from compat/jansson/strbuffer.c rename to src/3rdparty/jansson/strbuffer.c diff --git a/compat/jansson/strbuffer.h b/src/3rdparty/jansson/strbuffer.h similarity index 100% rename from compat/jansson/strbuffer.h rename to src/3rdparty/jansson/strbuffer.h diff --git a/compat/jansson/strconv.c b/src/3rdparty/jansson/strconv.c similarity index 100% rename from compat/jansson/strconv.c rename to src/3rdparty/jansson/strconv.c diff --git a/compat/jansson/utf.c b/src/3rdparty/jansson/utf.c similarity index 100% rename from compat/jansson/utf.c rename to src/3rdparty/jansson/utf.c diff --git a/compat/jansson/utf.h b/src/3rdparty/jansson/utf.h similarity index 100% rename from compat/jansson/utf.h rename to src/3rdparty/jansson/utf.h diff --git a/compat/jansson/value.c b/src/3rdparty/jansson/value.c similarity index 100% rename from compat/jansson/value.c rename to src/3rdparty/jansson/value.c diff --git a/compat/winansi.c b/src/3rdparty/winansi.cpp similarity index 98% rename from compat/winansi.c rename to src/3rdparty/winansi.cpp index 41cecd6a..c6fbbc20 100644 --- a/compat/winansi.c +++ b/src/3rdparty/winansi.cpp @@ -11,7 +11,7 @@ #include #include -#include "compat/winansi.h" +#include "winansi.h" /* * Copyright 2008 Peter Harris */ @@ -344,8 +344,8 @@ int winansi_vfprintf(FILE *stream, const char *format, va_list list) #endif va_end(cp); - if (len > sizeof(small_buf) - 1) { - buf = malloc(len + 1); + if ((unsigned) len > sizeof(small_buf) - 1) { + buf = (char*)malloc(len + 1); if (!buf) goto abort; @@ -389,4 +389,4 @@ int winansi_printf(const char *format, ...) va_end(list); return rv; -} \ No newline at end of file +} diff --git a/compat/winansi.h b/src/3rdparty/winansi.h similarity index 92% rename from compat/winansi.h rename to src/3rdparty/winansi.h index 70c13734..47914c36 100644 --- a/compat/winansi.h +++ b/src/3rdparty/winansi.h @@ -1,12 +1,11 @@ /* * ANSI emulation wrappers */ -#ifdef WIN32 + #include #include #include -#define isatty(fd) _isatty(fd) #define fileno(fd) _fileno(fd) #ifdef __cplusplus @@ -28,5 +27,3 @@ extern "C" { #define printf winansi_printf #define fprintf winansi_fprintf #define vfprintf winansi_vfprintf - -#endif \ No newline at end of file diff --git a/src/App.cpp b/src/App.cpp new file mode 100644 index 00000000..ce9d2b2c --- /dev/null +++ b/src/App.cpp @@ -0,0 +1,84 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "App.h" +#include "Console.h" +#include "net/Client.h" +#include "net/Network.h" +#include "Options.h" +#include "version.h" + + +Client *client; +uv_timer_t timer_req; + + +void timer_cb(uv_timer_t* handle) { + LOG_DEBUG("TIMER"); + + client->disconnect(); +} + + +App::App(int argc, char **argv) +{ + Console::init(); + m_options = Options::parse(argc, argv); + + m_network = new Network(m_options); +} + + +App::~App() +{ + LOG_DEBUG("~APP"); + + free(m_network); + free(m_options); +} + + +App::exec() +{ + if (!m_options->isReady()) { + return 0; + } + + m_network->connect(); + +// uv_timer_init(uv_default_loop(), &timer_req); +// uv_timer_start(&timer_req, timer_cb, 5000, 5000); + + +// client = new Client(); +// client->connect("192.168.2.34", 3333); + + const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + uv_loop_close(uv_default_loop()); + + return r; +} diff --git a/utils/threads.h b/src/App.h similarity index 62% rename from utils/threads.h rename to src/App.h index a2ef09f3..a6aef6fa 100644 --- a/utils/threads.h +++ b/src/App.h @@ -21,21 +21,26 @@ * along with this program. If not, see . */ -#ifndef __THREADS_H__ -#define __THREADS_H__ +#ifndef __APP_H__ +#define __APP_H__ -#if defined(WIN32) && defined(USE_NATIVE_THREADS) -# include -# define MUTEX CRITICAL_SECTION -# define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex) -# define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex) -# define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex) -#else -# include -# define MUTEX pthread_mutex_t -# define MUTEX_INIT(mutex) pthread_mutex_init(&mutex, NULL) -# define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex) -# define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex) -#endif -#endif /* __THREADS_H__ */ +class Options; +class Network; + + +class App +{ +public: + App(int argc, char **argv); + ~App(); + + int exec(); + +private: + Options *m_options; + Network *m_network; +}; + + +#endif /* __APP_H__ */ diff --git a/src/Console.cpp b/src/Console.cpp new file mode 100644 index 00000000..f57a7141 --- /dev/null +++ b/src/Console.cpp @@ -0,0 +1,139 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + +#ifdef WIN32 +# include +# include "3rdparty/winansi.h" +#endif + +#include "Console.h" + + +Console *Console::m_self = nullptr; + + +void Console::init() +{ + if (!m_self) { + m_self = new Console(); + } +} + + +void Console::message(Console::Level level, const char* fmt, ...) +{ + time_t now = time(nullptr); + tm stime; + +# ifdef _WIN32 + localtime_s(&stime, &now); +# else + localtime_r(&now, &stime); +# endif + + va_list ap; + va_start(ap, fmt); + + const char* color = nullptr; + if (m_colors) { + switch (level) { + case ERR: + color = kCL_RED; + break; + + case WARNING: + color = kCL_YELLOW; + break; + + case NOTICE: + color = kCL_WHITE; + break; + + case DEBUG: + color = kCL_GRAY; + break; + + default: + color = ""; + break; + } + } + + const size_t len = 64 + strlen(fmt) + 2; + char *buf = static_cast(alloca(len)); + + sprintf(buf, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n", + stime.tm_year + 1900, + stime.tm_mon + 1, + stime.tm_mday, + stime.tm_hour, + stime.tm_min, + stime.tm_sec, + color, + fmt, + m_colors ? kCL_N : "" + ); + + uv_mutex_lock(&m_mutex); + + vfprintf(stdout, buf, ap); + fflush(stdout); + + uv_mutex_unlock(&m_mutex); + + va_end(ap); +} + + +void Console::text(const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + const int len = 64 + strlen(fmt) + 2; + char *buf = static_cast(alloca(len)); + + sprintf(buf, "%s%s\n", + fmt, + m_colors ? kCL_N : "" + ); + + uv_mutex_lock(&m_mutex); + + vfprintf(stdout, buf, ap); + fflush(stdout); + + uv_mutex_unlock(&m_mutex); + + va_end(ap); +} + + +Console::Console() : + m_colors(true) +{ + uv_mutex_init(&m_mutex); +} diff --git a/src/Console.h b/src/Console.h new file mode 100644 index 00000000..a02e3761 --- /dev/null +++ b/src/Console.h @@ -0,0 +1,81 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONSOLE_H__ +#define __CONSOLE_H__ + + +#include + + +class Console +{ +public: + enum Level { + ERR, + WARNING, + NOTICE, + INFO, + DEBUG + }; + + constexpr static const char* kCL_N = "\x1B[0m"; + constexpr static const char* kCL_RED = "\x1B[31m"; + constexpr static const char* kCL_YELLOW = "\x1B[33m"; + constexpr static const char* kCL_WHITE = "\x1B[01;37m"; + +# ifdef WIN32 + constexpr static const char* kCL_GRAY = "\x1B[01;30m"; +# else + constexpr static const char* kCL_GRAY = "\x1B[90m"; +# endif + + static inline Console* i() { return m_self; } + static void init(); + + void message(Level level, const char* fmt, ...); + void text(const char* fmt, ...); + +private: + Console(); + + static Console *m_self; + bool m_colors; + uv_mutex_t m_mutex; +}; + + +#define LOG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) +#define LOG_WARN(x, ...) Console::i()->message(Console::WARNING, x, ##__VA_ARGS__) +#define LOG_NOTICE(x, ...) Console::i()->message(Console::NOTICE, x, ##__VA_ARGS__) +#define LOG_INFO(x, ...) Console::i()->message(Console::INFO, x, ##__VA_ARGS__) + +#ifdef APP_DEBUG +# define LOG_DEBUG(x, ...) Console::i()->message(Console::DEBUG, x, ##__VA_ARGS__) +# define LOG_DEBUG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) +#else +# define LOG_DEBUG(x, ...) +# define LOG_DEBUG_ERR(x, ...) +#endif + +#endif /* __CONSOLE_H__ */ diff --git a/src/Options.cpp b/src/Options.cpp new file mode 100644 index 00000000..5a8551c4 --- /dev/null +++ b/src/Options.cpp @@ -0,0 +1,433 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include + + +#include "Console.h" +#include "Options.h" +#include "version.h" +#include "donate.h" +#include "net/Url.h" + + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + + +Options *Options::m_self = nullptr; + + +static char const usage[] = "\ +Usage: " APP_ID " [OPTIONS]\n\ +Options:\n\ + -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ + -o, --url=URL URL of mining server\n\ + -b, --backup-url=URL URL of backup mining server\n\ + -O, --userpass=U:P username:password pair for mining server\n\ + -u, --user=USERNAME username for mining server\n\ + -p, --pass=PASSWORD password for mining server\n\ + -t, --threads=N number of miner threads\n\ + -v, --av=N algorithm variation, 0 auto select\n\ + -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ + -r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ + -R, --retry-pause=N time to pause between retries (default: 5)\n\ + --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ + --no-color disable colored output\n\ + --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ + -B, --background run the miner in the background\n\ + -c, --config=FILE load a JSON-format configuration file\n\ + --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ + --safe safe adjust threads and av settings for current CPU\n\ + --nicehash enable nicehash support\n\ + -h, --help display this help and exit\n\ + -V, --version output version information and exit\n\ +"; + + +static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:"; + + +static struct option const options[] = { + { "algo", 1, nullptr, 'a' }, + { "av", 1, nullptr, 'v' }, + { "background", 0, nullptr, 'B' }, + { "backup-url", 1, nullptr, 'b' }, + { "config", 1, nullptr, 'c' }, + { "cpu-affinity", 1, nullptr, 1020 }, + { "donate-level", 1, nullptr, 1003 }, + { "help", 0, nullptr, 'h' }, + { "keepalive", 0, nullptr ,'k' }, + { "max-cpu-usage", 1, nullptr, 1004 }, + { "nicehash", 0, nullptr, 1006 }, + { "no-color", 0, nullptr, 1002 }, + { "pass", 1, nullptr, 'p' }, + { "retries", 1, nullptr, 'r' }, + { "retry-pause", 1, nullptr, 'R' }, + { "safe", 0, nullptr, 1005 }, + { "threads", 1, nullptr, 't' }, + { "url", 1, nullptr, 'o' }, + { "user", 1, nullptr, 'u' }, + { "userpass", 1, nullptr, 'O' }, + { "version", 0, nullptr, 'V' }, + { 0, 0, 0, 0 } +}; + + +static const char *algo_names[] = { + "cryptonight", +# ifndef XMRIG_NO_AEON + "cryptonight-lite" +# endif +}; + + +Options *Options::parse(int argc, char **argv) +{ + if (!m_self) { + m_self = new Options(argc, argv); + } + + return m_self; +} + + +Options::Options(int argc, char **argv) : + m_background(false), + m_colors(true), + m_doubleHash(false), + m_keepalive(false), + m_nicehash(false), + m_ready(false), + m_safe(false), + m_pass(nullptr), + m_user(nullptr), + m_algo(0), + m_algoVariant(0), + m_donateLevel(DONATE_LEVEL), + m_maxCpuUsage(75), + m_retries(5), + m_retryPause(5), + m_threads(0), + m_affinity(-1L), + m_backupUrl(nullptr), + m_url(nullptr) +{ + int key; + + while (1) { + key = getopt_long(argc, argv, short_options, options, NULL); + if (key < 0) { + break; + } + + if (!parseArg(key, optarg)) { + return; + } + } + + if (optind < argc) { + fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]); + return; + } + + if (!m_url) { + LOG_ERR("No pool URL supplied. Exiting.", argv[0]); + return; + } + + if (!m_nicehash && m_url->isNicehash()) { + m_nicehash = true; + } + + if (!m_user) { + m_user = strdup("x"); + } + + if (!m_pass) { + m_pass = strdup("x"); + } + + m_ready = true; +} + + +Options::~Options() +{ + delete m_url; + delete m_backupUrl; + + free(m_user); + free(m_pass); +} + + +bool Options::parseArg(int key, char *arg) +{ +// char *p; + int v; +// uint64_t ul; + Url *url; + + switch (key) { + case 'a': /* --algo */ + if (!setAlgo(arg)) { + return false; + } + break; + + case 'O': /* --userpass */ + if (!setUserpass(arg)) { + return false; + } + break; + + case 'o': /* --url */ + url = parseUrl(arg); + if (url) { + free(m_url); + m_url = url; + } + break; + + case 'b': /* --backup-url */ + url = parseUrl(arg); + if (url) { + free(m_backupUrl); + m_backupUrl = url; + } + break; + + case 'u': /* --user */ + free(m_user); + m_user = strdup(arg); + break; + + case 'p': /* --pass */ + free(m_pass); + m_pass = strdup(arg); + break; + + case 'r': /* --retries */ + v = atoi(arg); + if (v < 1 || v > 1000) { + showUsage(1); + return false; + } + + m_retries = v; + break; + + case 'R': /* --retry-pause */ + v = atoi(arg); + if (v < 1 || v > 3600) { + showUsage(1); + return false; + } + + m_retryPause = v; + break; + + case 't': /* --threads */ + v = atoi(arg); + if (v < 1 || v > 1024) { + showUsage(1); + return false; + } + + m_threads = v; + break; + + case 1004: /* --max-cpu-usage */ + v = atoi(arg); + if (v < 1 || v > 100) { + showUsage(1); + return false; + } + + m_maxCpuUsage = v; + break; + + case 1005: /* --safe */ + m_safe = true; + break; + + case 'k': /* --keepalive */ + m_keepalive = true; + break; + + case 'V': /* --version */ + showVersion(); + return false; + + case 'h': /* --help */ + showUsage(0); + return false; + + case 'B': /* --background */ + m_background = true; + m_colors = false; + break; + + case 'v': /* --av */ + v = atoi(arg); + if (v < 0 || v > 1000) { + showUsage(1); + return false; + } + + m_algoVariant = v; + break; + + case 1020: /* --cpu-affinity */ +// p = strstr(arg, "0x"); +// ul = p ? strtoul(p, NULL, 16) : atol(arg); +// if (ul > (1UL << cpu_info.total_logical_cpus) -1) { +// ul = -1; +// } + +// opt_affinity = ul; + break; + + case 1002: /* --no-color */ + m_colors = false; + break; + + case 1003: /* --donate-level */ + v = atoi(arg); + if (v < 1 || v > 99) { + showUsage(1); + return false; + } + + m_donateLevel = v; + break; + + case 1006: /* --nicehash */ + m_nicehash = true; + break; + + default: + showUsage(1); + return false; + } + + return true; +} + + +Url *Options::parseUrl(const char *arg) const +{ + auto url = new Url(arg); + if (!url->isValid()) { + delete url; + return nullptr; + } + + return url; +} + + +void Options::showUsage(int status) const +{ + if (status) { + fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n"); + } + else { + printf(usage); + } +} + + +void Options::showVersion() +{ + printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ + + #ifdef __GNUC__ + " with GCC"); + printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); + #endif + + printf("\n features:" + #ifdef __i386__ + " i386" + #endif + #ifdef __x86_64__ + " x86_64" + #endif + #ifdef __AES__ + " AES-NI" + #endif + "\n"); + + printf("\nlibuv/%s\n", uv_version_string()); + printf("libjansson/%s\n", JANSSON_VERSION); +} + + +bool Options::setAlgo(const char *algo) +{ + for (size_t i = 0; i < ARRAY_SIZE(algo_names); i++) { + if (algo_names[i] && !strcmp(algo, algo_names[i])) { + m_algo = i; + break; + } + +# ifndef XMRIG_NO_AEON + if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light")) { + m_algo = ALGO_CRYPTONIGHT_LITE; + break; + } +# endif + + if (i == ARRAY_SIZE(algo_names) - 1) { + showUsage(1); + return false; + } + } + + return true; +} + + +bool Options::setUserpass(const char *userpass) +{ + char *p = strchr(userpass, ':'); + if (!p) { + showUsage(1); + return false; + } + + free(m_user); + free(m_pass); + + m_user = static_cast(calloc(p - userpass + 1, 1)); + strncpy(m_user, userpass, p - userpass); + m_pass = strdup(p + 1); + + return true; +} diff --git a/src/Options.h b/src/Options.h new file mode 100644 index 00000000..eccfbcff --- /dev/null +++ b/src/Options.h @@ -0,0 +1,94 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __OPTIONS_H__ +#define __OPTIONS_H__ + + +#include + + +class Url; + + +class Options +{ +public: + enum Algo { + ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ + ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ + }; + + enum AlgoVariant { + AV0_AUTO, + AV1_AESNI, + AV2_AESNI_DOUBLE, + AV3_SOFT_AES, + AV4_SOFT_AES_DOUBLE, + AV_MAX + }; + + static inline Options* i() { return m_self; } + static Options *parse(int argc, char **argv); + + inline bool isReady() const { return m_ready; } + inline const char *pass() const { return m_pass; } + inline const char *user() const { return m_user; } + inline Url *url() const { return m_url; } + +private: + Options(int argc, char **argv); + ~Options(); + + static Options *m_self; + + bool parseArg(int key, char *arg); + Url *parseUrl(const char *arg) const; + void showUsage(int status) const; + void showVersion(void); + + bool setAlgo(const char *algo); + bool setUserpass(const char *userpass); + + bool m_background; + bool m_colors; + bool m_doubleHash; + bool m_keepalive; + bool m_nicehash; + bool m_ready; + bool m_safe; + char *m_pass; + char *m_user; + int m_algo; + int m_algoVariant; + int m_donateLevel; + int m_maxCpuUsage; + int m_retries; + int m_retryPause; + int m_threads; + int64_t m_affinity; + Url *m_backupUrl; + Url *m_url; +}; + +#endif /* __OPTIONS_H__ */ diff --git a/donate.h b/src/donate.h similarity index 100% rename from donate.h rename to src/donate.h diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h new file mode 100644 index 00000000..26ff10aa --- /dev/null +++ b/src/interfaces/IClientListener.h @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ICLIENTLISTENER_H__ +#define __ICLIENTLISTENER_H__ + + +class Client; + + +class IClientListener +{ +public: + virtual ~IClientListener() {} + + virtual void onLoginCredentialsRequired(Client *client) = 0; +}; + + +#endif // __ICLIENTLISTENER_H__ diff --git a/src/net/Client.cpp b/src/net/Client.cpp new file mode 100644 index 00000000..cb77ebad --- /dev/null +++ b/src/net/Client.cpp @@ -0,0 +1,311 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "Console.h" +#include "interfaces/IClientListener.h" +#include "net/Client.h" +#include "net/Url.h" + + +Client::Client(IClientListener *listener) : + m_host(nullptr), + m_listener(listener), + m_recvBufPos(0), + m_state(UnconnectedState), + m_port(0), + m_stream(nullptr), + m_socket(nullptr) +{ + m_resolver.data = this; + + m_hints.ai_family = PF_INET; + m_hints.ai_socktype = SOCK_STREAM; + m_hints.ai_protocol = IPPROTO_TCP; + m_hints.ai_flags = 0; + + m_recvBuf.base = static_cast(malloc(kRecvBufSize)); + m_recvBuf.len = kRecvBufSize; +} + + +Client::~Client() +{ + free(m_recvBuf.base); + free(m_socket); + free(m_host); +} + + +/** + * @brief Connect to server. + * + * @param host + * @param port + */ +void Client::connect(const char *host, uint16_t port) +{ + m_host = strdup(host); + m_port = port; + + LOG_DEBUG("[%s:%u] connect", m_host, m_port); + + resolve(host); +} + + +/** + * @brief Connect to server. + * + * @param url + */ +void Client::connect(const Url *url) +{ + connect(url->host(), url->port()); +} + + +void Client::disconnect() +{ + close(); +} + + +void Client::login(const char *user, const char *pass, const char *agent) +{ + const size_t size = 96 + strlen(user) + strlen(pass) + strlen(agent); + char *req = static_cast(malloc(size)); + snprintf(req, size, "{\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"},\"id\":1}\n", user, pass, agent); + + send(req); +} + + +/** + * @brief Send raw data to server. + * + * @param data + */ +void Client::send(char *data) +{ + LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_host, m_port, strlen(data), data); + if (state() != ConnectedState) { + LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_host, m_port, m_state); + return; + } + + uv_buf_t buf = uv_buf_init(data, strlen(data)); + + uv_write_t *req = static_cast(malloc(sizeof(uv_write_t))); + req->data = buf.base; + + uv_write(req, m_stream, &buf, 1, [](uv_write_t *req, int status) { + if (status) { + auto client = getClient(req->data); + LOG_ERR("[%s:%u] write error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + } + + free(req->data); + free(req); + }); +} + + +int Client::resolve(const char *host) +{ + setState(HostLookupState); + + m_recvBufPos = 0; + + const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); + if (r) { + LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_port, uv_strerror(r)); + return 1; + } + + return 0; +} + + +void Client::close() +{ + if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) { + return; + } + + setState(ClosingState); + uv_close(reinterpret_cast(m_socket), Client::onClose); +} + + +void Client::connect(struct sockaddr *addr) +{ + setState(ConnectingState); + + reinterpret_cast(addr)->sin_port = htons(m_port); + free(m_socket); + + uv_connect_t *req = (uv_connect_t*) malloc(sizeof(uv_connect_t)); + req->data = this; + + m_socket = static_cast(malloc(sizeof(uv_tcp_t))); + m_socket->data = this; + + uv_tcp_init(uv_default_loop(), m_socket); + uv_tcp_nodelay(m_socket, 1); + uv_tcp_keepalive(m_socket, 1, 60); + + uv_tcp_connect(req, m_socket, (const sockaddr*) addr, Client::onConnect); +} + + +void Client::parse(char *line, size_t len) +{ + line[len - 1] = '\0'; + + LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_host, m_port, len, line); + + json_error_t err; + json_t *val = json_loads(line, 0, &err); + + if (!val) { + LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_host, m_port, err.text); + return; + } +} + + +void Client::setState(SocketState state) +{ + LOG_DEBUG("[%s:%u] state: %d", m_host, m_port, state); + + if (m_state == state) { + return; + } + + m_state = state; +} + + +void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) +{ + auto client = getClient(handle->data); + + buf->base = &client->m_recvBuf.base[client->m_recvBufPos]; + buf->len = client->m_recvBuf.len - client->m_recvBufPos; +} + + +void Client::onClose(uv_handle_t *handle) +{ + auto client = getClient(handle->data); + + free(client->m_socket); + + client->m_stream = nullptr; + client->m_socket = nullptr; + client->setState(UnconnectedState); +} + + +void Client::onConnect(uv_connect_t *req, int status) +{ + auto client = getClient(req->data); + if (status < 0) { + LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + free(req); + return; + } + + client->m_stream = static_cast(req->handle); + client->m_stream->data = req->data; + client->setState(ConnectedState); + + uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead); + free(req); + + client->m_listener->onLoginCredentialsRequired(client); +} + + +void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) +{ + auto client = getClient(stream->data); + if (nread < 0) { + if (nread != UV_EOF) { + LOG_ERR("[%s:%u] read error: \"%s\"", client->m_host, client->m_port, uv_strerror(nread)); + } + + client->close(); + return; + } + + client->m_recvBufPos += nread; + + char* end; + char* start = client->m_recvBuf.base; + size_t remaining = client->m_recvBufPos; + + while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) { + end++; + size_t len = end - start; + client->parse(start, len); + + remaining -= len; + start = end; + } + + if (remaining == 0) { + client->m_recvBufPos = 0; + return; + } + + if (start == client->m_recvBuf.base) { + return; + } + + memcpy(client->m_recvBuf.base, start, remaining); + client->m_recvBufPos = remaining; +} + + +void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) +{ + auto client = getClient(req->data); + if (status < 0) { + LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + return; + } + + client->connect(res->ai_addr); + uv_freeaddrinfo(res); +} + + +Client *Client::getClient(void *data) +{ + return static_cast(data); +} diff --git a/src/net/Client.h b/src/net/Client.h new file mode 100644 index 00000000..181ea641 --- /dev/null +++ b/src/net/Client.h @@ -0,0 +1,87 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CLIENT_H__ +#define __CLIENT_H__ + + +#include + + +class Url; +class IClientListener; + + +class Client +{ +public: + enum SocketState { + UnconnectedState, + HostLookupState, + ConnectingState, + ConnectedState, + ClosingState + }; + + Client(IClientListener *listener); + ~Client(); + + void connect(const char *host, uint16_t port); + void connect(const Url *url); + void disconnect(); + void login(const char *user, const char *pass, const char *agent); + void send(char *data); + + inline SocketState state() const { return m_state; } + +private: + constexpr static size_t kRecvBufSize = 4096; + + int resolve(const char *host); + void close(); + void connect(struct sockaddr *addr); + void parse(char *line, size_t len); + void setState(SocketState state); + + static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); + static void onClose(uv_handle_t *handle); + static void onConnect(uv_connect_t *req, int status); + static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); + static void onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res); + + static Client *getClient(void *data); + + char *m_host; + IClientListener *m_listener; + size_t m_recvBufPos; + SocketState m_state; + struct addrinfo m_hints; + uint16_t m_port; + uv_buf_t m_recvBuf; + uv_getaddrinfo_t m_resolver; + uv_stream_t *m_stream; + uv_tcp_t *m_socket; +}; + + +#endif /* __CLIENT_H__ */ diff --git a/src/net/Network.cpp b/src/net/Network.cpp new file mode 100644 index 00000000..91b62621 --- /dev/null +++ b/src/net/Network.cpp @@ -0,0 +1,65 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "Console.h" +#include "net/Client.h" +#include "net/Network.h" +#include "Options.h" + + +Network::Network(const Options *options) : + m_backupPool(nullptr), + m_donatePool(nullptr), + m_pool(nullptr), + m_options(options) +{ + m_agent = userAgent(); + m_pool = new Client(this); +} + + +Network::~Network() +{ + delete m_pool; + delete m_donatePool; + delete m_backupPool; + + free(m_agent); +} + + +void Network::connect() +{ + m_pool->connect(m_options->url()); +// LOG_DEBUG("XX %s", m_options->url()); +} + + +void Network::onLoginCredentialsRequired(Client *client) +{ + client->login(m_options->user(), m_options->pass(), m_agent); +} diff --git a/src/net/Network.h b/src/net/Network.h new file mode 100644 index 00000000..5ee7c295 --- /dev/null +++ b/src/net/Network.h @@ -0,0 +1,56 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __NETWORK_H__ +#define __NETWORK_H__ + + +#include "interfaces/IClientListener.h" + + +class Options; + + +class Network : public IClientListener +{ +public: + Network(const Options *options); + ~Network(); + + void connect(); + + static char *userAgent(); + +protected: + void onLoginCredentialsRequired(Client *client) override; + +private: + char *m_agent; + Client *m_backupPool; + Client *m_donatePool; + Client *m_pool; + const Options *m_options; +}; + + +#endif /* __NETWORK_H__ */ diff --git a/src/net/Network_win.cpp b/src/net/Network_win.cpp new file mode 100644 index 00000000..432ea71e --- /dev/null +++ b/src/net/Network_win.cpp @@ -0,0 +1,64 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#include "net/Network.h" +#include "version.h" + + +static inline OSVERSIONINFOEX winOsVersion() +{ + typedef NTSTATUS (NTAPI *RtlGetVersionFunction)(LPOSVERSIONINFO); + OSVERSIONINFOEX result = { sizeof(OSVERSIONINFOEX), 0, 0, 0, 0, {'\0'}, 0, 0, 0, 0, 0}; + + HMODULE ntdll = GetModuleHandleW(L"ntdll.dll"); + if (ntdll ) { + RtlGetVersionFunction pRtlGetVersion = reinterpret_cast(GetProcAddress(ntdll, "RtlGetVersion")); + + if (pRtlGetVersion) { + pRtlGetVersion((LPOSVERSIONINFO) &result); + } + } + + return result; +} + + +char *Network::userAgent() +{ + const auto osver = winOsVersion(); + + char *buf = static_cast(malloc(128)); + +# ifdef __GNUC__ + snprintf(buf, 128, "%s/%s (Windows NT %lu.%lu; Win64; x64) libuv/%s gcc/%d.%d.%d", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion, uv_version_string(), __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# else + snprintf(buf, 128, "%s/%s (Windows NT %lu.%lu; Win64; x64) libuv/%s", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion, uv_version_string()); +# endif + + return buf; +} diff --git a/src/net/Url.cpp b/src/net/Url.cpp new file mode 100644 index 00000000..f54b0b92 --- /dev/null +++ b/src/net/Url.cpp @@ -0,0 +1,93 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#include "net/Url.h" + + +/** + * @brief Parse url. + * + * Valid urls: + * example.com + * example.com:3333 + * stratum+tcp://example.com + * stratum+tcp://example.com:3333 + * + * @param url + */ +Url::Url(const char *url) : + m_host(nullptr), + m_port(3333) +{ + const char *p = strstr(url, "://"); + const char *base = url; + + if (p) { + if (strncasecmp(url, "stratum+tcp://", 14)) { + return; + } + + base = url + 14; + } + + if (!strlen(base) || *base == '/') { + return; + } + + char *port = strchr(base, ':'); + if (!port) { + m_host = strdup(base); + return; + } + + const size_t size = port++ - base + 1; + m_host = static_cast(malloc(size)); + memcpy(m_host, base, size - 1); + m_host[size - 1] = '\0'; + + m_port = strtol(port, nullptr, 10); +} + + +Url::Url(const char *host, uint16_t port) : + m_port(port) +{ + m_host = strdup(host); +} + + +Url::~Url() +{ + free(m_host); +} + + +bool Url::isNicehash() const +{ + return isValid() && strstr(m_host, ".nicehash.com"); +} diff --git a/src/net/Url.h b/src/net/Url.h new file mode 100644 index 00000000..a0e2d48d --- /dev/null +++ b/src/net/Url.h @@ -0,0 +1,49 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __URL_H__ +#define __URL_H__ + + +#include + + +class Url +{ +public: + Url(const char *url); + Url(const char *host, uint16_t port); + ~Url(); + + bool isNicehash() const; + + inline bool isValid() const { return m_host && m_port > 0; } + inline const char *host() const { return m_host; } + inline uint16_t port() const { return m_port; } + +private: + char *m_host; + uint16_t m_port; +}; + +#endif /* __URL_H__ */ diff --git a/version.h b/src/version.h similarity index 92% rename from version.h rename to src/version.h index 330d9697..d7bde178 100644 --- a/version.h +++ b/src/version.h @@ -27,14 +27,14 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "0.8.3" +#define APP_VERSION "1.0.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" -#define APP_VER_MAJOR 0 -#define APP_VER_MINOR 8 -#define APP_VER_BUILD 3 +#define APP_VER_MAJOR 1 +#define APP_VER_MINOR 0 +#define APP_VER_BUILD 0 #define APP_VER_REV 0 #endif /* __VERSION_H__ */ diff --git a/src/xmrig.cpp b/src/xmrig.cpp new file mode 100644 index 00000000..4b4afcd2 --- /dev/null +++ b/src/xmrig.cpp @@ -0,0 +1,31 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "App.h" + + +int main(int argc, char **argv) { + auto app = new App(argc, argv); + + return app->exec(); +} diff --git a/utils/applog.c b/utils/applog.c deleted file mode 100644 index e0043c86..00000000 --- a/utils/applog.c +++ /dev/null @@ -1,151 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "xmrig.h" -#include "applog.h" -#include "threads.h" -#include -#include - -#ifdef WIN32 -# include "compat/winansi.h" -#endif - -#include "options.h" - - -MUTEX applog_mutex; - - -void applog_init() -{ - MUTEX_INIT(applog_mutex); -} - - -void applog(int prio, const char *fmt, ...) -{ - if (opt_background) { - return; - } - - va_list ap; - va_start(ap, fmt); - - struct tm tm; - struct tm *tm_p; - time_t now = time(NULL); - - MUTEX_LOCK(applog_mutex); - tm_p = localtime(&now); - memcpy(&tm, tm_p, sizeof(tm)); - MUTEX_UNLOCK(applog_mutex); - - const char* color = ""; - - if (opt_colors) { - switch (prio) { - case LOG_ERR: color = CL_RED; break; - case LOG_WARNING: color = CL_YLW; break; - case LOG_NOTICE: color = CL_WHT; break; - case LOG_INFO: color = ""; break; - case LOG_DEBUG: color = CL_GRY; break; - - case LOG_BLUE: - prio = LOG_NOTICE; - color = CL_CYN; - break; - - case LOG_GREEN: - prio = LOG_NOTICE; - color = CL_LGR; - break; - } - } - - const int len = 64 + strlen(fmt) + 2; - char *f = alloca(len); - - sprintf(f, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n", - tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec, - color, - fmt, - opt_colors ? CL_N : "" - ); - - MUTEX_LOCK(applog_mutex); - vfprintf(stderr, f, ap); - fflush(stderr); - MUTEX_UNLOCK(applog_mutex); - - va_end(ap); -} - - -void applog_notime(int prio, const char *fmt, ...) -{ - if (opt_background) { - return; - } - - va_list ap; - va_start(ap, fmt); - - const char* color = ""; - - if (opt_colors) { - switch (prio) { - case LOG_ERR: color = CL_RED; break; - case LOG_WARNING: color = CL_LYL; break; - case LOG_NOTICE: color = CL_WHT; break; - case LOG_INFO: color = ""; break; - case LOG_DEBUG: color = CL_GRY; break; - - case LOG_BLUE: - prio = LOG_NOTICE; - color = CL_CYN; - break; - } - } - - const int len = 64 + strlen(fmt) + 2; - char *f = alloca(len); - - sprintf(f, "%s%s%s\n", - color, - fmt, - opt_colors ? CL_N : "" - ); - - MUTEX_LOCK(applog_mutex); - vfprintf(stderr, f, ap); - fflush(stderr); - MUTEX_UNLOCK(applog_mutex); - - va_end(ap); -} diff --git a/utils/applog.h b/utils/applog.h deleted file mode 100644 index 24a73226..00000000 --- a/utils/applog.h +++ /dev/null @@ -1,75 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __APPLOG_H__ -#define __APPLOG_H__ - -enum { - LOG_ERR, - LOG_WARNING, - LOG_NOTICE, - LOG_INFO, - LOG_DEBUG, - LOG_BLUE = 0x10, - LOG_GREEN -}; - -#define CL_N "\x1B[0m" -#define CL_RED "\x1B[31m" -#define CL_GRN "\x1B[32m" -#define CL_YLW "\x1B[33m" -#define CL_BLU "\x1B[34m" -#define CL_MAG "\x1B[35m" -#define CL_CYN "\x1B[36m" - -#define CL_BLK "\x1B[22;30m" /* black */ -#define CL_RD2 "\x1B[22;31m" /* red */ -#define CL_GR2 "\x1B[22;32m" /* green */ -#define CL_BRW "\x1B[22;33m" /* brown */ -#define CL_BL2 "\x1B[22;34m" /* blue */ -#define CL_MA2 "\x1B[22;35m" /* magenta */ -#define CL_CY2 "\x1B[22;36m" /* cyan */ -#define CL_SIL "\x1B[22;37m" /* gray */ - -#ifdef WIN32 -#define CL_GRY "\x1B[01;30m" /* dark gray */ -#else -#define CL_GRY "\x1B[90m" /* dark gray selectable in putty */ -#endif -#define CL_LRD "\x1B[01;31m" /* light red */ -#define CL_LGR "\x1B[01;32m" /* light green */ -#define CL_LYL "\x1B[01;33m" /* light yellow */ -#define CL_LBL "\x1B[01;34m" /* light blue */ -#define CL_LMA "\x1B[01;35m" /* light magenta */ -#define CL_LCY "\x1B[01;36m" /* light cyan */ - -#define CL_WHT "\x1B[01;37m" /* white */ - -#define OPT_COLOR(color, text) (opt_colors ? (color text CL_N) : text) - - -void applog_init(); -void applog(int prio, const char *fmt, ...); -void applog_notime(int prio, const char *fmt, ...); - -#endif /* __APPLOG_H__ */ From 7deee3240b09e88a26f82c6318ffce2b5c8627fe Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 6 Jun 2017 06:05:17 +0300 Subject: [PATCH 02/92] Handle jsonrpc errors. --- src/net/Client.cpp | 40 ++++++++++++++++++++++++++++++++++++---- src/net/Client.h | 5 +++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index cb77ebad..8b80cd25 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -22,9 +22,6 @@ */ -#include - - #include "Console.h" #include "interfaces/IClientListener.h" #include "net/Client.h" @@ -34,6 +31,8 @@ Client::Client(IClientListener *listener) : m_host(nullptr), m_listener(listener), + m_retries(0), + m_sequence(1), m_recvBufPos(0), m_state(UnconnectedState), m_port(0), @@ -96,9 +95,11 @@ void Client::disconnect() void Client::login(const char *user, const char *pass, const char *agent) { + m_sequence = 1; + const size_t size = 96 + strlen(user) + strlen(pass) + strlen(agent); char *req = static_cast(malloc(size)); - snprintf(req, size, "{\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"},\"id\":1}\n", user, pass, agent); + snprintf(req, size, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_sequence, user, pass, agent); send(req); } @@ -117,6 +118,7 @@ void Client::send(char *data) return; } + m_sequence++; uv_buf_t buf = uv_buf_init(data, strlen(data)); uv_write_t *req = static_cast(malloc(sizeof(uv_write_t))); @@ -195,6 +197,36 @@ void Client::parse(char *line, size_t len) LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_host, m_port, err.text); return; } + + const json_t *id = json_object_get(val, "id"); + if (json_is_integer(id)) { + parseResponse(json_integer_value(id), json_object_get(val, "result"), json_object_get(val, "error")); + } + else { + parseNotification(json_string_value(json_object_get(val, "method")), json_object_get(val, "params")); + } + + json_decref(val); +} + + +void Client::parseNotification(const char *method, const json_t *params) +{ + +} + + +void Client::parseResponse(int64_t id, const json_t *result, const json_t *error) +{ + if (json_is_object(error)) { + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + + if (id == 1) { + close(); + } + + return; + } } diff --git a/src/net/Client.h b/src/net/Client.h index 181ea641..89167aff 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -25,6 +25,7 @@ #define __CLIENT_H__ +#include #include @@ -61,6 +62,8 @@ private: void close(); void connect(struct sockaddr *addr); void parse(char *line, size_t len); + void parseNotification(const char *method, const json_t *params); + void parseResponse(int64_t id, const json_t *result, const json_t *error); void setState(SocketState state); static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); @@ -73,6 +76,8 @@ private: char *m_host; IClientListener *m_listener; + int64_t m_retries; + int64_t m_sequence; size_t m_recvBufPos; SocketState m_state; struct addrinfo m_hints; From 26b82063329fd23d53851edf0776810daaf0fc6d Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 6 Jun 2017 06:35:17 +0300 Subject: [PATCH 03/92] Basic login parse. --- src/net/Client.cpp | 30 ++++++++++++++++++++++++++++++ src/net/Client.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 8b80cd25..53b2504b 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -136,6 +136,21 @@ void Client::send(char *data) } +bool Client::parseLogin(const json_t *result, int *code) +{ + const char *id = json_string_value(json_object_get(result, "id")); + if (!id || strlen(id) >= sizeof(m_rpcId)) { + *code = 1; + return false; + } + + memset(m_rpcId, 0, sizeof(m_rpcId)); + memcpy(m_rpcId, id, strlen(id)); + + return true; +} + + int Client::resolve(const char *host) { setState(HostLookupState); @@ -227,6 +242,21 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error return; } + + if (!json_is_object(result)) { + return; + } + + if (id == 1) { + int code = -1; + if (!parseLogin(result, &code)) { + LOG_ERR("[%s:%u] login error code: %d", m_host, m_port, code); + return close(); + } + + return; + } + } diff --git a/src/net/Client.h b/src/net/Client.h index 89167aff..7db3ae3f 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -58,6 +58,7 @@ public: private: constexpr static size_t kRecvBufSize = 4096; + bool parseLogin(const json_t *result, int *code); int resolve(const char *host); void close(); void connect(struct sockaddr *addr); @@ -75,6 +76,7 @@ private: static Client *getClient(void *data); char *m_host; + char m_rpcId[64]; IClientListener *m_listener; int64_t m_retries; int64_t m_sequence; From 1ecee56eb62745aa298caefa318e5362e524e232 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 6 Jun 2017 20:43:52 +0300 Subject: [PATCH 04/92] Add Job class. --- CMakeLists.txt | 2 + src/net/Client.cpp | 32 ++++++++- src/net/Client.h | 1 + src/net/Job.cpp | 158 +++++++++++++++++++++++++++++++++++++++++++++ src/net/Job.h | 57 ++++++++++++++++ 5 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 src/net/Job.cpp create mode 100644 src/net/Job.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f485e11..dc3feb36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ set(HEADERS src/App.h src/interfaces/IClientListener.h src/net/Client.h + src/net/Job.h src/net/Network.h src/net/Url.h src/Options.h @@ -15,6 +16,7 @@ set(HEADERS set(SOURCES src/App.cpp src/net/Client.cpp + src/net/Job.cpp src/net/Network.cpp src/net/Url.cpp src/Options.cpp diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 53b2504b..ee2c6873 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -25,6 +25,7 @@ #include "Console.h" #include "interfaces/IClientListener.h" #include "net/Client.h" +#include "net/Job.h" #include "net/Url.h" @@ -136,6 +137,35 @@ void Client::send(char *data) } +bool Client::parseJob(const json_t *params, int *code) +{ + if (!json_is_object(params)) { + *code = 2; + return false; + } + + Job job; + if (!job.setId(json_string_value(json_object_get(params, "job_id")))) { + *code = 3; + return false; + } + + if (!job.setBlob(json_string_value(json_object_get(params, "blob")))) { + *code = 4; + return false; + } + + if (!job.setTarget(json_string_value(json_object_get(params, "target")))) { + *code = 5; + return false; + } + + LOG_NOTICE("PARSE JOB %d %lld %lld", job.size(), job.target(), job.diff()); + + return true; +} + + bool Client::parseLogin(const json_t *result, int *code) { const char *id = json_string_value(json_object_get(result, "id")); @@ -147,7 +177,7 @@ bool Client::parseLogin(const json_t *result, int *code) memset(m_rpcId, 0, sizeof(m_rpcId)); memcpy(m_rpcId, id, strlen(id)); - return true; + return parseJob(json_object_get(result, "job"), code); } diff --git a/src/net/Client.h b/src/net/Client.h index 7db3ae3f..2eecb044 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -58,6 +58,7 @@ public: private: constexpr static size_t kRecvBufSize = 4096; + bool parseJob(const json_t *params, int *code); bool parseLogin(const json_t *result, int *code); int resolve(const char *host); void close(); diff --git a/src/net/Job.cpp b/src/net/Job.cpp new file mode 100644 index 00000000..aeb46685 --- /dev/null +++ b/src/net/Job.cpp @@ -0,0 +1,158 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +//#include + + +#include "net/Job.h" +#include "Console.h" + + +static inline unsigned char hf_hex2bin(char c, bool &err) +{ + if (c >= '0' && c <= '9') { + return c - '0'; + } + else if (c >= 'a' && c <= 'f') { + return c - 'a' + 0xA; + } + else if (c >= 'A' && c <= 'F') { + return c - 'A' + 0xA; + } + + err = true; + return 0; +} + + +static inline char hf_bin2hex(unsigned char c) +{ + if (c <= 0x9) { + return '0' + c; + } + + return 'a' - 0xA + c; +} + + +Job::Job() : + m_size(0), + m_diff(0), + m_target(0) +{ +} + + +bool Job::setBlob(const char *blob) +{ + if (!blob) { + return false; + } + + m_size = strlen(blob); + if (m_size % 2 != 0) { + return false; + } + + m_size /= 2; + if (m_size < 76 || m_size >= sizeof(m_blob)) { + return false; + } + + return fromHex(blob, m_size * 2, m_blob); +} + + +bool Job::setId(const char *id) +{ + if (!id || strlen(id) >= sizeof(m_id)) { + return false; + } + + memset(m_id, 0, sizeof(m_id)); + memcpy(m_id, id, strlen(id)); + return true; +} + + +bool Job::setTarget(const char *target) +{ + if (!target) { + return false; + } + + const size_t len = strlen(target); + + if (len <= 8) { + uint32_t tmp = 0; + char str[8]; + memcpy(str, target, len); + + if (!fromHex(str, 8, reinterpret_cast(&tmp)) || tmp == 0) { + return false; + } + + m_target = 0xFFFFFFFFFFFFFFFFULL / (0xFFFFFFFFULL / static_cast(tmp)); + } + else if (len <= 16) { + m_target = 0; + char str[16]; + memcpy(str, target, len); + + if (!fromHex(str, 16, reinterpret_cast(&m_target)) || m_target == 0) { + return false; + } + } + else { + return false; + } + + + m_diff = toDiff(m_target); + return true; +} + + +bool Job::fromHex(const char* in, unsigned int len, unsigned char* out) +{ + bool error = false; + for (unsigned int i = 0; i < len; i += 2) { + out[i / 2] = (hf_hex2bin(in[i], error) << 4) | hf_hex2bin(in[i + 1], error); + + if (error) { + return false; + } + } + return true; +} + + +void Job::toHex(const unsigned char* in, unsigned int len, char* out) +{ + for (unsigned int i = 0; i < len; i++) { + out[i * 2] = hf_bin2hex((in[i] & 0xF0) >> 4); + out[i * 2 + 1] = hf_bin2hex(in[i] & 0x0F); + } +} diff --git a/src/net/Job.h b/src/net/Job.h new file mode 100644 index 00000000..d213ec34 --- /dev/null +++ b/src/net/Job.h @@ -0,0 +1,57 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __JOB_H__ +#define __JOB_H__ + + +#include + + +class Job +{ +public: + Job(); + bool setBlob(const char *blob); + bool setId(const char *id); + bool setTarget(const char *target); + + inline const uint8_t *blob() const { return m_blob; } + inline const char *id() const { return m_id; } + inline uint32_t size() const { return m_size; } + inline uint32_t diff() const { return m_diff; } + inline uint64_t target() const { return m_target; } + + static bool fromHex(const char* in, unsigned int len, unsigned char* out); + static void toHex(const unsigned char* in, unsigned int len, char* out); + inline static uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } + +private: + char m_id[64] __attribute__((aligned(16))); + uint8_t m_blob[84] __attribute__((aligned(16))); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. + uint32_t m_size; + uint64_t m_diff; + uint64_t m_target; +}; + +#endif /* __JOB_H__ */ From 4c06d8b08054f0a460a4749f6ef931ec233d1d66 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2017 01:19:59 +0300 Subject: [PATCH 05/92] Handle job notification. --- src/interfaces/IClientListener.h | 3 +++ src/net/Client.cpp | 19 +++++++++++++++++-- src/net/Client.h | 4 ++++ src/net/Network.cpp | 11 +++++++++++ src/net/Network.h | 2 ++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h index 26ff10aa..8a2a439f 100644 --- a/src/interfaces/IClientListener.h +++ b/src/interfaces/IClientListener.h @@ -26,6 +26,7 @@ class Client; +class Job; class IClientListener @@ -33,7 +34,9 @@ class IClientListener public: virtual ~IClientListener() {} + virtual void onJobReceived(Client *client, const Job &job) = 0; virtual void onLoginCredentialsRequired(Client *client) = 0; + virtual void onLoginSuccess(Client *client) = 0; }; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index ee2c6873..296acf64 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -25,7 +25,6 @@ #include "Console.h" #include "interfaces/IClientListener.h" #include "net/Client.h" -#include "net/Job.h" #include "net/Url.h" @@ -160,8 +159,9 @@ bool Client::parseJob(const json_t *params, int *code) return false; } - LOG_NOTICE("PARSE JOB %d %lld %lld", job.size(), job.target(), job.diff()); + m_job = job; + LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_host, m_port, job.id(), job.diff()); return true; } @@ -257,7 +257,20 @@ void Client::parse(char *line, size_t len) void Client::parseNotification(const char *method, const json_t *params) { + if (!method) { + return; + } + if (strcmp(method, "job") == 0) { + int code = -1; + if (parseJob(params, &code)) { + m_listener->onJobReceived(this, m_job); + } + + return; + } + + LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_host, m_port, method); } @@ -284,6 +297,8 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error return close(); } + m_listener->onLoginSuccess(this); + m_listener->onJobReceived(this, m_job); return; } diff --git a/src/net/Client.h b/src/net/Client.h index 2eecb044..309078de 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -29,6 +29,9 @@ #include +#include "net/Job.h" + + class Url; class IClientListener; @@ -81,6 +84,7 @@ private: IClientListener *m_listener; int64_t m_retries; int64_t m_sequence; + Job m_job; size_t m_recvBufPos; SocketState m_state; struct addrinfo m_hints; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 91b62621..f87c41d5 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -59,7 +59,18 @@ void Network::connect() } +void Network::onJobReceived(Client *client, const Job &job) +{ + +} + + void Network::onLoginCredentialsRequired(Client *client) { client->login(m_options->user(), m_options->pass(), m_agent); } + + +void Network::onLoginSuccess(Client *client) +{ +} diff --git a/src/net/Network.h b/src/net/Network.h index 5ee7c295..87e31909 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -42,7 +42,9 @@ public: static char *userAgent(); protected: + void onJobReceived(Client *client, const Job &job) override; void onLoginCredentialsRequired(Client *client) override; + void onLoginSuccess(Client *client) override; private: char *m_agent; From b8cc1136a4dae5a842f52bba9a21358868c72bb9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2017 02:46:52 +0300 Subject: [PATCH 06/92] More flexible pools configuration. --- src/App.cpp | 1 - src/Options.cpp | 2 +- src/Options.h | 9 +++++---- src/donate.h | 16 +++++++++++++++- src/net/Client.cpp | 37 +++++++++++++++++++------------------ src/net/Client.h | 7 +++++-- src/net/Network.cpp | 39 +++++++++++++++++++++++++++++---------- src/net/Network.h | 12 +++++++++--- 8 files changed, 83 insertions(+), 40 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index ce9d2b2c..a82eb88c 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -48,7 +48,6 @@ App::App(int argc, char **argv) { Console::init(); m_options = Options::parse(argc, argv); - m_network = new Network(m_options); } diff --git a/src/Options.cpp b/src/Options.cpp index 5a8551c4..331db843 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -128,7 +128,7 @@ Options::Options(int argc, char **argv) : m_user(nullptr), m_algo(0), m_algoVariant(0), - m_donateLevel(DONATE_LEVEL), + m_donateLevel(kDonateLevel), m_maxCpuUsage(75), m_retries(5), m_retryPause(5), diff --git a/src/Options.h b/src/Options.h index eccfbcff..421d19f4 100644 --- a/src/Options.h +++ b/src/Options.h @@ -51,10 +51,11 @@ public: static inline Options* i() { return m_self; } static Options *parse(int argc, char **argv); - inline bool isReady() const { return m_ready; } - inline const char *pass() const { return m_pass; } - inline const char *user() const { return m_user; } - inline Url *url() const { return m_url; } + inline bool isReady() const { return m_ready; } + inline const char *pass() const { return m_pass; } + inline const char *user() const { return m_user; } + inline const Url *backupUrl() const { return m_backupUrl; } + inline const Url *url() const { return m_url; } private: Options(int argc, char **argv); diff --git a/src/donate.h b/src/donate.h index 4fc60787..3a000948 100644 --- a/src/donate.h +++ b/src/donate.h @@ -24,6 +24,20 @@ #ifndef __DONATE_H__ #define __DONATE_H__ -#define DONATE_LEVEL 5 + +/* + * Dev donation. + * + * Percentage of your hashing power that you want to donate to the developer, can be 0 if you don't want to do that. + * Example of how it works for the default setting of 1: + * You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1 minute. + * Switching is instant, and only happens after a successful connection, so you never loose any hashes. + * + * If you plan on changing this setting to 0 please consider making a one off donation to my wallet: + * XMR: 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD + * BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT + */ +constexpr const int kDonateLevel = 5; + #endif /* __DONATE_H__ */ diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 296acf64..a8a4f5d5 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -28,9 +28,10 @@ #include "net/Url.h" -Client::Client(IClientListener *listener) : +Client::Client(int id, IClientListener *listener) : m_host(nullptr), m_listener(listener), + m_id(id), m_retries(0), m_sequence(1), m_recvBufPos(0), @@ -59,20 +60,9 @@ Client::~Client() } -/** - * @brief Connect to server. - * - * @param host - * @param port - */ -void Client::connect(const char *host, uint16_t port) +void Client::connect() { - m_host = strdup(host); - m_port = port; - - LOG_DEBUG("[%s:%u] connect", m_host, m_port); - - resolve(host); + resolve(m_host); } @@ -83,7 +73,8 @@ void Client::connect(const char *host, uint16_t port) */ void Client::connect(const Url *url) { - connect(url->host(), url->port()); + setUrl(url); + resolve(m_host); } @@ -136,6 +127,14 @@ void Client::send(char *data) } +void Client::setUrl(const Url *url) +{ + free(m_host); + m_host = strdup(url->host()); + m_port = url->port(); +} + + bool Client::parseJob(const json_t *params, int *code) { if (!json_is_object(params)) { @@ -335,6 +334,8 @@ void Client::onClose(uv_handle_t *handle) client->m_stream = nullptr; client->m_socket = nullptr; client->setState(UnconnectedState); + + LOG_NOTICE("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); } @@ -344,6 +345,7 @@ void Client::onConnect(uv_connect_t *req, int status) if (status < 0) { LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); free(req); + client->close(); return; } @@ -366,8 +368,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) LOG_ERR("[%s:%u] read error: \"%s\"", client->m_host, client->m_port, uv_strerror(nread)); } - client->close(); - return; + return client->close();; } client->m_recvBufPos += nread; @@ -404,7 +405,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) auto client = getClient(req->data); if (status < 0) { LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); - return; + return client->close();; } client->connect(res->ai_addr); diff --git a/src/net/Client.h b/src/net/Client.h index 309078de..8df21559 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -47,15 +47,17 @@ public: ClosingState }; - Client(IClientListener *listener); + Client(int id, IClientListener *listener); ~Client(); - void connect(const char *host, uint16_t port); + void connect(); void connect(const Url *url); void disconnect(); void login(const char *user, const char *pass, const char *agent); void send(char *data); + void setUrl(const Url *url); + inline int id() const { return m_id; } inline SocketState state() const { return m_state; } private: @@ -82,6 +84,7 @@ private: char *m_host; char m_rpcId[64]; IClientListener *m_listener; + int m_id; int64_t m_retries; int64_t m_sequence; Job m_job; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index f87c41d5..1f0a55e9 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -23,30 +23,37 @@ #include +#include #include "Console.h" #include "net/Client.h" #include "net/Network.h" +#include "net/Url.h" #include "Options.h" Network::Network(const Options *options) : - m_backupPool(nullptr), - m_donatePool(nullptr), - m_pool(nullptr), - m_options(options) + m_donate(false), + m_options(options), + m_pool(1) { + m_pools.reserve(2); m_agent = userAgent(); - m_pool = new Client(this); + + std::unique_ptr url(new Url("donate.xmrig.com", 443)); + + addPool(url.get()); + addPool(m_options->url()); + addPool(m_options->backupUrl()); } Network::~Network() { - delete m_pool; - delete m_donatePool; - delete m_backupPool; + for (auto client : m_pools) { + delete client; + } free(m_agent); } @@ -54,8 +61,7 @@ Network::~Network() void Network::connect() { - m_pool->connect(m_options->url()); -// LOG_DEBUG("XX %s", m_options->url()); + m_pools.at(m_pool)->connect(); } @@ -74,3 +80,16 @@ void Network::onLoginCredentialsRequired(Client *client) void Network::onLoginSuccess(Client *client) { } + + +void Network::addPool(const Url *url) +{ + if (!url) { + return; + } + + Client *client = new Client(m_pools.size(), this); + client->setUrl(url); + + m_pools.push_back(client); +} diff --git a/src/net/Network.h b/src/net/Network.h index 87e31909..2b7cf208 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -25,10 +25,14 @@ #define __NETWORK_H__ +#include + + #include "interfaces/IClientListener.h" class Options; +class Url; class Network : public IClientListener @@ -47,11 +51,13 @@ protected: void onLoginSuccess(Client *client) override; private: + void addPool(const Url *url); + + bool m_donate; char *m_agent; - Client *m_backupPool; - Client *m_donatePool; - Client *m_pool; const Options *m_options; + int m_pool; + std::vector m_pools; }; From c29dc8bcf4d28b3aab4d9dc91ba3333c34b9a06d Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2017 04:19:32 +0300 Subject: [PATCH 07/92] Implemented reconnect. --- src/Options.cpp | 2 +- src/Options.h | 1 + src/interfaces/IClientListener.h | 1 + src/net/Client.cpp | 25 ++++++++++++++++++++++--- src/net/Client.h | 10 +++++++--- src/net/Network.cpp | 7 +++++++ src/net/Network.h | 1 + 7 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 331db843..c996c755 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -131,7 +131,7 @@ Options::Options(int argc, char **argv) : m_donateLevel(kDonateLevel), m_maxCpuUsage(75), m_retries(5), - m_retryPause(5), + m_retryPause(2), m_threads(0), m_affinity(-1L), m_backupUrl(nullptr), diff --git a/src/Options.h b/src/Options.h index 421d19f4..05efbcee 100644 --- a/src/Options.h +++ b/src/Options.h @@ -56,6 +56,7 @@ public: inline const char *user() const { return m_user; } inline const Url *backupUrl() const { return m_backupUrl; } inline const Url *url() const { return m_url; } + inline int retryPause() const { return m_retryPause; } private: Options(int argc, char **argv); diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h index 8a2a439f..73a85516 100644 --- a/src/interfaces/IClientListener.h +++ b/src/interfaces/IClientListener.h @@ -34,6 +34,7 @@ class IClientListener public: virtual ~IClientListener() {} + virtual void onClose(Client *client, int failures); virtual void onJobReceived(Client *client, const Job &job) = 0; virtual void onLoginCredentialsRequired(Client *client) = 0; virtual void onLoginSuccess(Client *client) = 0; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index a8a4f5d5..6ae63b91 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -32,7 +32,8 @@ Client::Client(int id, IClientListener *listener) : m_host(nullptr), m_listener(listener), m_id(id), - m_retries(0), + m_retryPause(2000), + m_failures(0), m_sequence(1), m_recvBufPos(0), m_state(UnconnectedState), @@ -49,6 +50,9 @@ Client::Client(int id, IClientListener *listener) : m_recvBuf.base = static_cast(malloc(kRecvBufSize)); m_recvBuf.len = kRecvBufSize; + + m_retriesTimer.data = this; + uv_timer_init(uv_default_loop(), &m_retriesTimer); } @@ -80,6 +84,8 @@ void Client::connect(const Url *url) void Client::disconnect() { + m_failures = -1; + close(); } @@ -296,11 +302,24 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error return close(); } + m_failures = 0; m_listener->onLoginSuccess(this); m_listener->onJobReceived(this, m_job); return; } +} + +void Client::reconnect() +{ + if (m_failures == -1) { + return m_listener->onClose(this, -1); + } + + m_failures++; + m_listener->onClose(this, m_failures); + + uv_timer_start(&m_retriesTimer, [](uv_timer_t *handle) { getClient(handle->data)->connect(); }, m_retryPause, 0); } @@ -335,7 +354,7 @@ void Client::onClose(uv_handle_t *handle) client->m_socket = nullptr; client->setState(UnconnectedState); - LOG_NOTICE("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + client->reconnect(); } @@ -405,7 +424,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) auto client = getClient(req->data); if (status < 0) { LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); - return client->close();; + return client->reconnect();; } client->connect(res->ai_addr); diff --git a/src/net/Client.h b/src/net/Client.h index 8df21559..a1e9997a 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -57,8 +57,9 @@ public: void send(char *data); void setUrl(const Url *url); - inline int id() const { return m_id; } - inline SocketState state() const { return m_state; } + inline int id() const { return m_id; } + inline SocketState state() const { return m_state; } + inline void setRetryPause(int ms) { m_retryPause = ms; } private: constexpr static size_t kRecvBufSize = 4096; @@ -71,6 +72,7 @@ private: void parse(char *line, size_t len); void parseNotification(const char *method, const json_t *params); void parseResponse(int64_t id, const json_t *result, const json_t *error); + void reconnect(); void setState(SocketState state); static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); @@ -85,7 +87,8 @@ private: char m_rpcId[64]; IClientListener *m_listener; int m_id; - int64_t m_retries; + int m_retryPause; + int64_t m_failures; int64_t m_sequence; Job m_job; size_t m_recvBufPos; @@ -96,6 +99,7 @@ private: uv_getaddrinfo_t m_resolver; uv_stream_t *m_stream; uv_tcp_t *m_socket; + uv_timer_t m_retriesTimer; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 1f0a55e9..101c6b79 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -65,6 +65,12 @@ void Network::connect() } +void Network::onClose(Client *client, int failures) +{ + LOG_DEBUG("CLOSE %d %d", client->id(), failures); +} + + void Network::onJobReceived(Client *client, const Job &job) { @@ -90,6 +96,7 @@ void Network::addPool(const Url *url) Client *client = new Client(m_pools.size(), this); client->setUrl(url); + client->setRetryPause(m_options->retryPause() * 1000); m_pools.push_back(client); } diff --git a/src/net/Network.h b/src/net/Network.h index 2b7cf208..89787012 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -46,6 +46,7 @@ public: static char *userAgent(); protected: + void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; void onLoginCredentialsRequired(Client *client) override; void onLoginSuccess(Client *client) override; From 5f1f9016493084ab6104fd26d582317d119fa8dc Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2017 06:48:00 +0300 Subject: [PATCH 08/92] Add support for keepAlive. --- src/Options.cpp | 4 ++-- src/Options.h | 3 ++- src/net/Client.cpp | 43 +++++++++++++++++++++++++++++++++++-------- src/net/Client.h | 15 ++++++++++++--- src/net/Network.cpp | 3 ++- 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index c996c755..2df63441 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -120,7 +120,7 @@ Options::Options(int argc, char **argv) : m_background(false), m_colors(true), m_doubleHash(false), - m_keepalive(false), + m_keepAlive(false), m_nicehash(false), m_ready(false), m_safe(false), @@ -277,7 +277,7 @@ bool Options::parseArg(int key, char *arg) break; case 'k': /* --keepalive */ - m_keepalive = true; + m_keepAlive = true; break; case 'V': /* --version */ diff --git a/src/Options.h b/src/Options.h index 05efbcee..227659f7 100644 --- a/src/Options.h +++ b/src/Options.h @@ -52,6 +52,7 @@ public: static Options *parse(int argc, char **argv); inline bool isReady() const { return m_ready; } + inline bool keepAlive() const { return m_keepAlive; } inline const char *pass() const { return m_pass; } inline const char *user() const { return m_user; } inline const Url *backupUrl() const { return m_backupUrl; } @@ -75,7 +76,7 @@ private: bool m_background; bool m_colors; bool m_doubleHash; - bool m_keepalive; + bool m_keepAlive; bool m_nicehash; bool m_ready; bool m_safe; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 6ae63b91..fbfe17f8 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -29,6 +29,7 @@ Client::Client(int id, IClientListener *listener) : + m_keepAlive(false), m_host(nullptr), m_listener(listener), m_id(id), @@ -41,7 +42,7 @@ Client::Client(int id, IClientListener *listener) : m_stream(nullptr), m_socket(nullptr) { - m_resolver.data = this; + m_resolver.data = m_responseTimer.data = m_retriesTimer.data = m_keepAliveTimer.data = this; m_hints.ai_family = PF_INET; m_hints.ai_socktype = SOCK_STREAM; @@ -51,8 +52,10 @@ Client::Client(int id, IClientListener *listener) : m_recvBuf.base = static_cast(malloc(kRecvBufSize)); m_recvBuf.len = kRecvBufSize; - m_retriesTimer.data = this; - uv_timer_init(uv_default_loop(), &m_retriesTimer); + auto loop = uv_default_loop(); + uv_timer_init(loop, &m_retriesTimer); + uv_timer_init(loop, &m_responseTimer); + uv_timer_init(loop, &m_keepAliveTimer); } @@ -122,14 +125,11 @@ void Client::send(char *data) req->data = buf.base; uv_write(req, m_stream, &buf, 1, [](uv_write_t *req, int status) { - if (status) { - auto client = getClient(req->data); - LOG_ERR("[%s:%u] write error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); - } - free(req->data); free(req); }); + + uv_timer_start(&m_responseTimer, [](uv_timer_t* handle) { getClient(handle->data)->close(); }, kResponseTimeout, 0); } @@ -236,6 +236,8 @@ void Client::connect(struct sockaddr *addr) void Client::parse(char *line, size_t len) { + startTimeout(); + line[len - 1] = '\0'; LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_host, m_port, len, line); @@ -310,8 +312,22 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error } +void Client::ping() +{ + char *req = static_cast(malloc(128)); + snprintf(req, 128, "{\"id\":%lld,\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence, m_rpcId); + + send(req); +} + + void Client::reconnect() { + uv_timer_stop(&m_responseTimer); + if (m_keepAlive) { + uv_timer_stop(&m_keepAliveTimer); + } + if (m_failures == -1) { return m_listener->onClose(this, -1); } @@ -335,6 +351,17 @@ void Client::setState(SocketState state) } +void Client::startTimeout() +{ + uv_timer_stop(&m_responseTimer); + if (!m_keepAlive) { + return; + } + + uv_timer_start(&m_keepAliveTimer, [](uv_timer_t *handle) { getClient(handle->data)->ping(); }, kKeepAliveTimeout, 0); +} + + void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { auto client = getClient(handle->data); diff --git a/src/net/Client.h b/src/net/Client.h index a1e9997a..7dbdf21f 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -47,6 +47,9 @@ public: ClosingState }; + constexpr static int kResponseTimeout = 15 * 1000; + constexpr static int kKeepAliveTimeout = 60 * 1000; + Client(int id, IClientListener *listener); ~Client(); @@ -57,9 +60,10 @@ public: void send(char *data); void setUrl(const Url *url); - inline int id() const { return m_id; } - inline SocketState state() const { return m_state; } - inline void setRetryPause(int ms) { m_retryPause = ms; } + inline int id() const { return m_id; } + inline SocketState state() const { return m_state; } + inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } + inline void setRetryPause(int ms) { m_retryPause = ms; } private: constexpr static size_t kRecvBufSize = 4096; @@ -72,8 +76,10 @@ private: void parse(char *line, size_t len); void parseNotification(const char *method, const json_t *params); void parseResponse(int64_t id, const json_t *result, const json_t *error); + void ping(); void reconnect(); void setState(SocketState state); + void startTimeout(); static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); static void onClose(uv_handle_t *handle); @@ -83,6 +89,7 @@ private: static Client *getClient(void *data); + bool m_keepAlive; char *m_host; char m_rpcId[64]; IClientListener *m_listener; @@ -99,6 +106,8 @@ private: uv_getaddrinfo_t m_resolver; uv_stream_t *m_stream; uv_tcp_t *m_socket; + uv_timer_t m_keepAliveTimer; + uv_timer_t m_responseTimer; uv_timer_t m_retriesTimer; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 101c6b79..a6934167 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -41,7 +41,7 @@ Network::Network(const Options *options) : m_pools.reserve(2); m_agent = userAgent(); - std::unique_ptr url(new Url("donate.xmrig.com", 443)); + auto url = std::make_unique("donate.xmrig.com", 443); addPool(url.get()); addPool(m_options->url()); @@ -97,6 +97,7 @@ void Network::addPool(const Url *url) Client *client = new Client(m_pools.size(), this); client->setUrl(url); client->setRetryPause(m_options->retryPause() * 1000); + client->setKeepAlive(m_options->keepAlive()); m_pools.push_back(client); } From 387524e1c56c7d62d0ce33b8673182ec8f5a86f1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2017 07:34:14 +0300 Subject: [PATCH 09/92] Fix for error notification. --- src/net/Client.cpp | 9 +++++++-- src/net/Client.h | 2 +- src/net/Job.cpp | 1 - 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index fbfe17f8..72f179c2 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -255,15 +255,20 @@ void Client::parse(char *line, size_t len) parseResponse(json_integer_value(id), json_object_get(val, "result"), json_object_get(val, "error")); } else { - parseNotification(json_string_value(json_object_get(val, "method")), json_object_get(val, "params")); + parseNotification(json_string_value(json_object_get(val, "method")), json_object_get(val, "params"), json_object_get(val, "error")); } json_decref(val); } -void Client::parseNotification(const char *method, const json_t *params) +void Client::parseNotification(const char *method, const json_t *params, const json_t *error) { + if (json_is_object(error)) { + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + return; + } + if (!method) { return; } diff --git a/src/net/Client.h b/src/net/Client.h index 7dbdf21f..62bb4196 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -74,7 +74,7 @@ private: void close(); void connect(struct sockaddr *addr); void parse(char *line, size_t len); - void parseNotification(const char *method, const json_t *params); + void parseNotification(const char *method, const json_t *params, const json_t *error); void parseResponse(int64_t id, const json_t *result, const json_t *error); void ping(); void reconnect(); diff --git a/src/net/Job.cpp b/src/net/Job.cpp index aeb46685..65feabb7 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -129,7 +129,6 @@ bool Job::setTarget(const char *target) return false; } - m_diff = toDiff(m_target); return true; } From c31ea003994fa6a60ee59e52ba5f29554173e6b4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2017 09:07:31 +0300 Subject: [PATCH 10/92] Basic failover support. --- src/Console.h | 6 ++++-- src/Options.cpp | 2 +- src/Options.h | 1 + src/net/Client.cpp | 2 +- src/net/Client.h | 2 ++ src/net/Network.cpp | 35 ++++++++++++++++++++++++++++++++--- 6 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/Console.h b/src/Console.h index a02e3761..73e04706 100644 --- a/src/Console.h +++ b/src/Console.h @@ -71,11 +71,13 @@ private: #define LOG_INFO(x, ...) Console::i()->message(Console::INFO, x, ##__VA_ARGS__) #ifdef APP_DEBUG -# define LOG_DEBUG(x, ...) Console::i()->message(Console::DEBUG, x, ##__VA_ARGS__) -# define LOG_DEBUG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) +# define LOG_DEBUG(x, ...) Console::i()->message(Console::DEBUG, x, ##__VA_ARGS__) +# define LOG_DEBUG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) +# define LOG_DEBUG_WARN(x, ...) Console::i()->message(Console::WARNING, x, ##__VA_ARGS__) #else # define LOG_DEBUG(x, ...) # define LOG_DEBUG_ERR(x, ...) +# define LOG_DEBUG_WARN(x, ...) #endif #endif /* __CONSOLE_H__ */ diff --git a/src/Options.cpp b/src/Options.cpp index 2df63441..c09de032 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -131,7 +131,7 @@ Options::Options(int argc, char **argv) : m_donateLevel(kDonateLevel), m_maxCpuUsage(75), m_retries(5), - m_retryPause(2), + m_retryPause(5), m_threads(0), m_affinity(-1L), m_backupUrl(nullptr), diff --git a/src/Options.h b/src/Options.h index 227659f7..b2b1966d 100644 --- a/src/Options.h +++ b/src/Options.h @@ -57,6 +57,7 @@ public: inline const char *user() const { return m_user; } inline const Url *backupUrl() const { return m_backupUrl; } inline const Url *url() const { return m_url; } + inline int retries() const { return m_retries; } inline int retryPause() const { return m_retryPause; } private: diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 72f179c2..38e7df25 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -33,7 +33,7 @@ Client::Client(int id, IClientListener *listener) : m_host(nullptr), m_listener(listener), m_id(id), - m_retryPause(2000), + m_retryPause(5000), m_failures(0), m_sequence(1), m_recvBufPos(0), diff --git a/src/net/Client.h b/src/net/Client.h index 62bb4196..6110488d 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -60,8 +60,10 @@ public: void send(char *data); void setUrl(const Url *url); + inline const char *host() const { return m_host; } inline int id() const { return m_id; } inline SocketState state() const { return m_state; } + inline uint16_t port() const { return m_port; } inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } inline void setRetryPause(int ms) { m_retryPause = ms; } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index a6934167..692cfa7a 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -36,7 +36,7 @@ Network::Network(const Options *options) : m_donate(false), m_options(options), - m_pool(1) + m_pool(0) { m_pools.reserve(2); m_agent = userAgent(); @@ -61,13 +61,25 @@ Network::~Network() void Network::connect() { - m_pools.at(m_pool)->connect(); + m_pools.at(1)->connect(); } void Network::onClose(Client *client, int failures) { - LOG_DEBUG("CLOSE %d %d", client->id(), failures); + const int id = client->id(); + if (id == 0 && failures == -1) { + m_donate = false; + return; + } + + if (m_pool == id) { + m_pool = 0; + } + + if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { + m_pools.at(2)->connect(); + } } @@ -85,6 +97,23 @@ void Network::onLoginCredentialsRequired(Client *client) void Network::onLoginSuccess(Client *client) { + const int id = client->id(); + if (id == 0) { + m_donate = true; + return; + } + + if (id == 2 && m_pool) { // primary pool is already active + m_pools.at(2)->disconnect(); + return; + } + + LOG_NOTICE("use pool: \"%s:%d\"", client->host(), client->port()); + m_pool = id; + + if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool + m_pools.at(2)->disconnect(); + } } From 1cf5ad5212b6837227a5c0ce99db0cfc3e67db8d Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Jun 2017 22:34:23 +0300 Subject: [PATCH 11/92] Implemented switch to donate pool. --- CMakeLists.txt | 2 +- src/Options.h | 1 + src/net/Client.cpp | 6 +++- src/net/Network.cpp | 71 +++++++++++++++++++++++++++++++++++++-------- src/net/Network.h | 6 ++++ src/net/Url.cpp | 7 +++++ src/net/Url.h | 1 + 7 files changed, 80 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc3feb36..82641462 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") diff --git a/src/Options.h b/src/Options.h index b2b1966d..16733cca 100644 --- a/src/Options.h +++ b/src/Options.h @@ -57,6 +57,7 @@ public: inline const char *user() const { return m_user; } inline const Url *backupUrl() const { return m_backupUrl; } inline const Url *url() const { return m_url; } + inline int donateLevel() const { return m_donateLevel; } inline int retries() const { return m_retries; } inline int retryPause() const { return m_retryPause; } diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 38e7df25..8fdf09e9 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -129,12 +129,16 @@ void Client::send(char *data) free(req); }); - uv_timer_start(&m_responseTimer, [](uv_timer_t* handle) { getClient(handle->data)->close(); }, kResponseTimeout, 0); + uv_timer_start(&m_responseTimer, [](uv_timer_t *handle) { getClient(handle->data)->close(); }, kResponseTimeout, 0); } void Client::setUrl(const Url *url) { + if (!url || !url->isValid()) { + return; + } + free(m_host); m_host = strdup(url->host()); m_port = url->port(); diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 692cfa7a..d513fdda 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -22,7 +22,6 @@ */ -#include #include @@ -41,11 +40,12 @@ Network::Network(const Options *options) : m_pools.reserve(2); m_agent = userAgent(); - auto url = std::make_unique("donate.xmrig.com", 443); - - addPool(url.get()); + addPool(std::make_unique().get()); addPool(m_options->url()); addPool(m_options->backupUrl()); + + m_timer.data = this; + uv_timer_init(uv_default_loop(), &m_timer); } @@ -61,15 +61,22 @@ Network::~Network() void Network::connect() { - m_pools.at(1)->connect(); + m_pools[1]->connect(); + + if (m_options->donateLevel()) { + uv_timer_start(&m_timer, Network::onTimer, (100 - m_options->donateLevel()) * 60 * 1000, 0); + } } void Network::onClose(Client *client, int failures) { const int id = client->id(); - if (id == 0 && failures == -1) { - m_donate = false; + if (id == 0) { + if (failures == -1) { + stopDonate(); + } + return; } @@ -78,7 +85,7 @@ void Network::onClose(Client *client, int failures) } if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { - m_pools.at(2)->connect(); + m_pools[2]->connect(); } } @@ -99,12 +106,11 @@ void Network::onLoginSuccess(Client *client) { const int id = client->id(); if (id == 0) { - m_donate = true; - return; + return startDonate(); } if (id == 2 && m_pool) { // primary pool is already active - m_pools.at(2)->disconnect(); + m_pools[2]->disconnect(); return; } @@ -112,7 +118,7 @@ void Network::onLoginSuccess(Client *client) m_pool = id; if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool - m_pools.at(2)->disconnect(); + m_pools[2]->disconnect(); } } @@ -130,3 +136,44 @@ void Network::addPool(const Url *url) m_pools.push_back(client); } + + +void Network::startDonate() +{ + if (m_donate) { + return; + } + + LOG_NOTICE("dev donate started"); + + m_donate = true; +} + + +void Network::stopDonate() +{ + if (!m_donate) { + return; + } + + LOG_NOTICE("dev donate finished"); + + m_donate = false; +} + + +void Network::onTimer(uv_timer_t *handle) +{ + auto net = static_cast(handle->data); + + if (!net->m_donate) { + auto url = std::make_unique("donate.xmrig.com", 443); + net->m_pools[0]->connect(url.get()); + + uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); + return; + } + + net->m_pools[0]->disconnect(); + uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0); +} diff --git a/src/net/Network.h b/src/net/Network.h index 89787012..c8191a6e 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -26,6 +26,7 @@ #include +#include #include "interfaces/IClientListener.h" @@ -53,12 +54,17 @@ protected: private: void addPool(const Url *url); + void startDonate(); + void stopDonate(); + + static void onTimer(uv_timer_t *handle); bool m_donate; char *m_agent; const Options *m_options; int m_pool; std::vector m_pools; + uv_timer_t m_timer; }; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index f54b0b92..4e1dfd9f 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -29,6 +29,13 @@ #include "net/Url.h" +Url::Url() : + m_host(nullptr), + m_port(3333) +{ +} + + /** * @brief Parse url. * diff --git a/src/net/Url.h b/src/net/Url.h index a0e2d48d..7d44501d 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -31,6 +31,7 @@ class Url { public: + Url(); Url(const char *url); Url(const char *host, uint16_t port); ~Url(); From 0556fd664c64af910db490b06ce3d4ae349a9d49 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 00:10:26 +0300 Subject: [PATCH 12/92] Add Cpu class. --- CMakeLists.txt | 20 +++++- cpu.c | 100 ---------------------------- src/App.cpp | 20 +----- cpu.h => src/Cpu.cpp | 29 -------- src/Cpu.h | 62 +++++++++++++++++ cpu_stub.c => src/Cpu_stub.cpp | 46 ++++++++----- unix/cpu_unix.c => src/Cpu_unix.cpp | 36 ---------- win/cpu_win.c => src/Cpu_win.cpp | 16 ++--- 8 files changed, 119 insertions(+), 210 deletions(-) delete mode 100644 cpu.c rename cpu.h => src/Cpu.cpp (66%) create mode 100644 src/Cpu.h rename cpu_stub.c => src/Cpu_stub.cpp (79%) rename unix/cpu_unix.c => src/Cpu_unix.cpp (60%) rename win/cpu_win.c => src/Cpu_win.cpp (84%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82641462..e863e739 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.0) project(xmrig) +option(WITH_LIBCPUID "Use Libcpuid" ON) +option(WITH_AEON "CryptoNight-Lite support" ON) + set(HEADERS src/App.h src/interfaces/IClientListener.h @@ -10,6 +13,7 @@ set(HEADERS src/net/Url.h src/Options.h src/Console.h + src/Cpu.h src/version.h ) @@ -29,12 +33,13 @@ if (WIN32) res/app.rc src/3rdparty/winansi.cpp src/3rdparty/winansi.h + src/Cpu_win.cpp src/net/Network_win.cpp ) set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) else() - set(SOURCES_OS unix/cpu_unix.c unix/memory_unix.c unix/xmrig_unix.c) + set(SOURCES_OS src/Cpu_unix.cpp) set(EXTRA_LIBS pthread) endif() @@ -60,6 +65,17 @@ if (WIN32) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") endif() +if (WITH_LIBCPUID) +# add_subdirectory(compat/libcpuid) + +# include_directories(compat/libcpuid) +# set(CPUID_LIB cpuid) +# set(SOURCES_CPUID cpu.c) +else() + add_definitions(/DXMRIG_NO_LIBCPUID) + set(SOURCES_CPUID src/Cpu_stub.cpp) +endif() + include_directories(src) include_directories(src/3rdparty) include_directories(src/3rdparty/jansson) @@ -67,5 +83,5 @@ include_directories(${UV_INCLUDE_DIR}) add_subdirectory(src/3rdparty/jansson) -add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS}) +add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID}) target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS}) diff --git a/cpu.c b/cpu.c deleted file mode 100644 index 2f6ef8b6..00000000 --- a/cpu.c +++ /dev/null @@ -1,100 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#ifndef BUILD_TEST -# include -#endif - -#include "cpu.h" - - -#ifndef BUILD_TEST -void cpu_init_common() { - struct cpu_raw_data_t raw = { 0 }; - struct cpu_id_t data = { 0 }; - - cpuid_get_raw_data(&raw); - cpu_identify(&raw, &data); - - strncpy(cpu_info.brand, data.brand_str, sizeof(cpu_info.brand) - 1); - - cpu_info.total_logical_cpus = data.total_logical_cpus; - cpu_info.sockets = data.total_logical_cpus / data.num_logical_cpus; - cpu_info.total_cores = data.num_cores * cpu_info.sockets; - cpu_info.l3_cache = data.l3_cache > 0 ? data.l3_cache * cpu_info.sockets : 0; - - // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 - if (data.vendor == VENDOR_AMD && data.l3_cache <= 0 && data.l2_assoc == 16 && data.ext_family >= 21) { - cpu_info.l2_cache = data.l2_cache * (cpu_info.total_cores / 2) * cpu_info.sockets; - } - else { - cpu_info.l2_cache = data.l2_cache > 0 ? data.l2_cache * cpu_info.total_cores * cpu_info.sockets : 0; - } - - -# ifdef __x86_64__ - cpu_info.flags |= CPU_FLAG_X86_64; -# endif - - if (data.flags[CPU_FEATURE_AES]) { - cpu_info.flags |= CPU_FLAG_AES; - } - - if (data.flags[CPU_FEATURE_BMI2]) { - cpu_info.flags |= CPU_FLAG_BMI2; - } -} -#endif - - -int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage) { - if (cpu_info.total_logical_cpus == 1) { - return 1; - } - - int cache = cpu_info.l3_cache ? cpu_info.l3_cache : cpu_info.l2_cache; - int count = 0; - const int size = (algo ? 1024 : 2048) * (double_hash ? 2 : 1); - - if (cache) { - count = cache / size; - } - else { - count = cpu_info.total_logical_cpus / 2; - } - - if (count > cpu_info.total_logical_cpus) { - count = cpu_info.total_logical_cpus; - } - - if (((float) count / cpu_info.total_logical_cpus * 100) > max_cpu_usage) { - count = ceil((float) cpu_info.total_logical_cpus * (max_cpu_usage / 100.0)); - } - - return count < 1 ? 1 : count; -} diff --git a/src/App.cpp b/src/App.cpp index a82eb88c..3269f80e 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -27,26 +27,19 @@ #include "App.h" #include "Console.h" +#include "Cpu.h" #include "net/Client.h" #include "net/Network.h" #include "Options.h" #include "version.h" -Client *client; -uv_timer_t timer_req; - - -void timer_cb(uv_timer_t* handle) { - LOG_DEBUG("TIMER"); - - client->disconnect(); -} - App::App(int argc, char **argv) { Console::init(); + Cpu::init(); + m_options = Options::parse(argc, argv); m_network = new Network(m_options); } @@ -69,13 +62,6 @@ App::exec() m_network->connect(); -// uv_timer_init(uv_default_loop(), &timer_req); -// uv_timer_start(&timer_req, timer_cb, 5000, 5000); - - -// client = new Client(); -// client->connect("192.168.2.34", 3333); - const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); uv_loop_close(uv_default_loop()); diff --git a/cpu.h b/src/Cpu.cpp similarity index 66% rename from cpu.h rename to src/Cpu.cpp index 419192bf..8140cd5f 100644 --- a/cpu.h +++ b/src/Cpu.cpp @@ -21,33 +21,4 @@ * along with this program. If not, see . */ -#ifndef __CPU_H__ -#define __CPU_H__ -#include - -struct cpu_info { - int total_cores; - int total_logical_cpus; - int flags; - int sockets; - int l2_cache; - int l3_cache; - char brand[64]; -}; - -extern struct cpu_info cpu_info; - - -enum cpu_flags { - CPU_FLAG_X86_64 = 1, - CPU_FLAG_AES = 2, - CPU_FLAG_BMI2 = 4 -}; - - -void cpu_init(); -int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage); -int affine_to_cpu_mask(int id, unsigned long mask); - -#endif /* __CPU_H__ */ diff --git a/src/Cpu.h b/src/Cpu.h new file mode 100644 index 00000000..7d9e6450 --- /dev/null +++ b/src/Cpu.h @@ -0,0 +1,62 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CPU_H__ +#define __CPU_H__ + + +class Cpu +{ +public: + enum Flags { + X86_64 = 1, + AES = 2, + BMI2 = 4 + }; + + static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage); + static void init(); + static void setAffinity(int id, unsigned long mask); + + static inline bool hasAES() { return m_flags & AES; } + static inline const char *brand() { return m_brand; } + static inline int cores() { return m_totalCores; } + static inline int l2() { return m_l2_cache; } + static inline int l3() { return m_l3_cache; } + static inline int sockets() { return m_sockets; } + static inline int threads() { return m_totalThreads; } + +private: + static void initCommon(); + + static char m_brand[64]; + static int m_flags; + static int m_l2_cache; + static int m_l3_cache; + static int m_sockets; + static int m_totalCores; + static int m_totalThreads; +}; + + +#endif /* __CPU_H__ */ diff --git a/cpu_stub.c b/src/Cpu_stub.cpp similarity index 79% rename from cpu_stub.c rename to src/Cpu_stub.cpp index 83d5efc3..a04bce26 100644 --- a/cpu_stub.c +++ b/src/Cpu_stub.cpp @@ -21,10 +21,12 @@ * along with this program. If not, see . */ + #include #include -#include -#include "cpu.h" + + +#include "Cpu.h" #define VENDOR_ID (0) @@ -52,7 +54,7 @@ static inline void cpuid(int level, int output[4]) { } -static void cpu_brand_string(char* s) { +static inline void cpu_brand_string(char* s) { int cpu_info[4] = { 0 }; cpuid(VENDOR_ID, cpu_info); @@ -66,7 +68,7 @@ static void cpu_brand_string(char* s) { } -static bool has_aes_ni() +static inline bool has_aes_ni() { int cpu_info[4] = { 0 }; cpuid(PROCESSOR_INFO, cpu_info); @@ -75,7 +77,7 @@ static bool has_aes_ni() } -static bool has_bmi2() { +static inline bool has_bmi2() { int cpu_info[4] = { 0 }; cpuid(EXTENDED_FEATURES, cpu_info); @@ -83,25 +85,35 @@ static bool has_bmi2() { } -void cpu_init_common() { - cpu_info.sockets = 1; - cpu_brand_string(cpu_info.brand); +char Cpu::m_brand[64] = { 0 }; +int Cpu::m_flags = 0; +int Cpu::m_l2_cache = 0; +int Cpu::m_l3_cache = 0; +int Cpu::m_sockets = 1; +int Cpu::m_totalCores = 0; +int Cpu::m_totalThreads = 0; + + +int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage) +{ + int count = m_totalThreads / 2; + return count < 1 ? 1 : count; +} + + +void Cpu::initCommon() +{ + cpu_brand_string(m_brand); # ifdef __x86_64__ - cpu_info.flags |= CPU_FLAG_X86_64; + m_flags |= X86_64; # endif if (has_aes_ni()) { - cpu_info.flags |= CPU_FLAG_AES; + m_flags |= AES; } if (has_bmi2()) { - cpu_info.flags |= CPU_FLAG_BMI2; + m_flags |= BMI2; } } - - -int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage) { - int count = cpu_info.total_logical_cpus / 2; - return count < 1 ? 1 : count; -} diff --git a/unix/cpu_unix.c b/src/Cpu_unix.cpp similarity index 60% rename from unix/cpu_unix.c rename to src/Cpu_unix.cpp index 05b859b2..8140cd5f 100644 --- a/unix/cpu_unix.c +++ b/src/Cpu_unix.cpp @@ -21,40 +21,4 @@ * along with this program. If not, see . */ -#include -#include -#include -#include "cpu.h" - - -struct cpu_info cpu_info = { 0 }; -void cpu_init_common(); - - -void cpu_init() { -# ifdef XMRIG_NO_LIBCPUID - cpu_info.total_logical_cpus = sysconf(_SC_NPROCESSORS_CONF); -# endif - - cpu_init_common(); -} - - -int affine_to_cpu_mask(int id, unsigned long mask) -{ - cpu_set_t set; - CPU_ZERO(&set); - - for (unsigned i = 0; i < cpu_info.total_logical_cpus; i++) { - if (mask & (1UL << i)) { - CPU_SET(i, &set); - } - } - - if (id == -1) { - sched_setaffinity(0, sizeof(&set), &set); - } else { - pthread_setaffinity_np(pthread_self(), sizeof(&set), &set); - } -} diff --git a/win/cpu_win.c b/src/Cpu_win.cpp similarity index 84% rename from win/cpu_win.c rename to src/Cpu_win.cpp index 6b5cc7fa..fe4ea0ba 100644 --- a/win/cpu_win.c +++ b/src/Cpu_win.cpp @@ -21,29 +21,27 @@ * along with this program. If not, see . */ + #include -#include - -#include "cpu.h" -struct cpu_info cpu_info = { 0 }; -void cpu_init_common(); +#include "Cpu.h" -void cpu_init() { +void Cpu::init() +{ # ifdef XMRIG_NO_LIBCPUID SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); - cpu_info.total_logical_cpus = sysinfo.dwNumberOfProcessors; + m_totalThreads = sysinfo.dwNumberOfProcessors; # endif - cpu_init_common(); + initCommon(); } -int affine_to_cpu_mask(int id, unsigned long mask) +void Cpu::setAffinity(int id, unsigned long mask) { if (id == -1) { SetProcessAffinityMask(GetCurrentProcess(), mask); From 9797f4945628c5fb2cafbf5b40a016b347476d22 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 01:16:45 +0300 Subject: [PATCH 13/92] Add Summary. --- CMakeLists.txt | 2 + src/App.cpp | 3 + src/Cpu.h | 1 + src/Options.h | 1 + src/Summary.cpp | 85 ++++++++++++++++++++++ utils/summary.h => src/Summary.h | 8 +- utils/summary.c | 121 ------------------------------- 7 files changed, 99 insertions(+), 122 deletions(-) create mode 100644 src/Summary.cpp rename utils/summary.h => src/Summary.h (95%) delete mode 100644 utils/summary.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e863e739..66200623 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ set(HEADERS src/Options.h src/Console.h src/Cpu.h + src/Summary.h src/version.h ) @@ -25,6 +26,7 @@ set(SOURCES src/net/Url.cpp src/Options.cpp src/Console.cpp + src/Summary.cpp src/xmrig.cpp ) diff --git a/src/App.cpp b/src/App.cpp index 3269f80e..e7cf1aa4 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -31,6 +31,7 @@ #include "net/Client.h" #include "net/Network.h" #include "Options.h" +#include "Summary.h" #include "version.h" @@ -60,6 +61,8 @@ App::exec() return 0; } + Summary::print(); + m_network->connect(); const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); diff --git a/src/Cpu.h b/src/Cpu.h index 7d9e6450..292c6c6c 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -39,6 +39,7 @@ public: static void setAffinity(int id, unsigned long mask); static inline bool hasAES() { return m_flags & AES; } + static inline bool isX64() { return m_flags & X86_64; } static inline const char *brand() { return m_brand; } static inline int cores() { return m_totalCores; } static inline int l2() { return m_l2_cache; } diff --git a/src/Options.h b/src/Options.h index 16733cca..0c1dcc6e 100644 --- a/src/Options.h +++ b/src/Options.h @@ -51,6 +51,7 @@ public: static inline Options* i() { return m_self; } static Options *parse(int argc, char **argv); + inline bool colors() const { return m_colors; } inline bool isReady() const { return m_ready; } inline bool keepAlive() const { return m_keepAlive; } inline const char *pass() const { return m_pass; } diff --git a/src/Summary.cpp b/src/Summary.cpp new file mode 100644 index 00000000..4e047360 --- /dev/null +++ b/src/Summary.cpp @@ -0,0 +1,85 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "Summary.h" +#include "Console.h" +#include "Cpu.h" +#include "Options.h" +#include "version.h" + + + +static void print_versions() +{ + char *buf = static_cast(malloc(16)); + +# ifdef __GNUC__ + snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# else + buf[0] = '\0'; +# endif + + + if (Options::i()->colors()) { + Console::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf); + } else { + Console::i()->text(" * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf); + } + + free(buf); +} + + +static void print_cpu() +{ + if (Options::i()->colors()) { + Console::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI", + Cpu::brand(), + Cpu::sockets(), + Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-", + Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-"); +# ifndef XMRIG_NO_LIBCPUID + Console::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); +# endif + } + else { + Console::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-"); +# ifndef XMRIG_NO_LIBCPUID + Console::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); +# endif + } +} + + +void Summary::print() +{ + print_versions(); + print_cpu(); +} + + + diff --git a/utils/summary.h b/src/Summary.h similarity index 95% rename from utils/summary.h rename to src/Summary.h index 628c5304..3f64fd60 100644 --- a/utils/summary.h +++ b/src/Summary.h @@ -24,6 +24,12 @@ #ifndef __SUMMARY_H__ #define __SUMMARY_H__ -void print_summary(); + +class Summary +{ +public: + static void print(); +}; + #endif /* __SUMMARY_H__ */ diff --git a/utils/summary.c b/utils/summary.c deleted file mode 100644 index 65912bb0..00000000 --- a/utils/summary.c +++ /dev/null @@ -1,121 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "options.h" -#include "applog.h" -#include "version.h" -#include "persistent_memory.h" -#include "cpu.h" - - -static void print_memory() { - const char *t1 = (persistent_memory_flags & MEMORY_HUGEPAGES_AVAILABLE) ? OPT_COLOR(CL_LGR, "available") : OPT_COLOR(CL_LRD, "unavailable"); - const char *t2 = (persistent_memory_flags & MEMORY_HUGEPAGES_ENABLED) ? OPT_COLOR(CL_LGR, "enabled") : OPT_COLOR(CL_LRD, "disabled"); - - if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "HUGE PAGES: %s, %s", t1, t2); - } - else { - applog_notime(LOG_INFO, " * HUGE PAGES: %s, %s", t1, t2); - } -} - - -static void print_cpu() { - const char *t1 = (cpu_info.flags & CPU_FLAG_X86_64) ? OPT_COLOR(CL_LGR, "x86_64") : OPT_COLOR(CL_LRD, "-x86_64"); - const char *t2 = (cpu_info.flags & CPU_FLAG_AES) ? OPT_COLOR(CL_LGR, "AES-NI") : OPT_COLOR(CL_LRD, "-AES-NI"); - - if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU: %s (%d)", cpu_info.brand, cpu_info.sockets); - } - else { - applog_notime(LOG_INFO, " * CPU: %s (%d)", cpu_info.brand, cpu_info.sockets); - } - - # ifndef XMRIG_NO_LIBCPUID - if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU L2/L3: %.1f MB/%.1f MB", cpu_info.l2_cache / 1024.0, cpu_info.l3_cache / 1024.0); - } - else { - applog_notime(LOG_INFO, " * CPU L2/L3: %.1f MB/%.1f MB", cpu_info.l2_cache / 1024.0, cpu_info.l3_cache / 1024.0); - } - # endif - - if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU FEATURES: %s %s", t1, t2); - } - else { - applog_notime(LOG_INFO, " * CPU FEATURES: %s %s", t1, t2); - } -} - - -static void print_threads() { - const char *extra = ""; - if (opt_nicehash) { - extra = ", nicehash"; - } - - if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "THREADS: " CL_WHT "%d" CL_WHT ", av=%d, %s, donate=%d%%%s", opt_n_threads, opt_algo_variant, get_current_algo_name(), opt_donate_level, extra); - } - else { - applog_notime(LOG_INFO, " * THREADS: %d, av=%d, %s, donate=%d%%%s", opt_n_threads, opt_algo_variant, get_current_algo_name(), opt_donate_level, extra); - } -} - - -static void print_stratum() { - if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "STRATUM URL: " CL_LCY "%s", opt_url); - - if (opt_backup_url) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "FAILOVER URL: " CL_LCY "%s", opt_backup_url); - } - else { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "FAILOVER URL: " CL_LRD "none"); - } - } - else { - applog_notime(LOG_INFO, " * STRATUM URL: %s", opt_url); - applog_notime(LOG_INFO, " * FAILOVER URL: %s", opt_backup_url ? opt_backup_url : "none"); - } -} - - -void print_summary() { - if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT APP_NAME " " APP_VERSION " " CL_LCY APP_SITE); - } - else { - applog_notime(LOG_INFO, " * " APP_NAME " " APP_VERSION " " APP_SITE); - } - - print_memory(); - print_cpu(); - print_threads(); - print_stratum(); -} - - - From b11f95d2481d68b777605c096c1a46db7bd70b71 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 01:51:24 +0300 Subject: [PATCH 14/92] Restore libcpuid support. --- CMakeLists.txt | 10 +- .../3rdparty}/libcpuid/CMakeLists.txt | 14 +- .../3rdparty}/libcpuid/amd_code_t.h | 0 {compat => src/3rdparty}/libcpuid/asm-bits.c | 0 {compat => src/3rdparty}/libcpuid/asm-bits.h | 0 .../3rdparty}/libcpuid/cpuid_main.c | 337 +++++++++++++++++- .../3rdparty}/libcpuid/intel_code_t.h | 0 {compat => src/3rdparty}/libcpuid/libcpuid.h | 0 .../3rdparty}/libcpuid/libcpuid_constants.h | 0 .../3rdparty}/libcpuid/libcpuid_internal.h | 42 +++ .../3rdparty}/libcpuid/libcpuid_types.h | 0 .../3rdparty}/libcpuid/libcpuid_util.c | 0 .../3rdparty}/libcpuid/libcpuid_util.h | 2 - {compat => src/3rdparty}/libcpuid/recog_amd.c | 23 +- {compat => src/3rdparty}/libcpuid/recog_amd.h | 0 .../3rdparty}/libcpuid/recog_intel.c | 25 +- .../3rdparty}/libcpuid/recog_intel.h | 0 src/Cpu.cpp | 81 +++++ src/Summary.cpp | 3 +- 19 files changed, 478 insertions(+), 59 deletions(-) rename {compat => src/3rdparty}/libcpuid/CMakeLists.txt (68%) rename {compat => src/3rdparty}/libcpuid/amd_code_t.h (100%) rename {compat => src/3rdparty}/libcpuid/asm-bits.c (100%) rename {compat => src/3rdparty}/libcpuid/asm-bits.h (100%) rename {compat => src/3rdparty}/libcpuid/cpuid_main.c (55%) rename {compat => src/3rdparty}/libcpuid/intel_code_t.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_constants.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_internal.h (66%) rename {compat => src/3rdparty}/libcpuid/libcpuid_types.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_util.c (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_util.h (98%) rename {compat => src/3rdparty}/libcpuid/recog_amd.c (98%) rename {compat => src/3rdparty}/libcpuid/recog_amd.h (100%) rename {compat => src/3rdparty}/libcpuid/recog_intel.c (98%) rename {compat => src/3rdparty}/libcpuid/recog_intel.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66200623..11a6d1bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,11 +68,11 @@ if (WIN32) endif() if (WITH_LIBCPUID) -# add_subdirectory(compat/libcpuid) + add_subdirectory(src/3rdparty/libcpuid) -# include_directories(compat/libcpuid) -# set(CPUID_LIB cpuid) -# set(SOURCES_CPUID cpu.c) + include_directories(src/3rdparty/libcpuid) + set(CPUID_LIB cpuid) + set(SOURCES_CPUID src/Cpu.cpp) else() add_definitions(/DXMRIG_NO_LIBCPUID) set(SOURCES_CPUID src/Cpu_stub.cpp) @@ -86,4 +86,4 @@ include_directories(${UV_INCLUDE_DIR}) add_subdirectory(src/3rdparty/jansson) add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID}) -target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS}) +target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB}) diff --git a/compat/libcpuid/CMakeLists.txt b/src/3rdparty/libcpuid/CMakeLists.txt similarity index 68% rename from compat/libcpuid/CMakeLists.txt rename to src/3rdparty/libcpuid/CMakeLists.txt index 5c37492a..ef541cc3 100644 --- a/compat/libcpuid/CMakeLists.txt +++ b/src/3rdparty/libcpuid/CMakeLists.txt @@ -3,17 +3,19 @@ project (cpuid C) add_definitions(/DVERSION="0.4.0") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") + set(HEADERS libcpuid.h libcpuid_types.h libcpuid_constants.h libcpuid_internal.h -amd_code_t.h -intel_code_t.h -recog_amd.h -recog_intel.h -asm-bits.h -libcpuid_util.h + amd_code_t.h + intel_code_t.h + recog_amd.h + recog_intel.h + asm-bits.h + libcpuid_util.h ) set(SOURCES diff --git a/compat/libcpuid/amd_code_t.h b/src/3rdparty/libcpuid/amd_code_t.h similarity index 100% rename from compat/libcpuid/amd_code_t.h rename to src/3rdparty/libcpuid/amd_code_t.h diff --git a/compat/libcpuid/asm-bits.c b/src/3rdparty/libcpuid/asm-bits.c similarity index 100% rename from compat/libcpuid/asm-bits.c rename to src/3rdparty/libcpuid/asm-bits.c diff --git a/compat/libcpuid/asm-bits.h b/src/3rdparty/libcpuid/asm-bits.h similarity index 100% rename from compat/libcpuid/asm-bits.h rename to src/3rdparty/libcpuid/asm-bits.h diff --git a/compat/libcpuid/cpuid_main.c b/src/3rdparty/libcpuid/cpuid_main.c similarity index 55% rename from compat/libcpuid/cpuid_main.c rename to src/3rdparty/libcpuid/cpuid_main.c index 64c4198b..504c0af8 100644 --- a/compat/libcpuid/cpuid_main.c +++ b/src/3rdparty/libcpuid/cpuid_main.c @@ -117,7 +117,7 @@ static int get_total_cpus(void) #if defined linux || defined __linux__ || defined __sun #include #include - + static int get_total_cpus(void) { return sysconf(_SC_NPROCESSORS_ONLN); @@ -302,7 +302,7 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat data->ext_model = data->model + (xmodel << 4); } ext = raw->ext_cpuid[0][0] - 0x8000000; - + /* obtain the brand string, if present: */ if (ext >= 4) { for (i = 0; i < 3; i++) @@ -401,6 +401,107 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data) return set_error(ERR_OK); } +int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename) +{ + int i; + FILE *f; + + if (!strcmp(filename, "")) + f = stdout; + else + f = fopen(filename, "wt"); + if (!f) return set_error(ERR_OPEN); + + fprintf(f, "version=%s\n", VERSION); + for (i = 0; i < MAX_CPUID_LEVEL; i++) + fprintf(f, "basic_cpuid[%d]=%08x %08x %08x %08x\n", i, + data->basic_cpuid[i][0], data->basic_cpuid[i][1], + data->basic_cpuid[i][2], data->basic_cpuid[i][3]); + for (i = 0; i < MAX_EXT_CPUID_LEVEL; i++) + fprintf(f, "ext_cpuid[%d]=%08x %08x %08x %08x\n", i, + data->ext_cpuid[i][0], data->ext_cpuid[i][1], + data->ext_cpuid[i][2], data->ext_cpuid[i][3]); + for (i = 0; i < MAX_INTELFN4_LEVEL; i++) + fprintf(f, "intel_fn4[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn4[i][0], data->intel_fn4[i][1], + data->intel_fn4[i][2], data->intel_fn4[i][3]); + for (i = 0; i < MAX_INTELFN11_LEVEL; i++) + fprintf(f, "intel_fn11[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn11[i][0], data->intel_fn11[i][1], + data->intel_fn11[i][2], data->intel_fn11[i][3]); + for (i = 0; i < MAX_INTELFN12H_LEVEL; i++) + fprintf(f, "intel_fn12h[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn12h[i][0], data->intel_fn12h[i][1], + data->intel_fn12h[i][2], data->intel_fn12h[i][3]); + for (i = 0; i < MAX_INTELFN14H_LEVEL; i++) + fprintf(f, "intel_fn14h[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn14h[i][0], data->intel_fn14h[i][1], + data->intel_fn14h[i][2], data->intel_fn14h[i][3]); + + if (strcmp(filename, "")) + fclose(f); + return set_error(ERR_OK); +} + +int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename) +{ + int i, len; + char line[100]; + char token[100]; + char *value; + int syntax; + int cur_line = 0; + int recognized; + FILE *f; + + raw_data_t_constructor(data); + + if (!strcmp(filename, "")) + f = stdin; + else + f = fopen(filename, "rt"); + if (!f) return set_error(ERR_OPEN); + while (fgets(line, sizeof(line), f)) { + ++cur_line; + len = (int) strlen(line); + if (len < 2) continue; + if (line[len - 1] == '\n') + line[--len] = '\0'; + for (i = 0; i < len && line[i] != '='; i++) + if (i >= len && i < 1 && len - i - 1 <= 0) { + fclose(f); + return set_error(ERR_BADFMT); + } + strncpy(token, line, i); + token[i] = '\0'; + value = &line[i + 1]; + /* try to recognize the line */ + recognized = 0; + if (!strcmp(token, "version") || !strcmp(token, "build_date")) { + recognized = 1; + } + syntax = 1; + syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, MAX_CPUID_LEVEL, &recognized); + syntax = syntax && parse_token("ext_cpuid", token, value, data->ext_cpuid, MAX_EXT_CPUID_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn4", token, value, data->intel_fn4, MAX_INTELFN4_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn12h", token, value, data->intel_fn12h, MAX_INTELFN12H_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn14h", token, value, data->intel_fn14h, MAX_INTELFN14H_LEVEL, &recognized); + if (!syntax) { + warnf("Error: %s:%d: Syntax error\n", filename, cur_line); + fclose(f); + return set_error(ERR_BADFMT); + } + if (!recognized) { + warnf("Warning: %s:%d not understood!\n", filename, cur_line); + } + } + + if (strcmp(filename, "")) + fclose(f); + return set_error(ERR_OK); +} + int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { int r; @@ -432,7 +533,239 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) return cpu_ident_internal(raw, data, &throwaway); } +const char* cpu_feature_str(cpu_feature_t feature) +{ + const struct { cpu_feature_t feature; const char* name; } + matchtable[] = { + { CPU_FEATURE_FPU, "fpu" }, + { CPU_FEATURE_VME, "vme" }, + { CPU_FEATURE_DE, "de" }, + { CPU_FEATURE_PSE, "pse" }, + { CPU_FEATURE_TSC, "tsc" }, + { CPU_FEATURE_MSR, "msr" }, + { CPU_FEATURE_PAE, "pae" }, + { CPU_FEATURE_MCE, "mce" }, + { CPU_FEATURE_CX8, "cx8" }, + { CPU_FEATURE_APIC, "apic" }, + { CPU_FEATURE_MTRR, "mtrr" }, + { CPU_FEATURE_SEP, "sep" }, + { CPU_FEATURE_PGE, "pge" }, + { CPU_FEATURE_MCA, "mca" }, + { CPU_FEATURE_CMOV, "cmov" }, + { CPU_FEATURE_PAT, "pat" }, + { CPU_FEATURE_PSE36, "pse36" }, + { CPU_FEATURE_PN, "pn" }, + { CPU_FEATURE_CLFLUSH, "clflush" }, + { CPU_FEATURE_DTS, "dts" }, + { CPU_FEATURE_ACPI, "acpi" }, + { CPU_FEATURE_MMX, "mmx" }, + { CPU_FEATURE_FXSR, "fxsr" }, + { CPU_FEATURE_SSE, "sse" }, + { CPU_FEATURE_SSE2, "sse2" }, + { CPU_FEATURE_SS, "ss" }, + { CPU_FEATURE_HT, "ht" }, + { CPU_FEATURE_TM, "tm" }, + { CPU_FEATURE_IA64, "ia64" }, + { CPU_FEATURE_PBE, "pbe" }, + { CPU_FEATURE_PNI, "pni" }, + { CPU_FEATURE_PCLMUL, "pclmul" }, + { CPU_FEATURE_DTS64, "dts64" }, + { CPU_FEATURE_MONITOR, "monitor" }, + { CPU_FEATURE_DS_CPL, "ds_cpl" }, + { CPU_FEATURE_VMX, "vmx" }, + { CPU_FEATURE_SMX, "smx" }, + { CPU_FEATURE_EST, "est" }, + { CPU_FEATURE_TM2, "tm2" }, + { CPU_FEATURE_SSSE3, "ssse3" }, + { CPU_FEATURE_CID, "cid" }, + { CPU_FEATURE_CX16, "cx16" }, + { CPU_FEATURE_XTPR, "xtpr" }, + { CPU_FEATURE_PDCM, "pdcm" }, + { CPU_FEATURE_DCA, "dca" }, + { CPU_FEATURE_SSE4_1, "sse4_1" }, + { CPU_FEATURE_SSE4_2, "sse4_2" }, + { CPU_FEATURE_SYSCALL, "syscall" }, + { CPU_FEATURE_XD, "xd" }, + { CPU_FEATURE_X2APIC, "x2apic"}, + { CPU_FEATURE_MOVBE, "movbe" }, + { CPU_FEATURE_POPCNT, "popcnt" }, + { CPU_FEATURE_AES, "aes" }, + { CPU_FEATURE_XSAVE, "xsave" }, + { CPU_FEATURE_OSXSAVE, "osxsave" }, + { CPU_FEATURE_AVX, "avx" }, + { CPU_FEATURE_MMXEXT, "mmxext" }, + { CPU_FEATURE_3DNOW, "3dnow" }, + { CPU_FEATURE_3DNOWEXT, "3dnowext" }, + { CPU_FEATURE_NX, "nx" }, + { CPU_FEATURE_FXSR_OPT, "fxsr_opt" }, + { CPU_FEATURE_RDTSCP, "rdtscp" }, + { CPU_FEATURE_LM, "lm" }, + { CPU_FEATURE_LAHF_LM, "lahf_lm" }, + { CPU_FEATURE_CMP_LEGACY, "cmp_legacy" }, + { CPU_FEATURE_SVM, "svm" }, + { CPU_FEATURE_SSE4A, "sse4a" }, + { CPU_FEATURE_MISALIGNSSE, "misalignsse" }, + { CPU_FEATURE_ABM, "abm" }, + { CPU_FEATURE_3DNOWPREFETCH, "3dnowprefetch" }, + { CPU_FEATURE_OSVW, "osvw" }, + { CPU_FEATURE_IBS, "ibs" }, + { CPU_FEATURE_SSE5, "sse5" }, + { CPU_FEATURE_SKINIT, "skinit" }, + { CPU_FEATURE_WDT, "wdt" }, + { CPU_FEATURE_TS, "ts" }, + { CPU_FEATURE_FID, "fid" }, + { CPU_FEATURE_VID, "vid" }, + { CPU_FEATURE_TTP, "ttp" }, + { CPU_FEATURE_TM_AMD, "tm_amd" }, + { CPU_FEATURE_STC, "stc" }, + { CPU_FEATURE_100MHZSTEPS, "100mhzsteps" }, + { CPU_FEATURE_HWPSTATE, "hwpstate" }, + { CPU_FEATURE_CONSTANT_TSC, "constant_tsc" }, + { CPU_FEATURE_XOP, "xop" }, + { CPU_FEATURE_FMA3, "fma3" }, + { CPU_FEATURE_FMA4, "fma4" }, + { CPU_FEATURE_TBM, "tbm" }, + { CPU_FEATURE_F16C, "f16c" }, + { CPU_FEATURE_RDRAND, "rdrand" }, + { CPU_FEATURE_CPB, "cpb" }, + { CPU_FEATURE_APERFMPERF, "aperfmperf" }, + { CPU_FEATURE_PFI, "pfi" }, + { CPU_FEATURE_PA, "pa" }, + { CPU_FEATURE_AVX2, "avx2" }, + { CPU_FEATURE_BMI1, "bmi1" }, + { CPU_FEATURE_BMI2, "bmi2" }, + { CPU_FEATURE_HLE, "hle" }, + { CPU_FEATURE_RTM, "rtm" }, + { CPU_FEATURE_AVX512F, "avx512f" }, + { CPU_FEATURE_AVX512DQ, "avx512dq" }, + { CPU_FEATURE_AVX512PF, "avx512pf" }, + { CPU_FEATURE_AVX512ER, "avx512er" }, + { CPU_FEATURE_AVX512CD, "avx512cd" }, + { CPU_FEATURE_SHA_NI, "sha_ni" }, + { CPU_FEATURE_AVX512BW, "avx512bw" }, + { CPU_FEATURE_AVX512VL, "avx512vl" }, + { CPU_FEATURE_SGX, "sgx" }, + { CPU_FEATURE_RDSEED, "rdseed" }, + { CPU_FEATURE_ADX, "adx" }, + }; + unsigned i, n = COUNT_OF(matchtable); + if (n != NUM_CPU_FEATURES) { + warnf("Warning: incomplete library, feature matchtable size differs from the actual number of features.\n"); + } + for (i = 0; i < n; i++) + if (matchtable[i].feature == feature) + return matchtable[i].name; + return ""; +} + +const char* cpuid_error(void) +{ + const struct { cpu_error_t error; const char *description; } + matchtable[] = { + { ERR_OK , "No error"}, + { ERR_NO_CPUID , "CPUID instruction is not supported"}, + { ERR_NO_RDTSC , "RDTSC instruction is not supported"}, + { ERR_NO_MEM , "Memory allocation failed"}, + { ERR_OPEN , "File open operation failed"}, + { ERR_BADFMT , "Bad file format"}, + { ERR_NOT_IMP , "Not implemented"}, + { ERR_CPU_UNKN , "Unsupported processor"}, + { ERR_NO_RDMSR , "RDMSR instruction is not supported"}, + { ERR_NO_DRIVER, "RDMSR driver error (generic)"}, + { ERR_NO_PERMS , "No permissions to install RDMSR driver"}, + { ERR_EXTRACT , "Cannot extract RDMSR driver (read only media?)"}, + { ERR_HANDLE , "Bad handle"}, + { ERR_INVMSR , "Invalid MSR"}, + { ERR_INVCNB , "Invalid core number"}, + { ERR_HANDLE_R , "Error on handle read"}, + { ERR_INVRANGE , "Invalid given range"}, + }; + unsigned i; + for (i = 0; i < COUNT_OF(matchtable); i++) + if (_libcpiud_errno == matchtable[i].error) + return matchtable[i].description; + return "Unknown error"; +} + + const char* cpuid_lib_version(void) { return VERSION; } + +libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t new_fn) +{ + libcpuid_warn_fn_t ret = _warn_fun; + _warn_fun = new_fn; + return ret; +} + +void cpuid_set_verbosiness_level(int level) +{ + _current_verboselevel = level; +} + +cpu_vendor_t cpuid_get_vendor(void) +{ + static cpu_vendor_t vendor = VENDOR_UNKNOWN; + uint32_t raw_vendor[4]; + char vendor_str[VENDOR_STR_MAX]; + + if(vendor == VENDOR_UNKNOWN) { + if (!cpuid_present()) + set_error(ERR_NO_CPUID); + else { + cpu_exec_cpuid(0, raw_vendor); + vendor = cpuid_vendor_identify(raw_vendor, vendor_str); + } + } + return vendor; +} + +void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list) +{ + switch (vendor) { + case VENDOR_INTEL: + cpuid_get_list_intel(list); + break; + case VENDOR_AMD: + cpuid_get_list_amd(list); + break; + case VENDOR_CYRIX: + make_list_from_string("Cx486,Cx5x86,6x86,6x86MX,M II,MediaGX,MediaGXi,MediaGXm", list); + break; + case VENDOR_NEXGEN: + make_list_from_string("Nx586", list); + break; + case VENDOR_TRANSMETA: + make_list_from_string("Crusoe,Efficeon", list); + break; + case VENDOR_UMC: + make_list_from_string("UMC x86 CPU", list); + break; + case VENDOR_CENTAUR: + make_list_from_string("VIA C3,VIA C7,VIA Nano", list); + break; + case VENDOR_RISE: + make_list_from_string("Rise mP6", list); + break; + case VENDOR_SIS: + make_list_from_string("SiS mP6", list); + break; + case VENDOR_NSC: + make_list_from_string("Geode GXm,Geode GXLV,Geode GX1,Geode GX2", list); + break; + default: + warnf("Unknown vendor passed to cpuid_get_cpu_list()\n"); + break; + } +} + +void cpuid_free_cpu_list(struct cpu_list_t* list) +{ + int i; + if (list->num_entries <= 0) return; + for (i = 0; i < list->num_entries; i++) + free(list->names[i]); + free(list->names); +} diff --git a/compat/libcpuid/intel_code_t.h b/src/3rdparty/libcpuid/intel_code_t.h similarity index 100% rename from compat/libcpuid/intel_code_t.h rename to src/3rdparty/libcpuid/intel_code_t.h diff --git a/compat/libcpuid/libcpuid.h b/src/3rdparty/libcpuid/libcpuid.h similarity index 100% rename from compat/libcpuid/libcpuid.h rename to src/3rdparty/libcpuid/libcpuid.h diff --git a/compat/libcpuid/libcpuid_constants.h b/src/3rdparty/libcpuid/libcpuid_constants.h similarity index 100% rename from compat/libcpuid/libcpuid_constants.h rename to src/3rdparty/libcpuid/libcpuid_constants.h diff --git a/compat/libcpuid/libcpuid_internal.h b/src/3rdparty/libcpuid/libcpuid_internal.h similarity index 66% rename from compat/libcpuid/libcpuid_internal.h rename to src/3rdparty/libcpuid/libcpuid_internal.h index 7f3671da..038aa209 100644 --- a/compat/libcpuid/libcpuid_internal.h +++ b/src/3rdparty/libcpuid/libcpuid_internal.h @@ -58,6 +58,48 @@ struct internal_id_info_t { int score; // detection (matchtable) score }; +#define LBIT(x) (((long long) 1) << x) + +enum _common_bits_t { + _M_ = LBIT( 0 ), + MOBILE_ = LBIT( 1 ), + _MP_ = LBIT( 2 ), +}; + +// additional detection bits for Intel CPUs: +enum _intel_bits_t { + PENTIUM_ = LBIT( 10 ), + CELERON_ = LBIT( 11 ), + CORE_ = LBIT( 12 ), + _I_ = LBIT( 13 ), + _3 = LBIT( 14 ), + _5 = LBIT( 15 ), + _7 = LBIT( 16 ), + XEON_ = LBIT( 17 ), + ATOM_ = LBIT( 18 ), +}; +typedef enum _intel_bits_t intel_bits_t; + +enum _amd_bits_t { + ATHLON_ = LBIT( 10 ), + _XP_ = LBIT( 11 ), + DURON_ = LBIT( 12 ), + SEMPRON_ = LBIT( 13 ), + OPTERON_ = LBIT( 14 ), + TURION_ = LBIT( 15 ), + _LV_ = LBIT( 16 ), + _64_ = LBIT( 17 ), + _X2 = LBIT( 18 ), + _X3 = LBIT( 19 ), + _X4 = LBIT( 20 ), + _X6 = LBIT( 21 ), + _FX = LBIT( 22 ), + _APU_ = LBIT( 23 ), +}; +typedef enum _amd_bits_t amd_bits_t; + + + int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal); diff --git a/compat/libcpuid/libcpuid_types.h b/src/3rdparty/libcpuid/libcpuid_types.h similarity index 100% rename from compat/libcpuid/libcpuid_types.h rename to src/3rdparty/libcpuid/libcpuid_types.h diff --git a/compat/libcpuid/libcpuid_util.c b/src/3rdparty/libcpuid/libcpuid_util.c similarity index 100% rename from compat/libcpuid/libcpuid_util.c rename to src/3rdparty/libcpuid/libcpuid_util.c diff --git a/compat/libcpuid/libcpuid_util.h b/src/3rdparty/libcpuid/libcpuid_util.h similarity index 98% rename from compat/libcpuid/libcpuid_util.h rename to src/3rdparty/libcpuid/libcpuid_util.h index aba63f1a..c3b53933 100644 --- a/compat/libcpuid/libcpuid_util.h +++ b/src/3rdparty/libcpuid/libcpuid_util.h @@ -28,8 +28,6 @@ #define COUNT_OF(array) (sizeof(array) / sizeof(array[0])) -#define LBIT(x) (((long long) 1) << x) - struct feature_map_t { unsigned bit; cpu_feature_t feature; diff --git a/compat/libcpuid/recog_amd.c b/src/3rdparty/libcpuid/recog_amd.c similarity index 98% rename from compat/libcpuid/recog_amd.c rename to src/3rdparty/libcpuid/recog_amd.c index b735c400..3867aa8c 100644 --- a/compat/libcpuid/recog_amd.c +++ b/src/3rdparty/libcpuid/recog_amd.c @@ -44,26 +44,6 @@ struct amd_code_and_bits_t { uint64_t bits; }; -enum _amd_bits_t { - ATHLON_ = LBIT( 0 ), - _XP_ = LBIT( 1 ), - _M_ = LBIT( 2 ), - _MP_ = LBIT( 3 ), - MOBILE_ = LBIT( 4 ), - DURON_ = LBIT( 5 ), - SEMPRON_ = LBIT( 6 ), - OPTERON_ = LBIT( 7 ), - TURION_ = LBIT( 8 ), - _LV_ = LBIT( 9 ), - _64_ = LBIT( 10 ), - _X2 = LBIT( 11 ), - _X3 = LBIT( 12 ), - _X4 = LBIT( 13 ), - _X6 = LBIT( 14 ), - _FX = LBIT( 15 ), -}; -typedef enum _amd_bits_t amd_bits_t; - enum _amd_model_codes_t { // Only for Ryzen CPUs: _1400, @@ -469,11 +449,12 @@ static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) if (strstr(bs, "XP")) bits |= _XP_; if (strstr(bs, "XP-M")) bits |= _M_; if (strstr(bs, "(LV)")) bits |= _LV_; + if (strstr(bs, " APU ")) bits |= _APU_; if (match_pattern(bs, "C-##")) code = FUSION_C; if (match_pattern(bs, "E-###")) code = FUSION_E; if (match_pattern(bs, "Z-##")) code = FUSION_Z; - if (match_pattern(bs, "E#-####") || match_pattern(bs, "A#-####")) code = FUSION_EA; + if (match_pattern(bs, "[EA]#-####")) code = FUSION_EA; result.code = code; result.bits = bits; diff --git a/compat/libcpuid/recog_amd.h b/src/3rdparty/libcpuid/recog_amd.h similarity index 100% rename from compat/libcpuid/recog_amd.h rename to src/3rdparty/libcpuid/recog_amd.h diff --git a/compat/libcpuid/recog_intel.c b/src/3rdparty/libcpuid/recog_intel.c similarity index 98% rename from compat/libcpuid/recog_intel.c rename to src/3rdparty/libcpuid/recog_intel.c index 1d6c6a84..5e6c03b0 100644 --- a/compat/libcpuid/recog_intel.c +++ b/src/3rdparty/libcpuid/recog_intel.c @@ -59,23 +59,6 @@ enum _intel_model_t { }; typedef enum _intel_model_t intel_model_t; -enum _intel_bits_t { - PENTIUM_ = LBIT( 0 ), - CELERON_ = LBIT( 1 ), - MOBILE_ = LBIT( 2 ), - CORE_ = LBIT( 3 ), - _I_ = LBIT( 4 ), - _M_ = LBIT( 5 ), - _3 = LBIT( 6 ), - _5 = LBIT( 7 ), - _7 = LBIT( 8 ), - XEON_ = LBIT( 9 ), - _MP = LBIT( 10 ), - ATOM_ = LBIT( 11 ), - -}; -typedef enum _intel_bits_t intel_bits_t; - const struct match_entry_t cpudb_intel[] = { { -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Intel CPU" }, @@ -158,11 +141,11 @@ const struct match_entry_t cpudb_intel[] = { { 15, 0, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" }, { 15, 1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" }, { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Prestonia)" }, - { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP , 0, "Xeon (Gallatin)" }, + { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Gallatin)" }, { 15, 3, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" }, { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" }, { 15, 4, -1, 15, -1, 1, -1, -1, IRWIN, XEON_ , 0, "Xeon (Irwindale)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP , 0, "Xeon (Cranford)" }, + { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Cranford)" }, { 15, 4, -1, 15, -1, 1, -1, -1, POTOMAC, XEON_ , 0, "Xeon (Potomac)" }, { 15, 6, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Dempsey)" }, @@ -668,7 +651,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) const struct { uint64_t bit; const char* search; } bit_matchtable[] = { { XEON_, "Xeon" }, - { _MP, " MP" }, + { _MP_, " MP" }, { ATOM_, "Atom(TM) CPU" }, { MOBILE_, "Mobile" }, { CELERON_, "Celeron" }, @@ -710,7 +693,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) /* restrict by family, since later Xeons also have L3 ... */ code = IRWIN; } - if (match_all(bits, XEON_ + _MP) && data->l3_cache > 0) + if (match_all(bits, XEON_ + _MP_) && data->l3_cache > 0) code = POTOMAC; if (code == CORE_SOLO) { s = strstr(bs, "CPU"); diff --git a/compat/libcpuid/recog_intel.h b/src/3rdparty/libcpuid/recog_intel.h similarity index 100% rename from compat/libcpuid/recog_intel.h rename to src/3rdparty/libcpuid/recog_intel.h diff --git a/src/Cpu.cpp b/src/Cpu.cpp index 8140cd5f..53d81e58 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -22,3 +22,84 @@ */ +#include +#include +#include + +#include "Cpu.h" + + +char Cpu::m_brand[64] = { 0 }; +int Cpu::m_flags = 0; +int Cpu::m_l2_cache = 0; +int Cpu::m_l3_cache = 0; +int Cpu::m_sockets = 1; +int Cpu::m_totalCores = 0; +int Cpu::m_totalThreads = 0; + + +int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage) +{ + if (m_totalThreads == 1) { + return 1; + } + + int cache = m_l3_cache ? m_l3_cache : m_l2_cache; + int count = 0; + const int size = (algo ? 1024 : 2048) * (doubleHash ? 2 : 1); + + if (cache) { + count = cache / size; + } + else { + count = m_totalThreads / 2; + } + + if (count > m_totalThreads) { + count = m_totalThreads; + } + + if (((float) count / m_totalThreads * 100) > maxCpuUsage) { + count = ceil((float) m_totalThreads * (maxCpuUsage / 100.0)); + } + + return count < 1 ? 1 : count; +} + + +void Cpu::initCommon() +{ + struct cpu_raw_data_t raw = { 0 }; + struct cpu_id_t data = { 0 }; + + cpuid_get_raw_data(&raw); + cpu_identify(&raw, &data); + + strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1); + + m_totalThreads = data.total_logical_cpus; + m_sockets = m_totalThreads / data.num_logical_cpus; + m_totalCores = data.num_cores *m_sockets; + + m_l3_cache = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; + + // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 + if (data.vendor == VENDOR_AMD && data.l3_cache <= 0 && data.l2_assoc == 16 && data.ext_family >= 21) { + m_l2_cache = data.l2_cache * (m_totalCores / 2) * m_sockets; + } + else { + m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0; + } + +# ifdef __x86_64__ + m_flags |= X86_64; +# endif + + if (data.flags[CPU_FEATURE_AES]) { + m_flags |= AES; + } + + if (data.flags[CPU_FEATURE_BMI2]) { + m_flags |= BMI2; + } +} diff --git a/src/Summary.cpp b/src/Summary.cpp index 4e047360..38f1b1c5 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -25,14 +25,13 @@ #include -#include "Summary.h" #include "Console.h" #include "Cpu.h" #include "Options.h" +#include "Summary.h" #include "version.h" - static void print_versions() { char *buf = static_cast(malloc(16)); From da02e9a3a2811fd74fa2ea2bdd8e606c02c3b1a3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 04:16:55 +0300 Subject: [PATCH 15/92] Reduce libcpuid size. --- src/3rdparty/libcpuid/cpuid_main.c | 438 ++---------------------- src/3rdparty/libcpuid/libcpuid.h | 473 -------------------------- src/3rdparty/libcpuid/libcpuid_util.c | 125 ------- src/3rdparty/libcpuid/libcpuid_util.h | 20 -- src/3rdparty/libcpuid/recog_amd.c | 361 -------------------- src/3rdparty/libcpuid/recog_amd.h | 1 - src/3rdparty/libcpuid/recog_intel.c | 376 -------------------- src/3rdparty/libcpuid/recog_intel.h | 1 - 8 files changed, 28 insertions(+), 1767 deletions(-) diff --git a/src/3rdparty/libcpuid/cpuid_main.c b/src/3rdparty/libcpuid/cpuid_main.c index 504c0af8..f22c7dd6 100644 --- a/src/3rdparty/libcpuid/cpuid_main.c +++ b/src/3rdparty/libcpuid/cpuid_main.c @@ -46,11 +46,6 @@ int set_error(cpu_error_t err) return (int) err; } -static void raw_data_t_constructor(struct cpu_raw_data_t* raw) -{ - memset(raw, 0, sizeof(struct cpu_raw_data_t)); -} - static void cpu_id_t_constructor(struct cpu_id_t* id) { memset(id, 0, sizeof(struct cpu_id_t)); @@ -60,29 +55,6 @@ static void cpu_id_t_constructor(struct cpu_id_t* id) id->sse_size = -1; } -static int parse_token(const char* expected_token, const char *token, - const char *value, uint32_t array[][4], int limit, int *recognized) -{ - char format[32]; - int veax, vebx, vecx, vedx; - int index; - - if (*recognized) return 1; /* already recognized */ - if (strncmp(token, expected_token, strlen(expected_token))) return 1; /* not what we search for */ - sprintf(format, "%s[%%d]", expected_token); - *recognized = 1; - if (1 == sscanf(token, format, &index) && index >=0 && index < limit) { - if (4 == sscanf(value, "%x%x%x%x", &veax, &vebx, &vecx, &vedx)) { - array[index][0] = veax; - array[index][1] = vebx; - array[index][2] = vecx; - array[index][3] = vedx; - return 1; - } - } - return 0; -} - /* get_total_cpus() system specific code: uses OS routines to determine total number of CPUs */ #ifdef __APPLE__ #include @@ -249,42 +221,42 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vendor_str) { - int i; - cpu_vendor_t vendor = VENDOR_UNKNOWN; - const struct { cpu_vendor_t vendor; char match[16]; } - matchtable[NUM_CPU_VENDORS] = { - /* source: http://www.sandpile.org/ia32/cpuid.htm */ - { VENDOR_INTEL , "GenuineIntel" }, - { VENDOR_AMD , "AuthenticAMD" }, - { VENDOR_CYRIX , "CyrixInstead" }, - { VENDOR_NEXGEN , "NexGenDriven" }, - { VENDOR_TRANSMETA , "GenuineTMx86" }, - { VENDOR_UMC , "UMC UMC UMC " }, - { VENDOR_CENTAUR , "CentaurHauls" }, - { VENDOR_RISE , "RiseRiseRise" }, - { VENDOR_SIS , "SiS SiS SiS " }, - { VENDOR_NSC , "Geode by NSC" }, - }; + int i; + cpu_vendor_t vendor = VENDOR_UNKNOWN; + const struct { cpu_vendor_t vendor; char match[16]; } + matchtable[NUM_CPU_VENDORS] = { + /* source: http://www.sandpile.org/ia32/cpuid.htm */ + { VENDOR_INTEL , "GenuineIntel" }, + { VENDOR_AMD , "AuthenticAMD" }, + { VENDOR_CYRIX , "CyrixInstead" }, + { VENDOR_NEXGEN , "NexGenDriven" }, + { VENDOR_TRANSMETA , "GenuineTMx86" }, + { VENDOR_UMC , "UMC UMC UMC " }, + { VENDOR_CENTAUR , "CentaurHauls" }, + { VENDOR_RISE , "RiseRiseRise" }, + { VENDOR_SIS , "SiS SiS SiS " }, + { VENDOR_NSC , "Geode by NSC" }, + }; - memcpy(vendor_str + 0, &raw_vendor[1], 4); - memcpy(vendor_str + 4, &raw_vendor[3], 4); - memcpy(vendor_str + 8, &raw_vendor[2], 4); - vendor_str[12] = 0; + memcpy(vendor_str + 0, &raw_vendor[1], 4); + memcpy(vendor_str + 4, &raw_vendor[3], 4); + memcpy(vendor_str + 8, &raw_vendor[2], 4); + vendor_str[12] = 0; - /* Determine vendor: */ - for (i = 0; i < NUM_CPU_VENDORS; i++) - if (!strcmp(vendor_str, matchtable[i].match)) { - vendor = matchtable[i].vendor; - break; - } - return vendor; + /* Determine vendor: */ + for (i = 0; i < NUM_CPU_VENDORS; i++) + if (!strcmp(vendor_str, matchtable[i].match)) { + vendor = matchtable[i].vendor; + break; + } + return vendor; } static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) { int i, j, basic, xmodel, xfamily, ext; char brandstr[64] = {0}; - data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str); + data->vendor = cpuid_vendor_identify(raw->basic_cpuid[0], data->vendor_str); if (data->vendor == VENDOR_UNKNOWN) return set_error(ERR_CPU_UNKN); @@ -320,27 +292,6 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat return set_error(ERR_OK); } -static void make_list_from_string(const char* csv, struct cpu_list_t* list) -{ - int i, n, l, last; - l = (int) strlen(csv); - n = 0; - for (i = 0; i < l; i++) if (csv[i] == ',') n++; - n++; - list->num_entries = n; - list->names = (char**) malloc(sizeof(char*) * n); - last = -1; - n = 0; - for (i = 0; i <= l; i++) if (i == l || csv[i] == ',') { - list->names[n] = (char*) malloc(i - last); - memcpy(list->names[n], &csv[last + 1], i - last - 1); - list->names[n][i - last - 1] = '\0'; - n++; - last = i; - } -} - - /* Interface: */ int cpuid_get_total_cpus(void) @@ -401,107 +352,6 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data) return set_error(ERR_OK); } -int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename) -{ - int i; - FILE *f; - - if (!strcmp(filename, "")) - f = stdout; - else - f = fopen(filename, "wt"); - if (!f) return set_error(ERR_OPEN); - - fprintf(f, "version=%s\n", VERSION); - for (i = 0; i < MAX_CPUID_LEVEL; i++) - fprintf(f, "basic_cpuid[%d]=%08x %08x %08x %08x\n", i, - data->basic_cpuid[i][0], data->basic_cpuid[i][1], - data->basic_cpuid[i][2], data->basic_cpuid[i][3]); - for (i = 0; i < MAX_EXT_CPUID_LEVEL; i++) - fprintf(f, "ext_cpuid[%d]=%08x %08x %08x %08x\n", i, - data->ext_cpuid[i][0], data->ext_cpuid[i][1], - data->ext_cpuid[i][2], data->ext_cpuid[i][3]); - for (i = 0; i < MAX_INTELFN4_LEVEL; i++) - fprintf(f, "intel_fn4[%d]=%08x %08x %08x %08x\n", i, - data->intel_fn4[i][0], data->intel_fn4[i][1], - data->intel_fn4[i][2], data->intel_fn4[i][3]); - for (i = 0; i < MAX_INTELFN11_LEVEL; i++) - fprintf(f, "intel_fn11[%d]=%08x %08x %08x %08x\n", i, - data->intel_fn11[i][0], data->intel_fn11[i][1], - data->intel_fn11[i][2], data->intel_fn11[i][3]); - for (i = 0; i < MAX_INTELFN12H_LEVEL; i++) - fprintf(f, "intel_fn12h[%d]=%08x %08x %08x %08x\n", i, - data->intel_fn12h[i][0], data->intel_fn12h[i][1], - data->intel_fn12h[i][2], data->intel_fn12h[i][3]); - for (i = 0; i < MAX_INTELFN14H_LEVEL; i++) - fprintf(f, "intel_fn14h[%d]=%08x %08x %08x %08x\n", i, - data->intel_fn14h[i][0], data->intel_fn14h[i][1], - data->intel_fn14h[i][2], data->intel_fn14h[i][3]); - - if (strcmp(filename, "")) - fclose(f); - return set_error(ERR_OK); -} - -int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename) -{ - int i, len; - char line[100]; - char token[100]; - char *value; - int syntax; - int cur_line = 0; - int recognized; - FILE *f; - - raw_data_t_constructor(data); - - if (!strcmp(filename, "")) - f = stdin; - else - f = fopen(filename, "rt"); - if (!f) return set_error(ERR_OPEN); - while (fgets(line, sizeof(line), f)) { - ++cur_line; - len = (int) strlen(line); - if (len < 2) continue; - if (line[len - 1] == '\n') - line[--len] = '\0'; - for (i = 0; i < len && line[i] != '='; i++) - if (i >= len && i < 1 && len - i - 1 <= 0) { - fclose(f); - return set_error(ERR_BADFMT); - } - strncpy(token, line, i); - token[i] = '\0'; - value = &line[i + 1]; - /* try to recognize the line */ - recognized = 0; - if (!strcmp(token, "version") || !strcmp(token, "build_date")) { - recognized = 1; - } - syntax = 1; - syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, MAX_CPUID_LEVEL, &recognized); - syntax = syntax && parse_token("ext_cpuid", token, value, data->ext_cpuid, MAX_EXT_CPUID_LEVEL, &recognized); - syntax = syntax && parse_token("intel_fn4", token, value, data->intel_fn4, MAX_INTELFN4_LEVEL, &recognized); - syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_LEVEL, &recognized); - syntax = syntax && parse_token("intel_fn12h", token, value, data->intel_fn12h, MAX_INTELFN12H_LEVEL, &recognized); - syntax = syntax && parse_token("intel_fn14h", token, value, data->intel_fn14h, MAX_INTELFN14H_LEVEL, &recognized); - if (!syntax) { - warnf("Error: %s:%d: Syntax error\n", filename, cur_line); - fclose(f); - return set_error(ERR_BADFMT); - } - if (!recognized) { - warnf("Warning: %s:%d not understood!\n", filename, cur_line); - } - } - - if (strcmp(filename, "")) - fclose(f); - return set_error(ERR_OK); -} - int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { int r; @@ -533,239 +383,7 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) return cpu_ident_internal(raw, data, &throwaway); } -const char* cpu_feature_str(cpu_feature_t feature) -{ - const struct { cpu_feature_t feature; const char* name; } - matchtable[] = { - { CPU_FEATURE_FPU, "fpu" }, - { CPU_FEATURE_VME, "vme" }, - { CPU_FEATURE_DE, "de" }, - { CPU_FEATURE_PSE, "pse" }, - { CPU_FEATURE_TSC, "tsc" }, - { CPU_FEATURE_MSR, "msr" }, - { CPU_FEATURE_PAE, "pae" }, - { CPU_FEATURE_MCE, "mce" }, - { CPU_FEATURE_CX8, "cx8" }, - { CPU_FEATURE_APIC, "apic" }, - { CPU_FEATURE_MTRR, "mtrr" }, - { CPU_FEATURE_SEP, "sep" }, - { CPU_FEATURE_PGE, "pge" }, - { CPU_FEATURE_MCA, "mca" }, - { CPU_FEATURE_CMOV, "cmov" }, - { CPU_FEATURE_PAT, "pat" }, - { CPU_FEATURE_PSE36, "pse36" }, - { CPU_FEATURE_PN, "pn" }, - { CPU_FEATURE_CLFLUSH, "clflush" }, - { CPU_FEATURE_DTS, "dts" }, - { CPU_FEATURE_ACPI, "acpi" }, - { CPU_FEATURE_MMX, "mmx" }, - { CPU_FEATURE_FXSR, "fxsr" }, - { CPU_FEATURE_SSE, "sse" }, - { CPU_FEATURE_SSE2, "sse2" }, - { CPU_FEATURE_SS, "ss" }, - { CPU_FEATURE_HT, "ht" }, - { CPU_FEATURE_TM, "tm" }, - { CPU_FEATURE_IA64, "ia64" }, - { CPU_FEATURE_PBE, "pbe" }, - { CPU_FEATURE_PNI, "pni" }, - { CPU_FEATURE_PCLMUL, "pclmul" }, - { CPU_FEATURE_DTS64, "dts64" }, - { CPU_FEATURE_MONITOR, "monitor" }, - { CPU_FEATURE_DS_CPL, "ds_cpl" }, - { CPU_FEATURE_VMX, "vmx" }, - { CPU_FEATURE_SMX, "smx" }, - { CPU_FEATURE_EST, "est" }, - { CPU_FEATURE_TM2, "tm2" }, - { CPU_FEATURE_SSSE3, "ssse3" }, - { CPU_FEATURE_CID, "cid" }, - { CPU_FEATURE_CX16, "cx16" }, - { CPU_FEATURE_XTPR, "xtpr" }, - { CPU_FEATURE_PDCM, "pdcm" }, - { CPU_FEATURE_DCA, "dca" }, - { CPU_FEATURE_SSE4_1, "sse4_1" }, - { CPU_FEATURE_SSE4_2, "sse4_2" }, - { CPU_FEATURE_SYSCALL, "syscall" }, - { CPU_FEATURE_XD, "xd" }, - { CPU_FEATURE_X2APIC, "x2apic"}, - { CPU_FEATURE_MOVBE, "movbe" }, - { CPU_FEATURE_POPCNT, "popcnt" }, - { CPU_FEATURE_AES, "aes" }, - { CPU_FEATURE_XSAVE, "xsave" }, - { CPU_FEATURE_OSXSAVE, "osxsave" }, - { CPU_FEATURE_AVX, "avx" }, - { CPU_FEATURE_MMXEXT, "mmxext" }, - { CPU_FEATURE_3DNOW, "3dnow" }, - { CPU_FEATURE_3DNOWEXT, "3dnowext" }, - { CPU_FEATURE_NX, "nx" }, - { CPU_FEATURE_FXSR_OPT, "fxsr_opt" }, - { CPU_FEATURE_RDTSCP, "rdtscp" }, - { CPU_FEATURE_LM, "lm" }, - { CPU_FEATURE_LAHF_LM, "lahf_lm" }, - { CPU_FEATURE_CMP_LEGACY, "cmp_legacy" }, - { CPU_FEATURE_SVM, "svm" }, - { CPU_FEATURE_SSE4A, "sse4a" }, - { CPU_FEATURE_MISALIGNSSE, "misalignsse" }, - { CPU_FEATURE_ABM, "abm" }, - { CPU_FEATURE_3DNOWPREFETCH, "3dnowprefetch" }, - { CPU_FEATURE_OSVW, "osvw" }, - { CPU_FEATURE_IBS, "ibs" }, - { CPU_FEATURE_SSE5, "sse5" }, - { CPU_FEATURE_SKINIT, "skinit" }, - { CPU_FEATURE_WDT, "wdt" }, - { CPU_FEATURE_TS, "ts" }, - { CPU_FEATURE_FID, "fid" }, - { CPU_FEATURE_VID, "vid" }, - { CPU_FEATURE_TTP, "ttp" }, - { CPU_FEATURE_TM_AMD, "tm_amd" }, - { CPU_FEATURE_STC, "stc" }, - { CPU_FEATURE_100MHZSTEPS, "100mhzsteps" }, - { CPU_FEATURE_HWPSTATE, "hwpstate" }, - { CPU_FEATURE_CONSTANT_TSC, "constant_tsc" }, - { CPU_FEATURE_XOP, "xop" }, - { CPU_FEATURE_FMA3, "fma3" }, - { CPU_FEATURE_FMA4, "fma4" }, - { CPU_FEATURE_TBM, "tbm" }, - { CPU_FEATURE_F16C, "f16c" }, - { CPU_FEATURE_RDRAND, "rdrand" }, - { CPU_FEATURE_CPB, "cpb" }, - { CPU_FEATURE_APERFMPERF, "aperfmperf" }, - { CPU_FEATURE_PFI, "pfi" }, - { CPU_FEATURE_PA, "pa" }, - { CPU_FEATURE_AVX2, "avx2" }, - { CPU_FEATURE_BMI1, "bmi1" }, - { CPU_FEATURE_BMI2, "bmi2" }, - { CPU_FEATURE_HLE, "hle" }, - { CPU_FEATURE_RTM, "rtm" }, - { CPU_FEATURE_AVX512F, "avx512f" }, - { CPU_FEATURE_AVX512DQ, "avx512dq" }, - { CPU_FEATURE_AVX512PF, "avx512pf" }, - { CPU_FEATURE_AVX512ER, "avx512er" }, - { CPU_FEATURE_AVX512CD, "avx512cd" }, - { CPU_FEATURE_SHA_NI, "sha_ni" }, - { CPU_FEATURE_AVX512BW, "avx512bw" }, - { CPU_FEATURE_AVX512VL, "avx512vl" }, - { CPU_FEATURE_SGX, "sgx" }, - { CPU_FEATURE_RDSEED, "rdseed" }, - { CPU_FEATURE_ADX, "adx" }, - }; - unsigned i, n = COUNT_OF(matchtable); - if (n != NUM_CPU_FEATURES) { - warnf("Warning: incomplete library, feature matchtable size differs from the actual number of features.\n"); - } - for (i = 0; i < n; i++) - if (matchtable[i].feature == feature) - return matchtable[i].name; - return ""; -} - -const char* cpuid_error(void) -{ - const struct { cpu_error_t error; const char *description; } - matchtable[] = { - { ERR_OK , "No error"}, - { ERR_NO_CPUID , "CPUID instruction is not supported"}, - { ERR_NO_RDTSC , "RDTSC instruction is not supported"}, - { ERR_NO_MEM , "Memory allocation failed"}, - { ERR_OPEN , "File open operation failed"}, - { ERR_BADFMT , "Bad file format"}, - { ERR_NOT_IMP , "Not implemented"}, - { ERR_CPU_UNKN , "Unsupported processor"}, - { ERR_NO_RDMSR , "RDMSR instruction is not supported"}, - { ERR_NO_DRIVER, "RDMSR driver error (generic)"}, - { ERR_NO_PERMS , "No permissions to install RDMSR driver"}, - { ERR_EXTRACT , "Cannot extract RDMSR driver (read only media?)"}, - { ERR_HANDLE , "Bad handle"}, - { ERR_INVMSR , "Invalid MSR"}, - { ERR_INVCNB , "Invalid core number"}, - { ERR_HANDLE_R , "Error on handle read"}, - { ERR_INVRANGE , "Invalid given range"}, - }; - unsigned i; - for (i = 0; i < COUNT_OF(matchtable); i++) - if (_libcpiud_errno == matchtable[i].error) - return matchtable[i].description; - return "Unknown error"; -} - - const char* cpuid_lib_version(void) { return VERSION; } - -libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t new_fn) -{ - libcpuid_warn_fn_t ret = _warn_fun; - _warn_fun = new_fn; - return ret; -} - -void cpuid_set_verbosiness_level(int level) -{ - _current_verboselevel = level; -} - -cpu_vendor_t cpuid_get_vendor(void) -{ - static cpu_vendor_t vendor = VENDOR_UNKNOWN; - uint32_t raw_vendor[4]; - char vendor_str[VENDOR_STR_MAX]; - - if(vendor == VENDOR_UNKNOWN) { - if (!cpuid_present()) - set_error(ERR_NO_CPUID); - else { - cpu_exec_cpuid(0, raw_vendor); - vendor = cpuid_vendor_identify(raw_vendor, vendor_str); - } - } - return vendor; -} - -void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list) -{ - switch (vendor) { - case VENDOR_INTEL: - cpuid_get_list_intel(list); - break; - case VENDOR_AMD: - cpuid_get_list_amd(list); - break; - case VENDOR_CYRIX: - make_list_from_string("Cx486,Cx5x86,6x86,6x86MX,M II,MediaGX,MediaGXi,MediaGXm", list); - break; - case VENDOR_NEXGEN: - make_list_from_string("Nx586", list); - break; - case VENDOR_TRANSMETA: - make_list_from_string("Crusoe,Efficeon", list); - break; - case VENDOR_UMC: - make_list_from_string("UMC x86 CPU", list); - break; - case VENDOR_CENTAUR: - make_list_from_string("VIA C3,VIA C7,VIA Nano", list); - break; - case VENDOR_RISE: - make_list_from_string("Rise mP6", list); - break; - case VENDOR_SIS: - make_list_from_string("SiS mP6", list); - break; - case VENDOR_NSC: - make_list_from_string("Geode GXm,Geode GXLV,Geode GX1,Geode GX2", list); - break; - default: - warnf("Unknown vendor passed to cpuid_get_cpu_list()\n"); - break; - } -} - -void cpuid_free_cpu_list(struct cpu_list_t* list) -{ - int i; - if (list->num_entries <= 0) return; - for (i = 0; i < list->num_entries; i++) - free(list->names[i]); - free(list->names); -} diff --git a/src/3rdparty/libcpuid/libcpuid.h b/src/3rdparty/libcpuid/libcpuid.h index f99c0fe5..c44990c3 100644 --- a/src/3rdparty/libcpuid/libcpuid.h +++ b/src/3rdparty/libcpuid/libcpuid.h @@ -610,39 +610,6 @@ void cpu_exec_cpuid_ext(uint32_t* regs); */ int cpuid_get_raw_data(struct cpu_raw_data_t* data); -/** - * @brief Writes the raw CPUID data to a text file - * @param data - a pointer to cpu_raw_data_t structure - * @param filename - the path of the file, where the serialized data should be - * written. If empty, stdout will be used. - * @note This is intended primarily for debugging. On some processor, which is - * not currently supported or not completely recognized by cpu_identify, - * one can still successfully get the raw data and write it to a file. - * libcpuid developers can later import this file and debug the detection - * code as if running on the actual hardware. - * The file is simple text format of "something=value" pairs. Version info - * is also written, but the format is not intended to be neither backward- - * nor forward compatible. - * @returns zero if successful, and some negative number on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t - */ -int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename); - -/** - * @brief Reads raw CPUID data from file - * @param data - a pointer to cpu_raw_data_t structure. The deserialized data will - * be written here. - * @param filename - the path of the file, containing the serialized raw data. - * If empty, stdin will be used. - * @note This function may fail, if the file is created by different version of - * the library. Also, see the notes on cpuid_serialize_raw_data. - * @returns zero if successful, and some negative number on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t -*/ -int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename); - /** * @brief Identifies the CPU * @param raw - Input - a pointer to the raw CPUID data, which is obtained @@ -668,222 +635,6 @@ int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename */ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data); -/** - * @brief Returns the short textual representation of a CPU flag - * @param feature - the feature, whose textual representation is wanted. - * @returns a constant string like "fpu", "tsc", "sse2", etc. - * @note the names of the returned flags are compatible with those from - * /proc/cpuinfo in Linux, with the exception of `tm_amd' - */ -const char* cpu_feature_str(cpu_feature_t feature); - -/** - * @brief Returns textual description of the last error - * - * libcpuid stores an `errno'-style error status, whose description - * can be obtained with this function. - * @note This function is not thread-safe - * @see cpu_error_t - */ -const char* cpuid_error(void); - -/** - * @brief Executes RDTSC - * - * The RDTSC (ReaD Time Stamp Counter) instruction gives access to an - * internal 64-bit counter, which usually increments at each clock cycle. - * This can be used for various timing routines, and as a very precise - * clock source. It is set to zero on system startup. Beware that may not - * increment at the same frequency as the CPU. Consecutive calls of RDTSC - * are, however, guaranteed to return monotonically-increasing values. - * - * @param result - a pointer to a 64-bit unsigned integer, where the TSC value - * will be stored - * - * @note If 100% compatibility is a concern, you must first check if the - * RDTSC instruction is present (if it is not, your program will crash - * with "invalid opcode" exception). Only some very old processors (i486, - * early AMD K5 and some Cyrix CPUs) lack that instruction - they should - * have become exceedingly rare these days. To verify RDTSC presence, - * run cpu_identify() and check flags[CPU_FEATURE_TSC]. - * - * @note The monotonically increasing nature of the TSC may be violated - * on SMP systems, if their TSC clocks run at different rate. If the OS - * doesn't account for that, the TSC drift may become arbitrary large. - */ -void cpu_rdtsc(uint64_t* result); - -/** - * @brief Store TSC and timing info - * - * This function stores the current TSC value and current - * time info from a precise OS-specific clock source in the cpu_mark_t - * structure. The sys_clock field contains time with microsecond resolution. - * The values can later be used to measure time intervals, number of clocks, - * FPU frequency, etc. - * @see cpu_rdtsc - * - * @param mark [out] - a pointer to a cpu_mark_t structure - */ -void cpu_tsc_mark(struct cpu_mark_t* mark); - -/** - * @brief Calculate TSC and timing difference - * - * @param mark - input/output: a pointer to a cpu_mark_t sturcture, which has - * already been initialized by cpu_tsc_mark. The difference in - * TSC and time will be written here. - * - * This function calculates the TSC and time difference, by obtaining the - * current TSC and timing values and subtracting the contents of the `mark' - * structure from them. Results are written in the same structure. - * - * Example: - * @code - * ... - * struct cpu_mark_t mark; - * cpu_tsc_mark(&mark); - * foo(); - * cpu_tsc_unmark(&mark); - * printf("Foo finished. Executed in %llu cycles and %llu usecs\n", - * mark.tsc, mark.sys_clock); - * ... - * @endcode - */ -void cpu_tsc_unmark(struct cpu_mark_t* mark); - -/** - * @brief Calculates the CPU clock - * - * @param mark - pointer to a cpu_mark_t structure, which has been initialized - * with cpu_tsc_mark and later `stopped' with cpu_tsc_unmark. - * - * @note For reliable results, the marked time interval should be at least about - * 10 ms. - * - * @returns the CPU clock frequency, in MHz. Due to measurement error, it will - * differ from the true value in a few least-significant bits. Accuracy depends - * on the timing interval - the more, the better. If the timing interval is - * insufficient, the result is -1. Also, see the comment on cpu_clock_measure - * for additional issues and pitfalls in using RDTSC for CPU frequency - * measurements. - */ -int cpu_clock_by_mark(struct cpu_mark_t* mark); - -/** - * @brief Returns the CPU clock, as reported by the OS - * - * This function uses OS-specific functions to obtain the CPU clock. It may - * differ from the true clock for several reasons:

- * - * i) The CPU might be in some power saving state, while the OS reports its - * full-power frequency, or vice-versa.
- * ii) In some cases you can raise or lower the CPU frequency with overclocking - * utilities and the OS will not notice. - * - * @returns the CPU clock frequency in MHz. If the OS is not (yet) supported - * or lacks the necessary reporting machinery, the return value is -1 - */ -int cpu_clock_by_os(void); - -/** - * @brief Measure the CPU clock frequency - * - * @param millis - How much time to waste in the busy-wait cycle. In millisecs. - * Useful values 10 - 1000 - * @param quad_check - Do a more thorough measurement if nonzero - * (see the explanation). - * - * The function performs a busy-wait cycle for the given time and calculates - * the CPU frequency by the difference of the TSC values. The accuracy of the - * calculation depends on the length of the busy-wait cycle: more is better, - * but 100ms should be enough for most purposes. - * - * While this will calculate the CPU frequency correctly in most cases, there are - * several reasons why it might be incorrect:
- * - * i) RDTSC doesn't guarantee it will run at the same clock as the CPU. - * Apparently there aren't CPUs at the moment, but still, there's no - * guarantee.
- * ii) The CPU might be in a low-frequency power saving mode, and the CPU - * might be switched to higher frequency at any time. If this happens - * during the measurement, the result can be anywhere between the - * low and high frequencies. Also, if you're interested in the - * high frequency value only, this function might return the low one - * instead.
- * iii) On SMP systems exhibiting TSC drift (see \ref cpu_rdtsc) - * - * the quad_check option will run four consecutive measurements and - * then return the average of the two most-consistent results. The total - * runtime of the function will still be `millis' - consider using - * a bit more time for the timing interval. - * - * Finally, for benchmarking / CPU intensive applications, the best strategy is - * to use the cpu_tsc_mark() / cpu_tsc_unmark() / cpu_clock_by_mark() method. - * Begin by mark()-ing about one second after application startup (allowing the - * power-saving manager to kick in and rise the frequency during that time), - * then unmark() just before application finishing. The result will most - * acurately represent at what frequency your app was running. - * - * @returns the CPU clock frequency in MHz (within some measurement error - * margin). If RDTSC is not supported, the result is -1. - */ -int cpu_clock_measure(int millis, int quad_check); - -/** - * @brief Measure the CPU clock frequency using instruction-counting - * - * @param millis - how much time to allocate for each run, in milliseconds - * @param runs - how many runs to perform - * - * The function performs a busy-wait cycle using a known number of "heavy" (SSE) - * instructions. These instructions run at (more or less guaranteed) 1 IPC rate, - * so by running a busy loop for a fixed amount of time, and measuring the - * amount of instructions done, the CPU clock is accurately measured. - * - * Of course, this function is still affected by the power-saving schemes, so - * the warnings as of cpu_clock_measure() still apply. However, this function is - * immune to problems with detection, related to the Intel Nehalem's "Turbo" - * mode, where the internal clock is raised, but the RDTSC rate is unaffected. - * - * The function will run for about (millis * runs) milliseconds. - * You can make only a single busy-wait run (runs == 1); however, this can - * be affected by task scheduling (which will break the counting), so allowing - * more than one run is recommended. As run length is not imperative for - * accurate readings (e.g., 50ms is sufficient), you can afford a lot of short - * runs, e.g. 10 runs of 50ms or 20 runs of 25ms. - * - * Recommended values - millis = 50, runs = 4. For more robustness, - * increase the number of runs. - * - * NOTE: on Bulldozer and later CPUs, the busy-wait cycle runs at 1.4 IPC, thus - * the results are skewed. This is corrected internally by dividing the resulting - * value by 1.4. - * However, this only occurs if the thread is executed on a single CMT - * module - if there are other threads competing for resources, the results are - * unpredictable. Make sure you run cpu_clock_by_ic() on a CPU that is free from - * competing threads, or if there are such threads, they shouldn't exceed the - * number of modules. On a Bulldozer X8, that means 4 threads. - * - * @returns the CPU clock frequency in MHz (within some measurement error - * margin). If SSE is not supported, the result is -1. If the input parameters - * are incorrect, or some other internal fault is detected, the result is -2. - */ -int cpu_clock_by_ic(int millis, int runs); - -/** - * @brief Get the CPU clock frequency (all-in-one method) - * - * This is an all-in-one method for getting the CPU clock frequency. - * It tries to use the OS for that. If the OS doesn't have this info, it - * uses cpu_clock_measure with 200ms time interval and quadruple checking. - * - * @returns the CPU clock frequency in MHz. If every possible method fails, - * the result is -1. - */ -int cpu_clock(void); - - /** * @brief The return value of cpuid_get_epc(). * @details @@ -916,230 +667,6 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw); */ const char* cpuid_lib_version(void); -typedef void (*libcpuid_warn_fn_t) (const char *msg); -/** - * @brief Sets the warning print function - * - * In some cases, the internal libcpuid machinery would like to emit useful - * debug warnings. By default, these warnings are written to stderr. However, - * you can set a custom function that will receive those warnings. - * - * @param warn_fun - the warning function you want to set. If NULL, warnings - * are disabled. The function takes const char* argument. - * - * @returns the current warning function. You can use the return value to - * keep the previous warning function and restore it at your discretion. - */ -libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t warn_fun); - -/** - * @brief Sets the verbosiness level - * - * When the verbosiness level is above zero, some functions might print - * diagnostic information about what are they doing. The higher the level is, - * the more detail is printed. Level zero is guaranteed to omit all such - * output. The output is written using the same machinery as the warnings, - * @see cpuid_set_warn_function() - * - * @param level the desired verbosiness level. Useful values 0..2 inclusive - */ -void cpuid_set_verbosiness_level(int level); - - -/** - * @brief Obtains the CPU vendor from CPUID from the current CPU - * @note The result is cached. - * @returns VENDOR_UNKNOWN if failed, otherwise the CPU vendor type. - * @see cpu_vendor_t - */ -cpu_vendor_t cpuid_get_vendor(void); - -/** - * @brief a structure that holds a list of processor names - */ -struct cpu_list_t { - /** Number of entries in the list */ - int num_entries; - /** Pointers to names. There will be num_entries of them */ - char **names; -}; - -/** - * @brief Gets a list of all known CPU names from a specific vendor. - * - * This function compiles a list of all known CPU (code)names - * (i.e. the possible values of cpu_id_t::cpu_codename) for the given vendor. - * - * There are about 100 entries for Intel and AMD, and a few for the other - * vendors. The list is written out in approximate chronological introduction - * order of the parts. - * - * @param vendor the vendor to be queried - * @param list [out] the resulting list will be written here. - * NOTE: As the memory is dynamically allocated, be sure to call - * cpuid_free_cpu_list() after you're done with the data - * @see cpu_list_t - */ -void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list); - -/** - * @brief Frees a CPU list - * - * This function deletes all the memory associated with a CPU list, as obtained - * by cpuid_get_cpu_list() - * - * @param list - the list to be free()'d. - */ -void cpuid_free_cpu_list(struct cpu_list_t* list); - -struct msr_driver_t; -/** - * @brief Starts/opens a driver, needed to read MSRs (Model Specific Registers) - * - * On systems that support it, this function will create a temporary - * system driver, that has privileges to execute the RDMSR instruction. - * After the driver is created, you can read MSRs by calling \ref cpu_rdmsr - * - * @returns a handle to the driver on success, and NULL on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t - */ -struct msr_driver_t* cpu_msr_driver_open(void); - -/** - * @brief Similar to \ref cpu_msr_driver_open, but accept one parameter - * - * This function works on certain operating systems (GNU/Linux, FreeBSD) - * - * @param core_num specify the core number for MSR. - * The first core number is 0. - * The last core number is \ref cpuid_get_total_cpus - 1. - * - * @returns a handle to the driver on success, and NULL on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t - */ -struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num); - -/** - * @brief Reads a Model-Specific Register (MSR) - * - * If the CPU has MSRs (as indicated by the CPU_FEATURE_MSR flag), you can - * read a MSR with the given index by calling this function. - * - * There are several prerequisites you must do before reading MSRs: - * 1) You must ensure the CPU has RDMSR. Check the CPU_FEATURE_MSR flag - * in cpu_id_t::flags - * 2) You must ensure that the CPU implements the specific MSR you intend to - * read. - * 3) You must open a MSR-reader driver. RDMSR is a privileged instruction and - * needs ring-0 access in order to work. This temporary driver is created - * by calling \ref cpu_msr_driver_open - * - * @param handle - a handle to the MSR reader driver, as created by - * cpu_msr_driver_open - * @param msr_index - the numeric ID of the MSR you want to read - * @param result - a pointer to a 64-bit integer, where the MSR value is stored - * - * @returns zero if successful, and some negative number on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t - */ -int cpu_rdmsr(struct msr_driver_t* handle, uint32_t msr_index, uint64_t* result); - - -typedef enum { - INFO_MPERF, /*!< Maximum performance frequency clock. This - is a counter, which increments as a - proportion of the actual processor speed. */ - INFO_APERF, /*!< Actual performance frequency clock. This - accumulates the core clock counts when the - core is active. */ - INFO_MIN_MULTIPLIER, /*!< Minimum CPU:FSB ratio for this CPU, - multiplied by 100. */ - INFO_CUR_MULTIPLIER, /*!< Current CPU:FSB ratio, multiplied by 100. - e.g., a CPU:FSB value of 18.5 reads as - "1850". */ - INFO_MAX_MULTIPLIER, /*!< Maximum CPU:FSB ratio for this CPU, - multiplied by 100. */ - INFO_TEMPERATURE, /*!< The current core temperature in Celsius. */ - INFO_THROTTLING, /*!< 1 if the current logical processor is - throttling. 0 if it is running normally. */ - INFO_VOLTAGE, /*!< The current core voltage in Volt, - multiplied by 100. */ - INFO_BCLK, /*!< See \ref INFO_BUS_CLOCK. */ - INFO_BUS_CLOCK, /*!< The main bus clock in MHz, - e.g., FSB/QPI/DMI/HT base clock, - multiplied by 100. */ -} cpu_msrinfo_request_t; - -/** - * @brief Similar to \ref cpu_rdmsr, but extract a range of bits - * - * @param handle - a handle to the MSR reader driver, as created by - * cpu_msr_driver_open - * @param msr_index - the numeric ID of the MSR you want to read - * @param highbit - the high bit in range, must be inferior to 64 - * @param lowbit - the low bit in range, must be equal or superior to 0 - * @param result - a pointer to a 64-bit integer, where the MSR value is stored - * - * @returns zero if successful, and some negative number on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t - */ -int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit, - uint8_t lowbit, uint64_t* result); - -/** - * @brief Reads extended CPU information from Model-Specific Registers. - * @param handle - a handle to an open MSR driver, @see cpu_msr_driver_open - * @param which - which info field should be returned. A list of - * available information entities is listed in the - * cpu_msrinfo_request_t enum. - * @retval - if the requested information is available for the current - * processor model, the respective value is returned. - * if no information is available, or the CPU doesn't support - * the query, the special value CPU_INVALID_VALUE is returned - * @note This function is not MT-safe. If you intend to call it from multiple - * threads, guard it through a mutex or a similar primitive. - */ -int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which); -#define CPU_INVALID_VALUE 0x3fffffff - -/** - * @brief Writes the raw MSR data to a text file - * @param data - a pointer to msr_driver_t structure - * @param filename - the path of the file, where the serialized data should be - * written. If empty, stdout will be used. - * @note This is intended primarily for debugging. On some processor, which is - * not currently supported or not completely recognized by cpu_identify, - * one can still successfully get the raw data and write it to a file. - * libcpuid developers can later import this file and debug the detection - * code as if running on the actual hardware. - * The file is simple text format of "something=value" pairs. Version info - * is also written, but the format is not intended to be neither backward- - * nor forward compatible. - * @returns zero if successful, and some negative number on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t - */ -int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename); - -/** - * @brief Closes an open MSR driver - * - * This function unloads the MSR driver opened by cpu_msr_driver_open and - * frees any resources associated with it. - * - * @param handle - a handle to the MSR reader driver, as created by - * cpu_msr_driver_open - * - * @returns zero if successful, and some negative number on error. - * The error message can be obtained by calling \ref cpuid_error. - * @see cpu_error_t - */ -int cpu_msr_driver_close(struct msr_driver_t* handle); - #ifdef __cplusplus }; /* extern "C" */ #endif diff --git a/src/3rdparty/libcpuid/libcpuid_util.c b/src/3rdparty/libcpuid/libcpuid_util.c index 4de1871a..440b3724 100644 --- a/src/3rdparty/libcpuid/libcpuid_util.c +++ b/src/3rdparty/libcpuid/libcpuid_util.c @@ -32,8 +32,6 @@ #include "libcpuid.h" #include "libcpuid_util.h" -int _current_verboselevel; - void match_features(const struct feature_map_t* matchtable, int count, uint32_t reg, struct cpu_id_t* data) { int i; @@ -42,118 +40,6 @@ void match_features(const struct feature_map_t* matchtable, int count, uint32_t data->flags[matchtable[i].feature] = 1; } -static void default_warn(const char *msg) -{ - fprintf(stderr, "%s", msg); -} - -libcpuid_warn_fn_t _warn_fun = default_warn; - -#if defined(_MSC_VER) -# define vsnprintf _vsnprintf -#endif -void warnf(const char* format, ...) -{ - char buff[1024]; - va_list va; - if (!_warn_fun) return; - va_start(va, format); - vsnprintf(buff, sizeof(buff), format, va); - va_end(va); - _warn_fun(buff); -} - -void debugf(int verboselevel, const char* format, ...) -{ - char buff[1024]; - va_list va; - if (verboselevel > _current_verboselevel) return; - va_start(va, format); - vsnprintf(buff, sizeof(buff), format, va); - va_end(va); - _warn_fun(buff); -} - -static int popcount64(uint64_t mask) -{ - int num_set_bits = 0; - - while (mask) { - mask &= mask - 1; - num_set_bits++; - } - - return num_set_bits; -} - -static int score(const struct match_entry_t* entry, const struct cpu_id_t* data, - int brand_code, uint64_t bits, int model_code) -{ - int res = 0; - if (entry->family == data->family ) res += 2; - if (entry->model == data->model ) res += 2; - if (entry->stepping == data->stepping ) res += 2; - if (entry->ext_family == data->ext_family) res += 2; - if (entry->ext_model == data->ext_model ) res += 2; - if (entry->ncores == data->num_cores ) res += 2; - if (entry->l2cache == data->l2_cache ) res += 1; - if (entry->l3cache == data->l3_cache ) res += 1; - if (entry->brand_code == brand_code ) res += 2; - if (entry->model_code == model_code ) res += 2; - - res += popcount64(entry->model_bits & bits) * 2; - return res; -} - -int match_cpu_codename(const struct match_entry_t* matchtable, int count, - struct cpu_id_t* data, int brand_code, uint64_t bits, - int model_code) -{ - int bestscore = -1; - int bestindex = 0; - int i, t; - - debugf(3, "Matching cpu f:%d, m:%d, s:%d, xf:%d, xm:%d, ncore:%d, l2:%d, bcode:%d, bits:%llu, code:%d\n", - data->family, data->model, data->stepping, data->ext_family, - data->ext_model, data->num_cores, data->l2_cache, brand_code, (unsigned long long) bits, model_code); - - for (i = 0; i < count; i++) { - t = score(&matchtable[i], data, brand_code, bits, model_code); - debugf(3, "Entry %d, `%s', score %d\n", i, matchtable[i].name, t); - if (t > bestscore) { - debugf(2, "Entry `%s' selected - best score so far (%d)\n", matchtable[i].name, t); - bestscore = t; - bestindex = i; - } - } - strcpy(data->cpu_codename, matchtable[bestindex].name); - return bestscore; -} - -void generic_get_cpu_list(const struct match_entry_t* matchtable, int count, - struct cpu_list_t* list) -{ - int i, j, n, good; - n = 0; - list->names = (char**) malloc(sizeof(char*) * count); - for (i = 0; i < count; i++) { - if (strstr(matchtable[i].name, "Unknown")) continue; - good = 1; - for (j = n - 1; j >= 0; j--) - if (!strcmp(list->names[j], matchtable[i].name)) { - good = 0; - break; - } - if (!good) continue; -#if defined(_MSC_VER) - list->names[n++] = _strdup(matchtable[i].name); -#else - list->names[n++] = strdup(matchtable[i].name); -#endif - } - list->num_entries = n; -} - static int xmatch_entry(char c, const char* p) { int i, j; @@ -205,14 +91,3 @@ int match_all(uint64_t bits, uint64_t mask) { return (bits & mask) == mask; } - -void debug_print_lbits(int debuglevel, uint64_t mask) -{ - int i, first = 0; - for (i = 0; i < 64; i++) if (mask & (((uint64_t) 1) << i)) { - if (first) first = 0; - else debugf(2, " + "); - debugf(2, "LBIT(%d)", i); - } - debugf(2, "\n"); -} diff --git a/src/3rdparty/libcpuid/libcpuid_util.h b/src/3rdparty/libcpuid/libcpuid_util.h index c3b53933..0c8200e8 100644 --- a/src/3rdparty/libcpuid/libcpuid_util.h +++ b/src/3rdparty/libcpuid/libcpuid_util.h @@ -48,20 +48,6 @@ struct match_entry_t { int match_cpu_codename(const struct match_entry_t* matchtable, int count, struct cpu_id_t* data, int brand_code, uint64_t bits, int model_code); - -void warnf(const char* format, ...) -#ifdef __GNUC__ -__attribute__((format(printf, 1, 2))) -#endif -; -void debugf(int verboselevel, const char* format, ...) -#ifdef __GNUC__ -__attribute__((format(printf, 2, 3))) -#endif -; -void generic_get_cpu_list(const struct match_entry_t* matchtable, int count, - struct cpu_list_t* list); - /* * Seek for a pattern in `haystack'. * Pattern may be an fixed string, or contain the special metacharacters @@ -84,15 +70,9 @@ struct cpu_id_t* get_cached_cpuid(void); /* returns true if all bits of mask are present in `bits'. */ int match_all(uint64_t bits, uint64_t mask); -/* print what bits a mask consists of */ -void debug_print_lbits(int debuglevel, uint64_t mask); - /* * Sets the current errno */ int set_error(cpu_error_t err); -extern libcpuid_warn_fn_t _warn_fun; -extern int _current_verboselevel; - #endif /* __LIBCPUID_UTIL_H__ */ diff --git a/src/3rdparty/libcpuid/recog_amd.c b/src/3rdparty/libcpuid/recog_amd.c index 3867aa8c..352d733b 100644 --- a/src/3rdparty/libcpuid/recog_amd.c +++ b/src/3rdparty/libcpuid/recog_amd.c @@ -51,237 +51,6 @@ enum _amd_model_codes_t { _1600, }; - -const struct match_entry_t cpudb_amd[] = { - { -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD CPU" }, - - /* 486 and the likes */ - { 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 486" }, - { 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2" }, - { 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2WB" }, - { 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4" }, - { 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4WB" }, - - /* Pentia clones */ - { 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 586" }, - { 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" }, - { 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" }, - { 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" }, - { 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" }, - - /* The K6 */ - { 5, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" }, - { 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" }, - - { 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2" }, - { 5, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-III" }, - { 5, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" }, - { 5, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" }, - { 5, 12, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" }, - { 5, 13, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2+" }, - - /* Athlon et al. */ - { 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" }, - { 6, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" }, - { 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Duron (Spitfire)" }, - { 6, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (ThunderBird)" }, - - { 6, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon" }, - { 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon (Palomino)" }, - { 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_MP_ , 0, "Athlon MP (Palomino)" }, - { 6, 6, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Palomino)" }, - { 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP" }, - - { 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon XP" }, - { 6, 7, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Morgan)" }, - - { 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon XP (Thoroughbred)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP (Thoroughbred)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Applebred)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" }, - { 6, 8, -1, -1, -1, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" }, - { 6, 8, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_MP_ , 0, "Athlon MP (Thoroughbred)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_ , 0, "Mobile Athlon (T-Bred)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_|_LV_, 0, "Mobile Athlon (T-Bred)" }, - - { 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP (Barton)" }, - { 6, 10, -1, -1, -1, 1, 512, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP (Barton)" }, - { 6, 10, -1, -1, -1, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron (Barton)" }, - { 6, 10, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thorton)" }, - { 6, 10, -1, -1, -1, 1, 256, -1, NC, ATHLON_|_XP_ , 0, "Athlon XP (Thorton)" }, - { 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_MP_ , 0, "Athlon MP (Barton)" }, - { 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_ , 0, "Mobile Athlon (Barton)" }, - { 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_|_XP_|_M_|_LV_, 0, "Mobile Athlon (Barton)" }, - - /* K8 Architecture */ - { 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown K8" }, - { 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Unknown K9" }, - - { 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown A64" }, - { 15, -1, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" }, - { 15, -1, -1, 15, -1, 2, -1, -1, NC, OPTERON_|_X2 , 0, "Opteron (Dual Core)" }, - { 15, 3, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" }, - { 15, 3, -1, 15, -1, 2, -1, -1, NC, OPTERON_|_X2 , 0, "Opteron (Dual Core)" }, - { 15, -1, -1, 15, -1, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (512K)" }, - { 15, -1, -1, 15, -1, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (1024K)" }, - { 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_|_FX , 0, "Athlon FX" }, - { 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_|_64_|_FX , 0, "Athlon 64 FX" }, - { 15, 3, -1, 15, 35, 2, -1, -1, NC, ATHLON_|_64_|_FX , 0, "Athlon 64 FX X2 (Toledo)" }, - { 15, -1, -1, 15, -1, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (512K)" }, - { 15, -1, -1, 15, -1, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (1024K)" }, - { 15, -1, -1, 15, -1, 1, 512, -1, NC, TURION_|_64_ , 0, "Turion 64 (512K)" }, - { 15, -1, -1, 15, -1, 1, 1024, -1, NC, TURION_|_64_ , 0, "Turion 64 (1024K)" }, - { 15, -1, -1, 15, -1, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion 64 X2 (512K)" }, - { 15, -1, -1, 15, -1, 2, 1024, -1, NC, TURION_|_X2 , 0, "Turion 64 X2 (1024K)" }, - { 15, -1, -1, 15, -1, 1, 128, -1, NC, SEMPRON_ , 0, "A64 Sempron (128K)" }, - { 15, -1, -1, 15, -1, 1, 256, -1, NC, SEMPRON_ , 0, "A64 Sempron (256K)" }, - { 15, -1, -1, 15, -1, 1, 512, -1, NC, SEMPRON_ , 0, "A64 Sempron (512K)" }, - { 15, -1, -1, 15, 0x4f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Orleans/512K)" }, - { 15, -1, -1, 15, 0x5f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Orleans/512K)" }, - { 15, -1, -1, 15, 0x2f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Venice/512K)" }, - { 15, -1, -1, 15, 0x2c, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Venice/512K)" }, - { 15, -1, -1, 15, 0x1f, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Winchester/512K)" }, - { 15, -1, -1, 15, 0x0c, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Newcastle/512K)" }, - { 15, -1, -1, 15, 0x27, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (San Diego/512K)" }, - { 15, -1, -1, 15, 0x37, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (San Diego/512K)" }, - { 15, -1, -1, 15, 0x04, 1, 512, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (ClawHammer/512K)" }, - - { 15, -1, -1, 15, 0x5f, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (Orleans/1024K)" }, - { 15, -1, -1, 15, 0x27, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (San Diego/1024K)" }, - { 15, -1, -1, 15, 0x04, 1, 1024, -1, NC, ATHLON_|_64_ , 0, "Athlon 64 (ClawHammer/1024K)" }, - - { 15, -1, -1, 15, 0x4b, 2, 256, -1, NC, SEMPRON_ , 0, "Athlon 64 X2 (Windsor/256K)" }, - - { 15, -1, -1, 15, 0x23, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Toledo/512K)" }, - { 15, -1, -1, 15, 0x4b, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Windsor/512K)" }, - { 15, -1, -1, 15, 0x43, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Windsor/512K)" }, - { 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Brisbane/512K)" }, - { 15, -1, -1, 15, 0x2b, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Manchester/512K)"}, - - { 15, -1, -1, 15, 0x23, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Toledo/1024K)" }, - { 15, -1, -1, 15, 0x43, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon 64 X2 (Windsor/1024K)" }, - - { 15, -1, -1, 15, 0x08, 1, 128, -1, NC, MOBILE_|SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/128K)"}, - { 15, -1, -1, 15, 0x08, 1, 256, -1, NC, MOBILE_|SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/256K)"}, - { 15, -1, -1, 15, 0x0c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Paris)" }, - { 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" }, - { 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" }, - { 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/128K)"}, - { 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/256K)"}, - { 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" }, - { 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" }, - { 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Albany/128K)"}, - { 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Albany/256K)"}, - { 15, -1, -1, 15, 0x2f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" }, - { 15, -1, -1, 15, 0x2f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" }, - { 15, -1, -1, 15, 0x4f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" }, - { 15, -1, -1, 15, 0x4f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" }, - { 15, -1, -1, 15, 0x5f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" }, - { 15, -1, -1, 15, 0x5f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" }, - { 15, -1, -1, 15, 0x6b, 2, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/256K)"}, - { 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/512K)"}, - { 15, -1, -1, 15, 0x7f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/256K)" }, - { 15, -1, -1, 15, 0x7f, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/512K)" }, - { 15, -1, -1, 15, 0x4c, 1, 256, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Keene/256K)"}, - { 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, MOBILE_| SEMPRON_ , 0, "Mobile Sempron 64 (Keene/512K)"}, - { 15, -1, -1, 15, -1, 2, -1, -1, NC, SEMPRON_ , 0, "Sempron Dual Core" }, - - { 15, -1, -1, 15, 0x24, 1, 512, -1, NC, TURION_|_64_ , 0, "Turion 64 (Lancaster/512K)" }, - { 15, -1, -1, 15, 0x24, 1, 1024, -1, NC, TURION_|_64_ , 0, "Turion 64 (Lancaster/1024K)" }, - { 15, -1, -1, 15, 0x48, 2, 256, -1, NC, TURION_|_X2 , 0, "Turion X2 (Taylor)" }, - { 15, -1, -1, 15, 0x48, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion X2 (Trinidad)" }, - { 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, TURION_|_64_ , 0, "Turion 64 (Richmond)" }, - { 15, -1, -1, 15, 0x68, 2, 256, -1, NC, TURION_|_X2 , 0, "Turion X2 (Tyler/256K)" }, - { 15, -1, -1, 15, 0x68, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion X2 (Tyler/512K)" }, - { 15, -1, -1, 17, 3, 2, 512, -1, NC, TURION_|_X2 , 0, "Turion X2 (Griffin/512K)" }, - { 15, -1, -1, 17, 3, 2, 1024, -1, NC, TURION_|_X2 , 0, "Turion X2 (Griffin/1024K)" }, - - /* K10 Architecture (2007) */ - { 15, -1, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Unknown AMD Phenom" }, - { 15, 2, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Phenom" }, - { 15, 2, -1, 16, -1, 3, -1, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman)" }, - { 15, 2, -1, 16, -1, 4, -1, -1, PHENOM, 0 , 0, "Phenom X4 (Agena)" }, - { 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/256K)" }, - { 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/512K)" }, - { 15, 2, -1, 16, -1, 4, 128, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/128K)" }, - { 15, 2, -1, 16, -1, 4, 256, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/256K)" }, - { 15, 2, -1, 16, -1, 4, 512, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/512K)" }, - { 15, 2, -1, 16, -1, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon X2 (Kuma)" }, - /* Phenom II derivates: */ - { 15, 4, -1, 16, -1, 4, -1, -1, NC, 0 , 0, "Phenom (Deneb-based)" }, - { 15, 4, -1, 16, -1, 1, 1024, -1, NC, SEMPRON_ , 0, "Sempron (Sargas)" }, - { 15, 4, -1, 16, -1, 2, 512, -1, PHENOM2, 0 , 0, "Phenom II X2 (Callisto)" }, - { 15, 4, -1, 16, -1, 3, 512, -1, PHENOM2, 0 , 0, "Phenom II X3 (Heka)" }, - { 15, 4, -1, 16, -1, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4" }, - { 15, 4, -1, 16, 4, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" }, - { 15, 5, -1, 16, 5, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" }, - { 15, 4, -1, 16, 10, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Zosma)" }, - { 15, 4, -1, 16, 10, 6, 512, -1, PHENOM2, 0 , 0, "Phenom II X6 (Thuban)" }, - /* Athlon II derivates: */ - { 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_|_X2 , 0, "Athlon II (Champlain)" }, - { 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon II X2 (Regor)" }, - { 15, 6, -1, 16, 6, 2, 1024, -1, NC, ATHLON_|_64_|_X2 , 0, "Athlon II X2 (Regor)" }, - { 15, 5, -1, 16, 5, 3, 512, -1, NC, ATHLON_|_64_|_X3 , 0, "Athlon II X3 (Rana)" }, - { 15, 5, -1, 16, 5, 4, 512, -1, NC, ATHLON_|_64_|_X4 , 0, "Athlon II X4 (Propus)" }, - /* Llano APUs (2011): */ - { 15, 1, -1, 18, 1, 2, -1, -1, FUSION_EA, 0 , 0, "Llano X2" }, - { 15, 1, -1, 18, 1, 3, -1, -1, FUSION_EA, 0 , 0, "Llano X3" }, - { 15, 1, -1, 18, 1, 4, -1, -1, FUSION_EA, 0 , 0, "Llano X4" }, - - /* Family 14h: Bobcat Architecture (2011) */ - { 15, 2, -1, 20, -1, 1, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario" }, - { 15, 2, -1, 20, -1, 2, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario (Dual-core)" }, - { 15, 1, -1, 20, -1, 1, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate" }, - { 15, 1, -1, 20, -1, 2, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate (Dual-core)" }, - { 15, 2, -1, 20, -1, 2, -1, -1, FUSION_Z, 0 , 0, "Brazos Desna (Dual-core)" }, - - /* Family 15h: Bulldozer Architecture (2011) */ - { 15, -1, -1, 21, 0, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" }, - { 15, -1, -1, 21, 1, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" }, - { 15, -1, -1, 21, 1, 6, -1, -1, NC, 0 , 0, "Bulldozer X3" }, - { 15, -1, -1, 21, 1, 8, -1, -1, NC, 0 , 0, "Bulldozer X4" }, - /* 2nd-gen, Piledriver core (2012): */ - { 15, -1, -1, 21, 2, 4, -1, -1, NC, 0 , 0, "Vishera X2" }, - { 15, -1, -1, 21, 2, 6, -1, -1, NC, 0 , 0, "Vishera X3" }, - { 15, -1, -1, 21, 2, 8, -1, -1, NC, 0 , 0, "Vishera X4" }, - { 15, 0, -1, 21, 16, 2, -1, -1, FUSION_A, 0 , 0, "Trinity X2" }, - { 15, 0, -1, 21, 16, 4, -1, -1, FUSION_A, 0 , 0, "Trinity X4" }, - { 15, 3, -1, 21, 19, 2, -1, -1, FUSION_A, 0 , 0, "Richland X2" }, - { 15, 3, -1, 21, 19, 4, -1, -1, FUSION_A, 0 , 0, "Richland X4" }, - /* 3rd-gen, Steamroller core (2014): */ - { 15, 0, -1, 21, 48, 2, -1, -1, FUSION_A, 0 , 0, "Kaveri X2" }, - { 15, 0, -1, 21, 48, 4, -1, -1, FUSION_A, 0 , 0, "Kaveri X4" }, - { 15, 8, -1, 21, 56, 4, -1, -1, FUSION_A, 0 , 0, "Godavari X4" }, - /* 4th-gen, Excavator core (2015): */ - { 15, 1, -1, 21, 96, 2, -1, -1, FUSION_A, 0 , 0, "Carrizo X2" }, - { 15, 1, -1, 21, 96, 4, -1, -1, FUSION_A, 0 , 0, "Carrizo X4" }, - { 15, 5, -1, 21, 101, 2, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X2" }, - { 15, 5, -1, 21, 101, 4, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X4" }, - { 15, 0, -1, 21, 112, 2, -1, -1, FUSION_A, 0 , 0, "Stoney Ridge X2" }, - { 15, 0, -1, 21, 112, 2, -1, -1, FUSION_E, 0 , 0, "Stoney Ridge X2" }, - - /* Family 16h: Jaguar Architecture (2013) */ - { 15, 0, -1, 22, 0, 2, -1, -1, FUSION_A, 0 , 0, "Kabini X2" }, - { 15, 0, -1, 22, 0, 4, -1, -1, FUSION_A, 0 , 0, "Kabini X4" }, - /* 2nd-gen, Puma core (2013): */ - { 15, 0, -1, 22, 48, 2, -1, -1, FUSION_E, 0 , 0, "Mullins X2" }, - { 15, 0, -1, 22, 48, 4, -1, -1, FUSION_A, 0 , 0, "Mullins X4" }, - - /* Family 17h: Zen Architecture (2017) */ - { 15, -1, -1, 23, 1, 8, -1, -1, NC, 0 , 0, "Ryzen 7" }, - { 15, -1, -1, 23, 1, 6, -1, -1, NC, 0 , _1600, "Ryzen 5" }, - { 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1500, "Ryzen 5" }, - { 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1400, "Ryzen 5" }, - { 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Ryzen 3" }, - //{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Raven Ridge" }, //TBA - - /* Newer Opterons: */ - { 15, 9, -1, 22, 9, 8, -1, -1, NC, OPTERON_ , 0, "Magny-Cours Opteron" }, -}; - - static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) { const struct feature_map_t matchtable_edx81[] = { @@ -391,140 +160,10 @@ static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id } } -static int amd_has_turion_modelname(const char *bs) -{ - /* We search for something like TL-60. Ahh, I miss regexes...*/ - int i, l, k; - char code[3] = {0}; - const char* codes[] = { "ML", "MT", "MK", "TK", "TL", "RM", "ZM", "" }; - l = (int) strlen(bs); - for (i = 3; i < l - 2; i++) { - if (bs[i] == '-' && - isupper(bs[i-1]) && isupper(bs[i-2]) && !isupper(bs[i-3]) && - isdigit(bs[i+1]) && isdigit(bs[i+2]) && !isdigit(bs[i+3])) - { - code[0] = bs[i-2]; - code[1] = bs[i-1]; - for (k = 0; codes[k][0]; k++) - if (!strcmp(codes[k], code)) return 1; - } - } - return 0; -} - -static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) -{ - amd_code_t code = NC; - uint64_t bits = 0; - struct amd_code_and_bits_t result; - - if (strstr(bs, "Dual Core") || - strstr(bs, "Dual-Core") || - strstr(bs, " X2 ")) - bits |= _X2; - if (strstr(bs, " X4 ")) bits |= _X4; - if (strstr(bs, " X3 ")) bits |= _X3; - if (strstr(bs, "Opteron")) bits |= OPTERON_; - if (strstr(bs, "Phenom")) { - code = (strstr(bs, "II")) ? PHENOM2 : PHENOM; - } - if (amd_has_turion_modelname(bs)) { - bits |= TURION_; - } - if (strstr(bs, "Athlon(tm)")) bits |= ATHLON_; - if (strstr(bs, "Sempron(tm)")) bits |= SEMPRON_; - if (strstr(bs, "Duron")) bits |= DURON_; - if (strstr(bs, " 64 ")) bits |= _64_; - if (strstr(bs, " FX")) bits |= _FX; - if (strstr(bs, " MP")) bits |= _MP_; - if (strstr(bs, "Athlon(tm) 64") || strstr(bs, "Athlon(tm) II X") || match_pattern(bs, "Athlon(tm) X#")) { - bits |= ATHLON_ | _64_; - } - if (strstr(bs, "Turion")) bits |= TURION_; - - if (strstr(bs, "mobile") || strstr(bs, "Mobile")) { - bits |= MOBILE_; - } - - if (strstr(bs, "XP")) bits |= _XP_; - if (strstr(bs, "XP-M")) bits |= _M_; - if (strstr(bs, "(LV)")) bits |= _LV_; - if (strstr(bs, " APU ")) bits |= _APU_; - - if (match_pattern(bs, "C-##")) code = FUSION_C; - if (match_pattern(bs, "E-###")) code = FUSION_E; - if (match_pattern(bs, "Z-##")) code = FUSION_Z; - if (match_pattern(bs, "[EA]#-####")) code = FUSION_EA; - - result.code = code; - result.bits = bits; - return result; -} - -static int decode_amd_ryzen_model_code(const char* bs) -{ - const struct { - int model_code; - const char* match_str; - } patterns[] = { - { _1600, "1600" }, - { _1500, "1500" }, - { _1400, "1400" }, - }; - int i; - - for (i = 0; i < COUNT_OF(patterns); i++) - if (strstr(bs, patterns[i].match_str)) - return patterns[i].model_code; - // - return 0; -} - -static void decode_amd_codename(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) -{ - struct amd_code_and_bits_t code_and_bits = decode_amd_codename_part1(data->brand_str); - int i = 0; - char* code_str = NULL; - int model_code; - - for (i = 0; i < COUNT_OF(amd_code_str); i++) { - if (code_and_bits.code == amd_code_str[i].code) { - code_str = amd_code_str[i].str; - break; - } - } - if (/*code == ATHLON_64_X2*/ match_all(code_and_bits.bits, ATHLON_|_64_|_X2) && data->l2_cache < 512) { - code_and_bits.bits &= ~(ATHLON_ | _64_); - code_and_bits.bits |= SEMPRON_; - } - if (code_str) - debugf(2, "Detected AMD brand code: %d (%s)\n", code_and_bits.code, code_str); - else - debugf(2, "Detected AMD brand code: %d\n", code_and_bits.code); - - if (code_and_bits.bits) { - debugf(2, "Detected AMD bits: "); - debug_print_lbits(2, code_and_bits.bits); - } - // is it Ryzen? if so, we need to detect discern between the four-core 1400/1500 (Ryzen 5) and the four-core Ryzen 3: - model_code = (data->ext_family == 23) ? decode_amd_ryzen_model_code(data->brand_str) : 0; - - internal->code.amd = code_and_bits.code; - internal->bits = code_and_bits.bits; - internal->score = match_cpu_codename(cpudb_amd, COUNT_OF(cpudb_amd), data, code_and_bits.code, - code_and_bits.bits, model_code); -} - int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { load_amd_features(raw, data); decode_amd_cache_info(raw, data); decode_amd_number_of_cores(raw, data); - decode_amd_codename(raw, data, internal); return 0; } - -void cpuid_get_list_amd(struct cpu_list_t* list) -{ - generic_get_cpu_list(cpudb_amd, COUNT_OF(cpudb_amd), list); -} diff --git a/src/3rdparty/libcpuid/recog_amd.h b/src/3rdparty/libcpuid/recog_amd.h index 34e89598..19f839ba 100644 --- a/src/3rdparty/libcpuid/recog_amd.h +++ b/src/3rdparty/libcpuid/recog_amd.h @@ -27,6 +27,5 @@ #define __RECOG_AMD_H__ int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal); -void cpuid_get_list_amd(struct cpu_list_t* list); #endif /* __RECOG_AMD_H__ */ diff --git a/src/3rdparty/libcpuid/recog_intel.c b/src/3rdparty/libcpuid/recog_intel.c index 5e6c03b0..5467c19f 100644 --- a/src/3rdparty/libcpuid/recog_intel.c +++ b/src/3rdparty/libcpuid/recog_intel.c @@ -59,291 +59,6 @@ enum _intel_model_t { }; typedef enum _intel_model_t intel_model_t; -const struct match_entry_t cpudb_intel[] = { - { -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Intel CPU" }, - - /* i486 */ - { 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown i486" }, - { 4, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-25/33" }, - { 4, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-50" }, - { 4, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX" }, - { 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2" }, - { 4, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SL" }, - { 4, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX2" }, - { 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2 WriteBack" }, - { 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4" }, - { 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4 WriteBack" }, - - /* All Pentia: - Pentium 1 */ - { 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium" }, - { 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium A-Step" }, - { 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.8u)" }, - { 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" }, - { 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium OverDrive" }, - { 5, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" }, - { 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" }, - { 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium MMX (0.25u)" }, - - /* Pentium 2 / 3 / M / Conroe / whatsnext - all P6 based. */ - { 6, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown P6" }, - { 6, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" }, - { 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" }, - { 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Klamath)" }, - { 6, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Deschutes)" }, - { 6, 5, -1, -1, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile Pentium II (Tonga)"}, - { 6, 6, -1, -1, -1, 1, -1, -1, NC,0 , 0, "Pentium II (Dixon)" }, - - { 6, 3, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Klamath)" }, - { 6, 5, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Drake)" }, - { 6, 6, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Dixon)" }, - - { 6, 5, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Covington)" }, - { 6, 6, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Mendocino)" }, - - /* -------------------------------------------------- */ - - { 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Katmai)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"}, - { 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"}, - { 6, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Tualatin)" }, - - { 6, 7, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tanner)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" }, - { 6, 10, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" }, - { 6, 11, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tualatin)" }, - - { 6, 7, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Katmai)" }, - { 6, 8, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" }, - { 6, 10, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" }, - { 6, 11, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Tualatin)" }, - - /* Netburst based (Pentium 4 and later) - classic P4s */ - { 15, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium 4" }, - { 15, -1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "Unknown P-4 Celeron" }, - { 15, -1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Unknown Xeon" }, - - { 15, 0, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" }, - { 15, 1, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" }, - { 15, 2, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Northwood)" }, - { 15, 3, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" }, - { 15, 6, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Cedar Mill)" }, - { 15, 0, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Willamette)" }, - { 15, 1, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Willamette)" }, - { 15, 2, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Northwood)" }, - { 15, 3, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Prescott)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Prescott)" }, - { 15, 6, -1, 15, -1, 1, -1, -1, NC, MOBILE_|PENTIUM_, 0, "Mobile P-4 (Cedar Mill)" }, - - /* server CPUs */ - { 15, 0, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" }, - { 15, 1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" }, - { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Prestonia)" }, - { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Gallatin)" }, - { 15, 3, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, IRWIN, XEON_ , 0, "Xeon (Irwindale)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Cranford)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, POTOMAC, XEON_ , 0, "Xeon (Potomac)" }, - { 15, 6, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Dempsey)" }, - - /* Pentium Ds */ - { 15, 4, 4, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (SmithField)" }, - { 15, 4, 7, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" }, - { 15, 6, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (Presler)" }, - - /* Celeron and Celeron Ds */ - { 15, 1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Willamette)" }, - { 15, 2, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Northwood)" }, - { 15, 3, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" }, - { 15, 6, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Cedar Mill)" }, - - /* -------------------------------------------------- */ - /* Intel Core microarchitecture - P6-based */ - - { 6, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium M" }, - { 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Unknown Pentium M" }, - { 6, 9, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Banias)" }, - { 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Banias)" }, - { 6, 9, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" }, - { 6, 13, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Dothan)" }, - { 6, 13, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Dothan)" }, - { 6, 13, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" }, - - { 6, 12, -1, -1, -1, -1, -1, -1, NC, ATOM_ , 0, "Unknown Atom" }, - { 6, 12, -1, -1, -1, -1, -1, -1, DIAMONDVILLE,ATOM_, 0, "Atom (Diamondville)" }, - { 6, 12, -1, -1, -1, -1, -1, -1, SILVERTHORNE,ATOM_, 0, "Atom (Silverthorne)" }, - { 6, 12, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" }, - { 6, 6, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" }, - { 6, 12, -1, -1, -1, -1, -1, -1, PINEVIEW, ATOM_ , 0, "Atom (Pineview)" }, - - /* -------------------------------------------------- */ - - { 6, 14, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Yonah" }, - { 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" }, - { 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO, 0 , 0, "Yonah (Core Duo)" }, - { 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, MOBILE_, 0, "Yonah (Core Solo)" }, - { 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO , MOBILE_, 0, "Yonah (Core Duo)" }, - { 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" }, - - { 6, 15, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Core 2" }, - { 6, 15, -1, -1, -1, 2, 4096, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo)" }, - { 6, 15, -1, -1, -1, 2, 1024, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 1024K" }, - { 6, 15, -1, -1, -1, 2, 512, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 512K" }, - { 6, 15, -1, -1, -1, 4, -1, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" }, - { 6, 15, -1, -1, -1, 4, 4096, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" }, - { 6, 15, -1, -1, -1, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" }, - { 6, 15, -1, -1, -1, 2, 2048, -1, CORE_DUO, 0 , 0, "Allendale (Core 2 Duo)" }, - { 6, 15, -1, -1, -1, 2, -1, -1, MOBILE_CORE_DUO, 0, 0, "Merom (Core 2 Duo)" }, - { 6, 15, -1, -1, -1, 2, 2048, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 2048K" }, - { 6, 15, -1, -1, -1, 2, 4096, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 4096K" }, - - { 6, 15, -1, -1, 15, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" }, - { 6, 6, -1, -1, 22, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" }, - { 6, 15, -1, -1, 15, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" }, - { 6, 6, -1, -1, 22, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" }, - - - { 6, 6, -1, -1, 22, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" }, - { 6, 7, -1, -1, 23, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" }, - { 6, 6, -1, -1, 22, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" }, - { 6, 7, -1, -1, 23, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" }, - - { 6, 7, -1, -1, 23, 1, -1, -1, CORE_SOLO , 0, 0, "Unknown Core 45nm" }, - { 6, 7, -1, -1, 23, 1, -1, -1, CORE_DUO , 0, 0, "Unknown Core 45nm" }, - { 6, 7, -1, -1, 23, 2, 1024, -1, WOLFDALE , 0, 0, "Celeron Wolfdale 1M" }, - { 6, 7, -1, -1, 23, 2, 2048, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 2M" }, - { 6, 7, -1, -1, 23, 2, 3072, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 3M" }, - { 6, 7, -1, -1, 23, 2, 6144, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 6M" }, - { 6, 7, -1, -1, 23, 1, -1, -1, MOBILE_CORE_DUO , 0, 0, "Penryn (Core 2 Duo)" }, - { 6, 7, -1, -1, 23, 2, 1024, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo)" }, - { 6, 7, -1, -1, 23, 2, 3072, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 3M" }, - { 6, 7, -1, -1, 23, 2, 6144, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 6M" }, - { 6, 7, -1, -1, 23, 4, 2048, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 2M"}, - { 6, 7, -1, -1, 23, 4, 3072, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 3M"}, - { 6, 7, -1, -1, 23, 4, 6144, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 6M"}, - - /* Core microarchitecture-based Xeons: */ - { 6, 14, -1, -1, 14, 1, -1, -1, NC, XEON_ , 0, "Xeon LV" }, - { 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _5100, "Xeon (Woodcrest)" }, - { 6, 15, -1, -1, 15, 2, 2048, -1, NC, XEON_ , _3000, "Xeon (Conroe/2M)" }, - { 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _3000, "Xeon (Conroe/4M)" }, - { 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , X3200, "Xeon (Kentsfield)" }, - { 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , _5300, "Xeon (Clovertown)" }, - { 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _3100, "Xeon (Wolfdale)" }, - { 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _5200, "Xeon (Wolfdale DP)" }, - { 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , _5400, "Xeon (Harpertown)" }, - { 6, 7, -1, -1, 23, 4, 3072, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/3M)" }, - { 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/6M)" }, - - /* Nehalem CPUs (45nm): */ - { 6, 10, -1, -1, 26, 4, -1, -1, GAINESTOWN, XEON_ , 0, "Gainestown (Xeon)" }, - { 6, 10, -1, -1, 26, 4, -1, 4096, GAINESTOWN, XEON_ , 0, "Gainestown 4M (Xeon)" }, - { 6, 10, -1, -1, 26, 4, -1, 8192, GAINESTOWN, XEON_ , 0, "Gainestown 8M (Xeon)" }, - { 6, 10, -1, -1, 26, 4, -1, -1, NC, XEON_|_7 , 0, "Bloomfield (Xeon)" }, - { 6, 10, -1, -1, 26, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Bloomfield (Core i7)" }, - { 6, 10, -1, -1, 30, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Lynnfield (Core i7)" }, - { 6, 5, -1, -1, 37, 4, -1, 8192, NC, CORE_|_I_|_5 , 0, "Lynnfield (Core i5)" }, - - /* Westmere CPUs (32nm): */ - { 6, 5, -1, -1, 37, 2, -1, -1, NC, 0 , 0, "Unknown Core i3/i5" }, - { 6, 12, -1, -1, 44, -1, -1, -1, WESTMERE, XEON_ , 0, "Westmere (Xeon)" }, - { 6, 12, -1, -1, 44, -1, -1, 12288, WESTMERE, XEON_ , 0, "Gulftown (Xeon)" }, - { 6, 12, -1, -1, 44, 4, -1, 12288, NC, CORE_|_I_|_7 , 0, "Gulftown (Core i7)" }, - { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_5 , 0, "Clarkdale (Core i5)" }, - { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_3 , 0, "Clarkdale (Core i3)" }, - { 6, 5, -1, -1, 37, 2, -1, -1, NC, PENTIUM_ , 0, "Arrandale" }, - { 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_|_I_|_7 , 0, "Arrandale (Core i7)" }, - { 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_|_I_|_5 , 0, "Arrandale (Core i5)" }, - { 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_|_I_|_3 , 0, "Arrandale (Core i3)" }, - - /* Sandy Bridge CPUs (32nm): */ - { 6, 10, -1, -1, 42, -1, -1, -1, NC, 0 , 0, "Unknown Sandy Bridge" }, - { 6, 10, -1, -1, 42, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge (Xeon)" }, - { 6, 10, -1, -1, 42, -1, -1, -1, NC, CORE_|_I_|_7 , 0, "Sandy Bridge (Core i7)" }, - { 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Sandy Bridge (Core i7)" }, - { 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Sandy Bridge (Core i5)" }, - { 6, 10, -1, -1, 42, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Sandy Bridge (Core i3)" }, - { 6, 10, -1, -1, 42, 2, -1, -1, NC, PENTIUM_ , 0, "Sandy Bridge (Pentium)" }, - { 6, 10, -1, -1, 42, 1, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" }, - { 6, 10, -1, -1, 42, 2, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" }, - { 6, 13, -1, -1, 45, -1, -1, -1, NC, CORE_|_I_|_3 , 0, "Sandy Bridge-E" }, - { 6, 13, -1, -1, 45, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge-E (Xeon)" }, - - /* Ivy Bridge CPUs (22nm): */ - { 6, 10, -1, -1, 58, -1, -1, -1, NC, XEON_ , 0, "Ivy Bridge (Xeon)" }, - { 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Ivy Bridge (Core i7)" }, - { 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Ivy Bridge (Core i5)" }, - { 6, 10, -1, -1, 58, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Ivy Bridge (Core i3)" }, - { 6, 10, -1, -1, 58, 2, -1, -1, NC, PENTIUM_ , 0, "Ivy Bridge (Pentium)" }, - { 6, 10, -1, -1, 58, 1, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" }, - { 6, 10, -1, -1, 58, 2, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" }, - { 6, 14, -1, -1, 62, -1, -1, -1, NC, 0 , 0, "Ivy Bridge-E" }, - - /* Haswell CPUs (22nm): */ - { 6, 12, -1, -1, 60, -1, -1, -1, NC, XEON_ , 0, "Haswell (Xeon)" }, - { 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Haswell (Core i7)" }, - { 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Haswell (Core i7)" }, - { 6, 6, -1, -1, 70, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Haswell (Core i7)" }, - { 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" }, - { 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" }, - { 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" }, - { 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Haswell (Core i5)" }, - { 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Haswell (Core i3)" }, - { 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Haswell (Core i3)" }, - { 6, 12, -1, -1, 60, 2, -1, -1, NC, PENTIUM_ , 0, "Haswell (Pentium)" }, - { 6, 12, -1, -1, 60, 2, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" }, - { 6, 12, -1, -1, 60, 1, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" }, - { 6, 15, -1, -1, 63, -1, -1, -1, NC, 0 , 0, "Haswell-E" }, - - /* Broadwell CPUs (14nm): */ - { 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell (Core i7)" }, - { 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell (Core i5)" }, - { 6, 13, -1, -1, 61, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-U (Core i7)" }, - { 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-U (Core i7)" }, - { 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell-U (Core i5)" }, - { 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Broadwell-U (Core i3)" }, - { 6, 13, -1, -1, 61, 2, -1, -1, NC, PENTIUM_ , 0, "Broadwell-U (Pentium)" }, - { 6, 13, -1, -1, 61, 2, -1, -1, NC, CELERON_ , 0, "Broadwell-U (Celeron)" }, - { 6, 13, -1, -1, 61, 2, -1, -1, NA, 0 , 0, "Broadwell-U (Core M)" }, - { 6, 15, -1, -1, 79, -1, -1, -1, NC, XEON_ , 0, "Broadwell-E (Xeon)" }, - { 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Broadwell-E (Core i3)" }, - { 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell-E (Core i5)" }, - { 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Broadwell-E (Core i5)" }, - { 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-E (Core i7)" }, - { 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Broadwell-E (Core i7)" }, - - /* Skylake CPUs (14nm): */ - { 6, 14, -1, -1, 94, -1, -1, -1, NC, XEON_ , 0, "Skylake (Xeon)" }, - { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Skylake (Core i7)" }, - { 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Skylake (Core i5)" }, - { 6, 14, -1, -1, 94, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Skylake (Core i3)" }, - { 6, 14, -1, -1, 94, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" }, - { 6, 14, -1, -1, 94, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_7 , 0, "Skylake (Core m7)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_5 , 0, "Skylake (Core m5)" }, - { 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_|_M_|_3 , 0, "Skylake (Core m3)" }, - - /* Kaby Lake CPUs (14nm): */ - { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_7 , 0, "Kaby Lake (Core i7)" }, - { 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_|_I_|_5 , 0, "Kaby Lake (Core i5)" }, - { 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_|_I_|_3 , 0, "Kaby Lake (Core i3)" }, - { 6, 14, -1, -1, 158, 2, -1, -1, NC, PENTIUM_ , 0, "Kaby Lake (Pentium)" }, - { 6, 14, -1, -1, 158, 2, -1, -1, NC, CELERON_ , 0, "Kaby Lake (Celeron)" }, - { 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_|_M_|_3 , 0, "Kaby Lake (Core m3)" }, - - /* Itaniums */ - { 7, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Itanium" }, - { 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Itanium 2" }, -}; - - static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) { const struct feature_map_t matchtable_edx1[] = { @@ -558,8 +273,6 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw, else if (level == 4 && typenumber == 3) type = L4; else { - warnf("deterministic_cache: unknown level/typenumber combo (%d/%d), cannot\n", level, typenumber); - warnf("deterministic_cache: recognize cache type\n"); continue; } ways = ((raw->intel_fn4[ecx][1] >> 22) & 0x3ff) + 1; @@ -681,7 +394,6 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) code = matchtable[i].c; break; } - debugf(2, "intel matchtable result is %d\n", code); if (bits & XEON_) { if (match_pattern(bs, "W35##") || match_pattern(bs, "[ELXW]75##")) bits |= _7; @@ -743,65 +455,6 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) return result; } -static intel_model_t get_model_code(struct cpu_id_t* data) -{ - int i = 0; - int l = (int) strlen(data->brand_str); - const char *bs = data->brand_str; - int mod_flags = 0, model_no = 0, ndigs = 0; - /* If the CPU is a Core ix, then just return the model number generation: */ - if ((i = match_pattern(bs, "Core(TM) i[357]")) != 0) { - i += 11; - if (i + 4 >= l) return UNKNOWN; - if (bs[i] == '2') return _2xxx; - if (bs[i] == '3') return _3xxx; - return UNKNOWN; - } - - /* For Core2-based Xeons: */ - while (i < l - 3) { - if (bs[i] == 'C' && bs[i+1] == 'P' && bs[i+2] == 'U') - break; - i++; - } - if (i >= l - 3) return UNKNOWN; - i += 3; - while (i < l - 4 && bs[i] == ' ') i++; - if (i >= l - 4) return UNKNOWN; - while (i < l - 4 && !isdigit(bs[i])) { - if (bs[i] >= 'A' && bs[i] <= 'Z') - mod_flags |= (1 << (bs[i] - 'A')); - i++; - } - if (i >= l - 4) return UNKNOWN; - while (isdigit(bs[i])) { - ndigs++; - model_no = model_no * 10 + (int) (bs[i] - '0'); - i++; - } - if (ndigs != 4) return UNKNOWN; -#define HAVE(ch, flags) ((flags & (1 << ((int)(ch-'A')))) != 0) - switch (model_no / 100) { - case 30: return _3000; - case 31: return _3100; - case 32: - { - return (HAVE('X', mod_flags)) ? X3200 : _3200; - } - case 33: - { - return (HAVE('X', mod_flags)) ? X3300 : _3300; - } - case 51: return _5100; - case 52: return _5200; - case 53: return _5300; - case 54: return _5400; - default: - return UNKNOWN; - } -#undef HAVE -} - static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct cpu_id_t* data) { struct cpu_epc_t epc; @@ -828,13 +481,11 @@ static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct c for (i = 0; i < 1000000; i++) { epc = cpuid_get_epc(i, raw); if (epc.length == 0) { - debugf(2, "SGX: epc section request for %d returned null, no more EPC sections.\n", i); data->sgx.num_epc_sections = i; break; } } if (data->sgx.num_epc_sections == -1) { - debugf(1, "SGX: warning: seems to be infinitude of EPC sections.\n"); data->sgx.num_epc_sections = 1000000; } } @@ -867,9 +518,6 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw) int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { intel_code_and_bits_t brand; - intel_model_t model_code; - int i; - char* brand_code_str = NULL; load_intel_features(raw, data); if (raw->basic_cpuid[0][0] >= 4) { @@ -881,38 +529,14 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, stru decode_intel_number_of_cores(raw, data); brand = get_brand_code_and_bits(data); - model_code = get_model_code(data); - for (i = 0; i < COUNT_OF(intel_bcode_str); i++) { - if (brand.code == intel_bcode_str[i].code) { - brand_code_str = intel_bcode_str[i].str; - break; - } - } - if (brand_code_str) - debugf(2, "Detected Intel brand code: %d (%s)\n", brand.code, brand_code_str); - else - debugf(2, "Detected Intel brand code: %d\n", brand.code); - if (brand.bits) { - debugf(2, "Detected Intel bits: "); - debug_print_lbits(2, brand.bits); - } - debugf(2, "Detected Intel model code: %d\n", model_code); internal->code.intel = brand.code; internal->bits = brand.bits; if (data->flags[CPU_FEATURE_SGX]) { - debugf(2, "SGX seems to be present, decoding...\n"); // if SGX is indicated by the CPU, verify its presence: decode_intel_sgx_features(raw, data); } - internal->score = match_cpu_codename(cpudb_intel, COUNT_OF(cpudb_intel), data, - brand.code, brand.bits, model_code); return 0; } - -void cpuid_get_list_intel(struct cpu_list_t* list) -{ - generic_get_cpu_list(cpudb_intel, COUNT_OF(cpudb_intel), list); -} diff --git a/src/3rdparty/libcpuid/recog_intel.h b/src/3rdparty/libcpuid/recog_intel.h index b99c783b..96676f3b 100644 --- a/src/3rdparty/libcpuid/recog_intel.h +++ b/src/3rdparty/libcpuid/recog_intel.h @@ -27,6 +27,5 @@ #define __RECOG_INTEL_H__ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal); -void cpuid_get_list_intel(struct cpu_list_t* list); #endif /*__RECOG_INTEL_H__*/ From 5a606be8be6ea566569b7efe7e04b831954438ec Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 04:20:10 +0300 Subject: [PATCH 16/92] Move crypto/* --- CMakeLists.txt | 25 ++++++++++++++++++++++++- {crypto => src/crypto}/c_blake256.c | 0 {crypto => src/crypto}/c_blake256.h | 0 {crypto => src/crypto}/c_groestl.c | 0 {crypto => src/crypto}/c_groestl.h | 0 {crypto => src/crypto}/c_jh.c | 0 {crypto => src/crypto}/c_jh.h | 0 {crypto => src/crypto}/c_keccak.c | 0 {crypto => src/crypto}/c_keccak.h | 0 {crypto => src/crypto}/c_skein.c | 0 {crypto => src/crypto}/c_skein.h | 0 {crypto => src/crypto}/groestl_tables.h | 0 {crypto => src/crypto}/hash.h | 0 {crypto => src/crypto}/skein_port.h | 0 {crypto => src/crypto}/soft_aes.c | 0 15 files changed, 24 insertions(+), 1 deletion(-) rename {crypto => src/crypto}/c_blake256.c (100%) rename {crypto => src/crypto}/c_blake256.h (100%) rename {crypto => src/crypto}/c_groestl.c (100%) rename {crypto => src/crypto}/c_groestl.h (100%) rename {crypto => src/crypto}/c_jh.c (100%) rename {crypto => src/crypto}/c_jh.h (100%) rename {crypto => src/crypto}/c_keccak.c (100%) rename {crypto => src/crypto}/c_keccak.h (100%) rename {crypto => src/crypto}/c_skein.c (100%) rename {crypto => src/crypto}/c_skein.h (100%) rename {crypto => src/crypto}/groestl_tables.h (100%) rename {crypto => src/crypto}/hash.h (100%) rename {crypto => src/crypto}/skein_port.h (100%) rename {crypto => src/crypto}/soft_aes.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11a6d1bc..936cc9bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,17 @@ set(HEADERS src/version.h ) +set(HEADERS_CRYPTO + src/crypto/c_blake256.h + src/crypto/c_groestl.h + src/crypto/c_jh.h + src/crypto/c_keccak.h + src/crypto/c_skein.h + src/crypto/groestl_tables.h + src/crypto/hash.h + src/crypto/skein_port.h + ) + set(SOURCES src/App.cpp src/net/Client.cpp @@ -30,6 +41,15 @@ set(SOURCES src/xmrig.cpp ) +set(SOURCES_CRYPTO + src/crypto/c_keccak.c + src/crypto/c_groestl.c + src/crypto/c_blake256.c + src/crypto/c_jh.c + src/crypto/c_skein.c + src/crypto/soft_aes.c + ) + if (WIN32) set(SOURCES_OS res/app.rc @@ -57,6 +77,9 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") @@ -85,5 +108,5 @@ include_directories(${UV_INCLUDE_DIR}) add_subdirectory(src/3rdparty/jansson) -add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID}) +add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO}) target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB}) diff --git a/crypto/c_blake256.c b/src/crypto/c_blake256.c similarity index 100% rename from crypto/c_blake256.c rename to src/crypto/c_blake256.c diff --git a/crypto/c_blake256.h b/src/crypto/c_blake256.h similarity index 100% rename from crypto/c_blake256.h rename to src/crypto/c_blake256.h diff --git a/crypto/c_groestl.c b/src/crypto/c_groestl.c similarity index 100% rename from crypto/c_groestl.c rename to src/crypto/c_groestl.c diff --git a/crypto/c_groestl.h b/src/crypto/c_groestl.h similarity index 100% rename from crypto/c_groestl.h rename to src/crypto/c_groestl.h diff --git a/crypto/c_jh.c b/src/crypto/c_jh.c similarity index 100% rename from crypto/c_jh.c rename to src/crypto/c_jh.c diff --git a/crypto/c_jh.h b/src/crypto/c_jh.h similarity index 100% rename from crypto/c_jh.h rename to src/crypto/c_jh.h diff --git a/crypto/c_keccak.c b/src/crypto/c_keccak.c similarity index 100% rename from crypto/c_keccak.c rename to src/crypto/c_keccak.c diff --git a/crypto/c_keccak.h b/src/crypto/c_keccak.h similarity index 100% rename from crypto/c_keccak.h rename to src/crypto/c_keccak.h diff --git a/crypto/c_skein.c b/src/crypto/c_skein.c similarity index 100% rename from crypto/c_skein.c rename to src/crypto/c_skein.c diff --git a/crypto/c_skein.h b/src/crypto/c_skein.h similarity index 100% rename from crypto/c_skein.h rename to src/crypto/c_skein.h diff --git a/crypto/groestl_tables.h b/src/crypto/groestl_tables.h similarity index 100% rename from crypto/groestl_tables.h rename to src/crypto/groestl_tables.h diff --git a/crypto/hash.h b/src/crypto/hash.h similarity index 100% rename from crypto/hash.h rename to src/crypto/hash.h diff --git a/crypto/skein_port.h b/src/crypto/skein_port.h similarity index 100% rename from crypto/skein_port.h rename to src/crypto/skein_port.h diff --git a/crypto/soft_aes.c b/src/crypto/soft_aes.c similarity index 100% rename from crypto/soft_aes.c rename to src/crypto/soft_aes.c From 878e021ff66fe2a8c30a9f0a65da08e476279384 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 09:47:25 +0300 Subject: [PATCH 17/92] Initial CryptoNight. --- CMakeLists.txt | 4 + src/App.cpp | 6 + src/Options.cpp | 6 + src/Options.h | 5 + src/crypto/CryptoNight.cpp | 105 +++++++++++ src/crypto/CryptoNight.h | 45 +++++ src/crypto/CryptoNight_p.h | 349 +++++++++++++++++++++++++++++++++++++ 7 files changed, 520 insertions(+) create mode 100644 src/crypto/CryptoNight.cpp create mode 100644 src/crypto/CryptoNight.h create mode 100644 src/crypto/CryptoNight_p.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 936cc9bd..0d993dda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,8 @@ set(HEADERS_CRYPTO src/crypto/c_jh.h src/crypto/c_keccak.h src/crypto/c_skein.h + src/crypto/CryptoNight.h + src/crypto/CryptoNight_p.h src/crypto/groestl_tables.h src/crypto/hash.h src/crypto/skein_port.h @@ -48,6 +50,8 @@ set(SOURCES_CRYPTO src/crypto/c_jh.c src/crypto/c_skein.c src/crypto/soft_aes.c + src/crypto/soft_aes.c + src/crypto/CryptoNight.cpp ) if (WIN32) diff --git a/src/App.cpp b/src/App.cpp index e7cf1aa4..6608554c 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -28,6 +28,7 @@ #include "App.h" #include "Console.h" #include "Cpu.h" +#include "crypto/CryptoNight.h" #include "net/Client.h" #include "net/Network.h" #include "Options.h" @@ -61,6 +62,11 @@ App::exec() return 0; } + if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) { + LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName()); + return 1; + } + Summary::print(); m_network->connect(); diff --git a/src/Options.cpp b/src/Options.cpp index c09de032..1fbdb141 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -116,6 +116,12 @@ Options *Options::parse(int argc, char **argv) } +const char *Options::algoName() const +{ + return algo_names[m_algo]; +} + + Options::Options(int argc, char **argv) : m_background(false), m_colors(true), diff --git a/src/Options.h b/src/Options.h index 0c1dcc6e..cbad99fa 100644 --- a/src/Options.h +++ b/src/Options.h @@ -52,16 +52,21 @@ public: static Options *parse(int argc, char **argv); inline bool colors() const { return m_colors; } + inline bool doubleHash() const { return m_doubleHash; } inline bool isReady() const { return m_ready; } inline bool keepAlive() const { return m_keepAlive; } inline const char *pass() const { return m_pass; } inline const char *user() const { return m_user; } inline const Url *backupUrl() const { return m_backupUrl; } inline const Url *url() const { return m_url; } + inline int algo() const { return m_algo; } + inline int algoVariant() const { return m_algoVariant; } inline int donateLevel() const { return m_donateLevel; } inline int retries() const { return m_retries; } inline int retryPause() const { return m_retryPause; } + const char *algoName() const; + private: Options(int argc, char **argv); ~Options(); diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp new file mode 100644 index 00000000..a96ac761 --- /dev/null +++ b/src/crypto/CryptoNight.cpp @@ -0,0 +1,105 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/CryptoNight.h" +#include "crypto/CryptoNight_p.h" +#include "Options.h" + + +const static uint8_t test_input[152] = { + 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, + 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, + 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, + 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, + 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, + 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, + 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, + 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, + 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, + 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01 +}; + + +const static uint8_t test_output0[64] = { + 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, + 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, + 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, + 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00 +}; + + +#ifndef XMRIG_NO_AEON +const static uint8_t test_output1[64] = { + 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, + 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, + 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, + 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, +}; + +//void cryptonight_lite_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); +//void cryptonight_lite_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); +//void cryptonight_lite_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); +//void cryptonight_lite_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); +#endif + + +static inline void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx); +} + + +void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr; + + +static bool self_test(int algo) { + if (cryptonight_hash_ctx == NULL) { + return false; + } + + char output[64]; + + struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16); + ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16); + + cryptonight_hash_ctx(test_input, 76, output, ctx); + + _mm_free(ctx->memory); + _mm_free(ctx); + +# ifndef XMRIG_NO_AEON + if (algo == Options::ALGO_CRYPTONIGHT_LITE) { + return memcmp(output, test_output1, (Options::i()->doubleHash() ? 64 : 32)) == 0; + } +# endif + + return memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; +} + + +bool CryptoNight::init(int algo, int variant) +{ + cryptonight_hash_ctx = cryptonight_av1_aesni; + + return self_test(algo); +} diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h new file mode 100644 index 00000000..1c201af3 --- /dev/null +++ b/src/crypto/CryptoNight.h @@ -0,0 +1,45 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CRYPTONIGHT_H__ +#define __CRYPTONIGHT_H__ + +#include + +#define MEMORY 2097152 /* 2 MiB */ +#define MEMORY_LITE 1048576 /* 1 MiB */ + +struct cryptonight_ctx { + uint8_t state0[200] __attribute__((aligned(16))); + uint8_t state1[200] __attribute__((aligned(16))); + uint8_t* memory __attribute__((aligned(16))); +}; + + +class CryptoNight +{ +public: + static bool init(int algo, int variant); +}; + +#endif /* __CRYPTONIGHT_H__ */ diff --git a/src/crypto/CryptoNight_p.h b/src/crypto/CryptoNight_p.h new file mode 100644 index 00000000..28ca790d --- /dev/null +++ b/src/crypto/CryptoNight_p.h @@ -0,0 +1,349 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CRYPTONIGHT_P_H__ +#define __CRYPTONIGHT_P_H__ + + +#include + + +#include "crypto/CryptoNight.h" + + +extern "C" +{ +#include "crypto/c_keccak.h" +#include "crypto/c_groestl.h" +#include "crypto/c_blake256.h" +#include "crypto/c_jh.h" +#include "crypto/c_skein.h" +} + + +static inline void do_blake_hash(const void* input, size_t len, char* output) { + blake256_hash(reinterpret_cast(output), static_cast(input), len); +} + + +static inline void do_groestl_hash(const void* input, size_t len, char* output) { + groestl(static_cast(input), len * 8, reinterpret_cast(output)); +} + + +static inline void do_jh_hash(const void* input, size_t len, char* output) { + jh_hash(32 * 8, static_cast(input), 8 * len, reinterpret_cast(output)); +} + + +static inline void do_skein_hash(const void* input, size_t len, char* output) { + skein_hash(8 * 32, static_cast(input), 8 * len, reinterpret_cast(output)); +} + + +void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash}; + + +__m128i soft_aesenc(__m128i in, __m128i key); +__m128i soft_aeskeygenassist(__m128i key, uint8_t rcon); + + +#if defined(__x86_64__) +# define EXTRACT64(X) _mm_cvtsi128_si64(X) + +static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) +{ + unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; + *hi = r >> 64; + return (uint64_t) r; +} +#elif defined(__i386__) +# define HI32(X) \ + _mm_srli_si128((X), 4) + + +# define EXTRACT64(X) \ + ((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ + ((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32)) + +static inline uint64_t _umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { + // multiplier = ab = a * 2^32 + b + // multiplicand = cd = c * 2^32 + d + // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d + uint64_t a = multiplier >> 32; + uint64_t b = multiplier & 0xFFFFFFFF; + uint64_t c = multiplicand >> 32; + uint64_t d = multiplicand & 0xFFFFFFFF; + + //uint64_t ac = a * c; + uint64_t ad = a * d; + //uint64_t bc = b * c; + uint64_t bd = b * d; + + uint64_t adbc = ad + (b * c); + uint64_t adbc_carry = adbc < ad ? 1 : 0; + + // multiplier * multiplicand = product_hi * 2^64 + product_lo + uint64_t product_lo = bd + (adbc << 32); + uint64_t product_lo_carry = product_lo < bd ? 1 : 0; + *product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; + + return product_lo; +} +#endif + + +// This will shift and xor tmp1 into itself as 4 32-bit vals such as +// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1) +static inline __m128i sl_xor(__m128i tmp1) +{ + __m128i tmp4; + tmp4 = _mm_slli_si128(tmp1, 0x04); + tmp1 = _mm_xor_si128(tmp1, tmp4); + tmp4 = _mm_slli_si128(tmp4, 0x04); + tmp1 = _mm_xor_si128(tmp1, tmp4); + tmp4 = _mm_slli_si128(tmp4, 0x04); + tmp1 = _mm_xor_si128(tmp1, tmp4); + return tmp1; +} + + +template +static inline void aes_genkey_sub(__m128i* xout0, __m128i* xout2) +{ + __m128i xout1 = _mm_aeskeygenassist_si128(*xout2, rcon); + xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem + *xout0 = sl_xor(*xout0); + *xout0 = _mm_xor_si128(*xout0, xout1); + xout1 = _mm_aeskeygenassist_si128(*xout0, 0x00); + xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem + *xout2 = sl_xor(*xout2); + *xout2 = _mm_xor_si128(*xout2, xout1); +} + + +static inline void soft_aes_genkey_sub(__m128i* xout0, __m128i* xout2, uint8_t rcon) +{ + __m128i xout1 = soft_aeskeygenassist(*xout2, rcon); + xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem + *xout0 = sl_xor(*xout0); + *xout0 = _mm_xor_si128(*xout0, xout1); + xout1 = soft_aeskeygenassist(*xout0, 0x00); + xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem + *xout2 = sl_xor(*xout2); + *xout2 = _mm_xor_si128(*xout2, xout1); +} + + +template +static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9) +{ + __m128i xout0 = _mm_load_si128(memory); + __m128i xout2 = _mm_load_si128(memory +1 ); + *k0 = xout0; + *k1 = xout2; + + SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x01) : aes_genkey_sub<0x01>(&xout0, &xout2); + *k2 = xout0; + *k3 = xout2; + + SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x02) : aes_genkey_sub<0x02>(&xout0, &xout2); + *k4 = xout0; + *k5 = xout2; + + SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x04) : aes_genkey_sub<0x04>(&xout0, &xout2); + *k6 = xout0; + *k7 = xout2; + + SOFT_AES ? soft_aes_genkey_sub(&xout0, &xout2, 0x08) : aes_genkey_sub<0x08>(&xout0, &xout2); + *k8 = xout0; + *k9 = xout2; +} + + +template +static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7) +{ + if (SOFT_AES) { + *x0 = soft_aesenc(*x0, key); + *x1 = soft_aesenc(*x1, key); + *x2 = soft_aesenc(*x2, key); + *x3 = soft_aesenc(*x3, key); + *x4 = soft_aesenc(*x4, key); + *x5 = soft_aesenc(*x5, key); + *x6 = soft_aesenc(*x6, key); + *x7 = soft_aesenc(*x7, key); + } + else { + *x0 = _mm_aesenc_si128(*x0, key); + *x1 = _mm_aesenc_si128(*x1, key); + *x2 = _mm_aesenc_si128(*x2, key); + *x3 = _mm_aesenc_si128(*x3, key); + *x4 = _mm_aesenc_si128(*x4, key); + *x5 = _mm_aesenc_si128(*x5, key); + *x6 = _mm_aesenc_si128(*x6, key); + *x7 = _mm_aesenc_si128(*x7, key); + } +} + + +template +static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) +{ + __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; + __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; + + aes_genkey(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); + + xin0 = _mm_load_si128(input + 4); + xin1 = _mm_load_si128(input + 5); + xin2 = _mm_load_si128(input + 6); + xin3 = _mm_load_si128(input + 7); + xin4 = _mm_load_si128(input + 8); + xin5 = _mm_load_si128(input + 9); + xin6 = _mm_load_si128(input + 10); + xin7 = _mm_load_si128(input + 11); + + for (size_t i = 0; __builtin_expect(i < MEM / sizeof(__m128i), 1); i += 8) { + aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + + _mm_store_si128(output + i + 0, xin0); + _mm_store_si128(output + i + 1, xin1); + _mm_store_si128(output + i + 2, xin2); + _mm_store_si128(output + i + 3, xin3); + _mm_store_si128(output + i + 4, xin4); + _mm_store_si128(output + i + 5, xin5); + _mm_store_si128(output + i + 6, xin6); + _mm_store_si128(output + i + 7, xin7); + } +} + + +template +static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) +{ + __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; + __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; + + aes_genkey(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); + + xout0 = _mm_load_si128(output + 4); + xout1 = _mm_load_si128(output + 5); + xout2 = _mm_load_si128(output + 6); + xout3 = _mm_load_si128(output + 7); + xout4 = _mm_load_si128(output + 8); + xout5 = _mm_load_si128(output + 9); + xout6 = _mm_load_si128(output + 10); + xout7 = _mm_load_si128(output + 11); + + for (size_t i = 0; __builtin_expect(i < MEM / sizeof(__m128i), 1); i += 8) + { + xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); + xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); + xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); + xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); + xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); + xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); + xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); + xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); + + aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + } + + _mm_store_si128(output + 4, xout0); + _mm_store_si128(output + 5, xout1); + _mm_store_si128(output + 6, xout2); + _mm_store_si128(output + 7, xout3); + _mm_store_si128(output + 8, xout4); + _mm_store_si128(output + 9, xout5); + _mm_store_si128(output + 10, xout6); + _mm_store_si128(output + 11, xout7); +} + + +template +void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx) +{ + keccak(static_cast(input), size, ctx->state0, 200); + + cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); + + const uint8_t* l0 = ctx->memory; + uint64_t* h0 = reinterpret_cast(ctx->state0); + + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t ah0 = h0[1] ^ h0[5]; + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + + uint64_t idx0 = h0[0] ^ h0[4]; + + for (size_t i = 0; __builtin_expect(i < ITERATIONS, 1); i++) { + __m128i cx; + cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); + cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); + + _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + idx0 = EXTRACT64(cx); + bx0 = cx; + + uint64_t hi, lo, cl, ch; + cl = ((uint64_t*) &l0[idx0 & MASK])[0]; + ch = ((uint64_t*) &l0[idx0 & MASK])[1]; + lo = _umul128(idx0, cl, &hi); + + al0 += hi; + ah0 += lo; + + ((uint64_t*)&l0[idx0 & MASK])[0] = al0; + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + + ah0 ^= ch; + al0 ^= cl; + idx0 = al0; + } + + cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); + + keccakf(h0, 24); + extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast(output)); +} + +#endif /* __CRYPTONIGHT_P_H__ */ From 8b83a5fe2e9e0dd117077aba5284209a4e314b9a Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 23:31:42 +0300 Subject: [PATCH 18/92] Implemented CryptoNight with C++ templates. --- CMakeLists.txt | 1 + src/Options.cpp | 4 + src/crypto/CryptoNight.cpp | 141 ++++++++++++++++++++-------------- src/crypto/CryptoNight.h | 6 ++ src/crypto/CryptoNight_p.h | 96 +++++++++++++++++++++-- src/crypto/CryptoNight_test.h | 60 +++++++++++++++ 6 files changed, 242 insertions(+), 66 deletions(-) create mode 100644 src/crypto/CryptoNight_test.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d993dda..5f34e234 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ set(HEADERS_CRYPTO src/crypto/c_skein.h src/crypto/CryptoNight.h src/crypto/CryptoNight_p.h + src/crypto/CryptoNight_test.h src/crypto/groestl_tables.h src/crypto/hash.h src/crypto/skein_port.h diff --git a/src/Options.cpp b/src/Options.cpp index 1fbdb141..11f01d00 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -178,6 +178,10 @@ Options::Options(int argc, char **argv) : m_pass = strdup("x"); } + if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) { + m_doubleHash = true; + } + m_ready = true; } diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index a96ac761..b6273dc5 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -24,56 +24,93 @@ #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_p.h" +#include "crypto/CryptoNight_test.h" #include "Options.h" -const static uint8_t test_input[152] = { - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, - 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, - 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, - 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, - 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01 -}; - - -const static uint8_t test_output0[64] = { - 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, - 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, - 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, - 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00 -}; - - -#ifndef XMRIG_NO_AEON -const static uint8_t test_output1[64] = { - 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, - 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, - 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, - 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, -}; - -//void cryptonight_lite_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -//void cryptonight_lite_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -//void cryptonight_lite_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -//void cryptonight_lite_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -#endif - - -static inline void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { - cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx); -} - - void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = nullptr; -static bool self_test(int algo) { - if (cryptonight_hash_ctx == NULL) { +static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx); +} + + +static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx); +} + + +static void cryptonight_av3_softaes(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, true>(input, size, output, ctx); +} + + +static void cryptonight_av4_softaes_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, true>(input, size, output, ctx); +} + + +#ifndef XMRIG_NO_AEON +static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx); +} + + +static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx); +} + + +static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, true>(input, size, output, ctx); +} + + +static void cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { + cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, true>(input, size, output, ctx); +} + +void (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = { + cryptonight_av1_aesni, + cryptonight_av2_aesni_double, + cryptonight_av3_softaes, + cryptonight_av4_softaes_double, + cryptonight_lite_av1_aesni, + cryptonight_lite_av2_aesni_double, + cryptonight_lite_av3_softaes, + cryptonight_lite_av4_softaes_double + }; +#else +void (*cryptonight_variations[4])(const void *input, size_t size, void *output, cryptonight_ctx *ctx) = { + cryptonight_av1_aesni, + cryptonight_av2_aesni_double, + cryptonight_av3_softaes, + cryptonight_av4_softaes_double + }; +#endif + + +bool CryptoNight::init(int algo, int variant) +{ + if (variant < 1 || variant > 4) { + return false; + } + +# ifndef XMRIG_NO_AEON + const int index = algo == Options::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1); +# else + const int index = variant - 1; +# endif + + cryptonight_hash_ctx = cryptonight_variations[index]; + + return selfTest(algo); +} + + +bool CryptoNight::selfTest(int algo) { + if (cryptonight_hash_ctx == nullptr) { return false; } @@ -87,19 +124,5 @@ static bool self_test(int algo) { _mm_free(ctx->memory); _mm_free(ctx); -# ifndef XMRIG_NO_AEON - if (algo == Options::ALGO_CRYPTONIGHT_LITE) { - return memcmp(output, test_output1, (Options::i()->doubleHash() ? 64 : 32)) == 0; - } -# endif - - return memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; -} - - -bool CryptoNight::init(int algo, int variant) -{ - cryptonight_hash_ctx = cryptonight_av1_aesni; - - return self_test(algo); + return memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; } diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 1c201af3..ce1b7ba8 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -24,11 +24,14 @@ #ifndef __CRYPTONIGHT_H__ #define __CRYPTONIGHT_H__ + #include + #define MEMORY 2097152 /* 2 MiB */ #define MEMORY_LITE 1048576 /* 1 MiB */ + struct cryptonight_ctx { uint8_t state0[200] __attribute__((aligned(16))); uint8_t state1[200] __attribute__((aligned(16))); @@ -40,6 +43,9 @@ class CryptoNight { public: static bool init(int algo, int variant); + +private: + static bool selfTest(int algo); }; #endif /* __CRYPTONIGHT_H__ */ diff --git a/src/crypto/CryptoNight_p.h b/src/crypto/CryptoNight_p.h index 28ca790d..ed24a510 100644 --- a/src/crypto/CryptoNight_p.h +++ b/src/crypto/CryptoNight_p.h @@ -38,6 +38,9 @@ extern "C" #include "crypto/c_blake256.h" #include "crypto/c_jh.h" #include "crypto/c_skein.h" + +__m128i soft_aesenc(__m128i in, __m128i key); +__m128i soft_aeskeygenassist(__m128i key, uint8_t rcon); } @@ -64,14 +67,11 @@ static inline void do_skein_hash(const void* input, size_t len, char* output) { void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash}; -__m128i soft_aesenc(__m128i in, __m128i key); -__m128i soft_aeskeygenassist(__m128i key, uint8_t rcon); - #if defined(__x86_64__) # define EXTRACT64(X) _mm_cvtsi128_si64(X) -static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) +static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) { unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; *hi = r >> 64; @@ -86,7 +86,7 @@ static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) ((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ ((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32)) -static inline uint64_t _umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { +static inline uint64_t __umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { // multiplier = ab = a * 2^32 + b // multiplicand = cd = c * 2^32 + d // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d @@ -300,7 +300,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) template -void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx) { keccak(static_cast(input), size, ctx->state0, 200); @@ -327,7 +327,7 @@ void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restr uint64_t hi, lo, cl, ch; cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - lo = _umul128(idx0, cl, &hi); + lo = __umul128(idx0, cl, &hi); al0 += hi; ah0 += lo; @@ -346,4 +346,86 @@ void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restr extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast(output)); } + +template +inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +{ + keccak((const uint8_t *) input, size, ctx->state0, 200); + keccak((const uint8_t *) input + size, size, ctx->state1, 200); + + const uint8_t* l0 = ctx->memory; + const uint8_t* l1 = ctx->memory + MEMORY; + uint64_t* h0 = reinterpret_cast(ctx->state0); + uint64_t* h1 = reinterpret_cast(ctx->state1); + + cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); + cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); + + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t al1 = h1[0] ^ h1[4]; + uint64_t ah0 = h0[1] ^ h0[5]; + uint64_t ah1 = h1[1] ^ h1[5]; + + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + + uint64_t idx0 = h0[0] ^ h0[4]; + uint64_t idx1 = h1[0] ^ h1[4]; + + for (size_t i = 0; __builtin_expect(i < ITERATIONS, 1); i++) { + __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); + __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); + + cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); + cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); + + _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + + idx0 = EXTRACT64(cx0); + idx1 = EXTRACT64(cx1); + + bx0 = cx0; + bx1 = cx1; + + uint64_t hi, lo, cl, ch; + cl = ((uint64_t*) &l0[idx0 & MASK])[0]; + ch = ((uint64_t*) &l0[idx0 & MASK])[1]; + lo = __umul128(idx0, cl, &hi); + + al0 += hi; + ah0 += lo; + + ((uint64_t*) &l0[idx0 & MASK])[0] = al0; + ((uint64_t*) &l0[idx0 & MASK])[1] = ah0; + + ah0 ^= ch; + al0 ^= cl; + idx0 = al0; + + cl = ((uint64_t*) &l1[idx1 & MASK])[0]; + ch = ((uint64_t*) &l1[idx1 & MASK])[1]; + lo = __umul128(idx1, cl, &hi); + + al1 += hi; + ah1 += lo; + + ((uint64_t*) &l1[idx1 & MASK])[0] = al1; + ((uint64_t*) &l1[idx1 & MASK])[1] = ah1; + + ah1 ^= ch; + al1 ^= cl; + idx1 = al1; + } + + cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); + cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); + + keccakf(h0, 24); + keccakf(h1, 24); + + extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast(output)); + extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, static_cast(output) + 32); +} + #endif /* __CRYPTONIGHT_P_H__ */ diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h new file mode 100644 index 00000000..b2985379 --- /dev/null +++ b/src/crypto/CryptoNight_test.h @@ -0,0 +1,60 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CRYPTONIGHT_TEST_H__ +#define __CRYPTONIGHT_TEST_H__ + + +const static uint8_t test_input[152] = { + 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, + 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, + 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, + 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, + 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, + 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, + 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, + 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, + 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, + 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01 +}; + + +const static uint8_t test_output0[64] = { + 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, + 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, + 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, + 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00 +}; + + +#ifndef XMRIG_NO_AEON +const static uint8_t test_output1[64] = { + 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, + 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, + 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, + 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, +}; +#endif + + +#endif /* __CRYPTONIGHT_TEST_H__ */ From 04c5d6d00ad4ebbebebc014417261b41342f20d3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 9 Jun 2017 02:47:46 +0300 Subject: [PATCH 19/92] Print threads summary. --- .../cryptonight-lite/cryptonight_lite_aesni.h | 256 ------------------ .../cryptonight_lite_av1_aesni.c | 77 ------ .../cryptonight_lite_av2_aesni_double.c | 111 -------- .../cryptonight_lite_av3_softaes.c | 77 ------ .../cryptonight_lite_av4_softaes_double.c | 111 -------- .../cryptonight_lite_softaes.h | 237 ---------------- algo/cryptonight/cryptonight.c | 244 ----------------- algo/cryptonight/cryptonight.h | 47 ---- algo/cryptonight/cryptonight_aesni.h | 256 ------------------ algo/cryptonight/cryptonight_av1_aesni.c | 77 ------ .../cryptonight_av2_aesni_double.c | 111 -------- algo/cryptonight/cryptonight_av3_softaes.c | 77 ------ .../cryptonight_av4_softaes_double.c | 111 -------- algo/cryptonight/cryptonight_softaes.h | 237 ---------------- crypto/hash.c | 24 -- src/Options.cpp | 33 +-- src/Options.h | 3 + src/Summary.cpp | 34 ++- 18 files changed, 51 insertions(+), 2072 deletions(-) delete mode 100644 algo/cryptonight-lite/cryptonight_lite_aesni.h delete mode 100644 algo/cryptonight-lite/cryptonight_lite_av1_aesni.c delete mode 100644 algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c delete mode 100644 algo/cryptonight-lite/cryptonight_lite_av3_softaes.c delete mode 100644 algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c delete mode 100644 algo/cryptonight-lite/cryptonight_lite_softaes.h delete mode 100644 algo/cryptonight/cryptonight.c delete mode 100644 algo/cryptonight/cryptonight.h delete mode 100644 algo/cryptonight/cryptonight_aesni.h delete mode 100644 algo/cryptonight/cryptonight_av1_aesni.c delete mode 100644 algo/cryptonight/cryptonight_av2_aesni_double.c delete mode 100644 algo/cryptonight/cryptonight_av3_softaes.c delete mode 100644 algo/cryptonight/cryptonight_av4_softaes_double.c delete mode 100644 algo/cryptonight/cryptonight_softaes.h delete mode 100644 crypto/hash.c diff --git a/algo/cryptonight-lite/cryptonight_lite_aesni.h b/algo/cryptonight-lite/cryptonight_lite_aesni.h deleted file mode 100644 index bb528cfb..00000000 --- a/algo/cryptonight-lite/cryptonight_lite_aesni.h +++ /dev/null @@ -1,256 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __CRYPTONIGHT_LITE_AESNI_H__ -#define __CRYPTONIGHT_LITE_AESNI_H__ - -#include - - -#define aes_genkey_sub(imm8) \ - __m128i xout1 = _mm_aeskeygenassist_si128(*xout2, (imm8)); \ - xout1 = _mm_shuffle_epi32(xout1, 0xFF); \ - *xout0 = sl_xor(*xout0); \ - *xout0 = _mm_xor_si128(*xout0, xout1); \ - xout1 = _mm_aeskeygenassist_si128(*xout0, 0x00);\ - xout1 = _mm_shuffle_epi32(xout1, 0xAA); \ - *xout2 = sl_xor(*xout2); \ - *xout2 = _mm_xor_si128(*xout2, xout1); \ - - -// This will shift and xor tmp1 into itself as 4 32-bit vals such as -// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1) -static inline __m128i sl_xor(__m128i tmp1) -{ - __m128i tmp4; - tmp4 = _mm_slli_si128(tmp1, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - return tmp1; -} - - -static inline void aes_genkey_sub1(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x1) -} - - -static inline void aes_genkey_sub2(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x2) -} - - -static inline void aes_genkey_sub4(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x4) -} - - -static inline void aes_genkey_sub8(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x8) -} - - -static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7) -{ - *x0 = _mm_aesenc_si128(*x0, key); - *x1 = _mm_aesenc_si128(*x1, key); - *x2 = _mm_aesenc_si128(*x2, key); - *x3 = _mm_aesenc_si128(*x3, key); - *x4 = _mm_aesenc_si128(*x4, key); - *x5 = _mm_aesenc_si128(*x5, key); - *x6 = _mm_aesenc_si128(*x6, key); - *x7 = _mm_aesenc_si128(*x7, key); -} - - -static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9) -{ - __m128i xout0 = _mm_load_si128(memory); - __m128i xout2 = _mm_load_si128(memory + 1); - *k0 = xout0; - *k1 = xout2; - - aes_genkey_sub1(&xout0, &xout2); - *k2 = xout0; - *k3 = xout2; - - aes_genkey_sub2(&xout0, &xout2); - *k4 = xout0; - *k5 = xout2; - - aes_genkey_sub4(&xout0, &xout2); - *k6 = xout0; - *k7 = xout2; - - aes_genkey_sub8(&xout0, &xout2); - *k8 = xout0; - *k9 = xout2; -} - - -static inline void cn_explode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xin0 = _mm_load_si128(input + 4); - xin1 = _mm_load_si128(input + 5); - xin2 = _mm_load_si128(input + 6); - xin3 = _mm_load_si128(input + 7); - xin4 = _mm_load_si128(input + 8); - xin5 = _mm_load_si128(input + 9); - xin6 = _mm_load_si128(input + 10); - xin7 = _mm_load_si128(input + 11); - - for (size_t i = 0; __builtin_expect(i < MEMORY_LITE / sizeof(__m128i), 1); i += 8) { - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - _mm_store_si128(output + i + 0, xin0); - _mm_store_si128(output + i + 1, xin1); - _mm_store_si128(output + i + 2, xin2); - _mm_store_si128(output + i + 3, xin3); - _mm_store_si128(output + i + 4, xin4); - _mm_store_si128(output + i + 5, xin5); - _mm_store_si128(output + i + 6, xin6); - _mm_store_si128(output + i + 7, xin7); - } -} - - -static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xout0 = _mm_load_si128(output + 4); - xout1 = _mm_load_si128(output + 5); - xout2 = _mm_load_si128(output + 6); - xout3 = _mm_load_si128(output + 7); - xout4 = _mm_load_si128(output + 8); - xout5 = _mm_load_si128(output + 9); - xout6 = _mm_load_si128(output + 10); - xout7 = _mm_load_si128(output + 11); - - for (size_t i = 0; __builtin_expect(i < MEMORY_LITE / sizeof(__m128i), 1); i += 8) - { - xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); - xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); - xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); - xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); - xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); - xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); - xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); - xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - - _mm_store_si128(output + 4, xout0); - _mm_store_si128(output + 5, xout1); - _mm_store_si128(output + 6, xout2); - _mm_store_si128(output + 7, xout3); - _mm_store_si128(output + 8, xout4); - _mm_store_si128(output + 9, xout5); - _mm_store_si128(output + 10, xout6); - _mm_store_si128(output + 11, xout7); -} - - -#if defined(__x86_64__) -# define EXTRACT64(X) _mm_cvtsi128_si64(X) - -static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) -{ - unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; - *hi = r >> 64; - return (uint64_t) r; -} -#elif defined(__i386__) -# define HI32(X) \ - _mm_srli_si128((X), 4) - - -# define EXTRACT64(X) \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32)) - -static inline uint64_t _umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = multiplier >> 32; - uint64_t b = multiplier & 0xFFFFFFFF; - uint64_t c = multiplicand >> 32; - uint64_t d = multiplicand & 0xFFFFFFFF; - - //uint64_t ac = a * c; - uint64_t ad = a * d; - //uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + (b * c); - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - - return product_lo; -} -#endif - - -#endif /* __CRYPTONIGHT_LITE_AESNI_H__ */ diff --git a/algo/cryptonight-lite/cryptonight_lite_av1_aesni.c b/algo/cryptonight-lite/cryptonight_lite_av1_aesni.c deleted file mode 100644 index 80110fb2..00000000 --- a/algo/cryptonight-lite/cryptonight_lite_av1_aesni.c +++ /dev/null @@ -1,77 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "algo/cryptonight/cryptonight.h" -#include "cryptonight_lite_aesni.h" -#include "crypto/c_keccak.h" - - -void cryptonight_lite_av1_aesni(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); - - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = (uint64_t*) ctx->state0; - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - - for (size_t i = 0; __builtin_expect(i < 0x40000, 1); i++) { - __m128i cx; - cx = _mm_load_si128((__m128i *) &l0[idx0 & 0xFFFF0]); - cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); - - _mm_store_si128((__m128i *) &l0[idx0 & 0xFFFF0], _mm_xor_si128(bx0, cx)); - idx0 = EXTRACT64(cx); - bx0 = cx; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*) &l0[idx0 & 0xFFFF0])[0]; - ch = ((uint64_t*) &l0[idx0 & 0xFFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*)&l0[idx0 & 0xFFFF0])[0] = al0; - ((uint64_t*)&l0[idx0 & 0xFFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - } - - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); - - keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); -} diff --git a/algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c b/algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c deleted file mode 100644 index 055435c6..00000000 --- a/algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c +++ /dev/null @@ -1,111 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "algo/cryptonight/cryptonight.h" -#include "cryptonight_lite_aesni.h" -#include "crypto/c_keccak.h" - - -void cryptonight_lite_av2_aesni_double(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - keccak((const uint8_t *) input + size, size, ctx->state1, 200); - - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEMORY_LITE; - uint64_t* h0 = (uint64_t*) ctx->state0; - uint64_t* h1 = (uint64_t*) ctx->state1; - - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t al1 = h1[0] ^ h1[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - uint64_t ah1 = h1[1] ^ h1[5]; - - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - uint64_t idx1 = h1[0] ^ h1[4]; - - for (size_t i = 0; __builtin_expect(i < 0x40000, 1); i++) { - __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & 0xFFFF0]); - __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & 0xFFFF0]); - - cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); - cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); - - _mm_store_si128((__m128i *) &l0[idx0 & 0xFFFF0], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & 0xFFFF0], _mm_xor_si128(bx1, cx1)); - - idx0 = EXTRACT64(cx0); - idx1 = EXTRACT64(cx1); - - bx0 = cx0; - bx1 = cx1; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*) &l0[idx0 & 0xFFFF0])[0]; - ch = ((uint64_t*) &l0[idx0 & 0xFFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*) &l0[idx0 & 0xFFFF0])[0] = al0; - ((uint64_t*) &l0[idx0 & 0xFFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - - cl = ((uint64_t*) &l1[idx1 & 0xFFFF0])[0]; - ch = ((uint64_t*) &l1[idx1 & 0xFFFF0])[1]; - lo = _umul128(idx1, cl, &hi); - - al1 += hi; - ah1 += lo; - - ((uint64_t*) &l1[idx1 & 0xFFFF0])[0] = al1; - ((uint64_t*) &l1[idx1 & 0xFFFF0])[1] = ah1; - - ah1 ^= ch; - al1 ^= cl; - idx1 = al1; - } - - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); - - keccakf(h0, 24); - keccakf(h1, 24); - - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, (char*) output + 32); -} diff --git a/algo/cryptonight-lite/cryptonight_lite_av3_softaes.c b/algo/cryptonight-lite/cryptonight_lite_av3_softaes.c deleted file mode 100644 index 3dec6e33..00000000 --- a/algo/cryptonight-lite/cryptonight_lite_av3_softaes.c +++ /dev/null @@ -1,77 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "algo/cryptonight/cryptonight.h" -#include "cryptonight_lite_softaes.h" -#include "crypto/c_keccak.h" - - -void cryptonight_lite_av3_softaes(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); - - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = (uint64_t*) ctx->state0; - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - - for (size_t i = 0; __builtin_expect(i < 0x40000, 1); i++) { - __m128i cx; - cx = _mm_load_si128((__m128i *)&l0[idx0 & 0xFFFF0]); - cx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0)); - - _mm_store_si128((__m128i *)&l0[idx0 & 0xFFFF0], _mm_xor_si128(bx0, cx)); - idx0 = EXTRACT64(cx); - bx0 = cx; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*)&l0[idx0 & 0xFFFF0])[0]; - ch = ((uint64_t*)&l0[idx0 & 0xFFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*)&l0[idx0 & 0xFFFF0])[0] = al0; - ((uint64_t*)&l0[idx0 & 0xFFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - } - - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); - - keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); -} diff --git a/algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c b/algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c deleted file mode 100644 index 873b8cac..00000000 --- a/algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c +++ /dev/null @@ -1,111 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "algo/cryptonight/cryptonight.h" -#include "cryptonight_lite_softaes.h" -#include "crypto/c_keccak.h" - - -void cryptonight_lite_av4_softaes_double(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - keccak((const uint8_t *) input + size, size, ctx->state1, 200); - - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEMORY_LITE; - uint64_t* h0 = (uint64_t*) ctx->state0; - uint64_t* h1 = (uint64_t*) ctx->state1; - - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t al1 = h1[0] ^ h1[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - uint64_t ah1 = h1[1] ^ h1[5]; - - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - uint64_t idx1 = h1[0] ^ h1[4]; - - for (size_t i = 0; __builtin_expect(i < 0x40000, 1); i++) { - __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & 0xFFFF0]); - __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & 0xFFFF0]); - - cx0 = soft_aesenc(cx0, _mm_set_epi64x(ah0, al0)); - cx1 = soft_aesenc(cx1, _mm_set_epi64x(ah1, al1)); - - _mm_store_si128((__m128i *) &l0[idx0 & 0xFFFF0], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & 0xFFFF0], _mm_xor_si128(bx1, cx1)); - - idx0 = EXTRACT64(cx0); - idx1 = EXTRACT64(cx1); - - bx0 = cx0; - bx1 = cx1; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*) &l0[idx0 & 0xFFFF0])[0]; - ch = ((uint64_t*) &l0[idx0 & 0xFFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*) &l0[idx0 & 0xFFFF0])[0] = al0; - ((uint64_t*) &l0[idx0 & 0xFFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - - cl = ((uint64_t*) &l1[idx1 & 0xFFFF0])[0]; - ch = ((uint64_t*) &l1[idx1 & 0xFFFF0])[1]; - lo = _umul128(idx1, cl, &hi); - - al1 += hi; - ah1 += lo; - - ((uint64_t*) &l1[idx1 & 0xFFFF0])[0] = al1; - ((uint64_t*) &l1[idx1 & 0xFFFF0])[1] = ah1; - - ah1 ^= ch; - al1 ^= cl; - idx1 = al1; - } - - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); - - keccakf(h0, 24); - keccakf(h1, 24); - - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, (char*) output + 32); -} diff --git a/algo/cryptonight-lite/cryptonight_lite_softaes.h b/algo/cryptonight-lite/cryptonight_lite_softaes.h deleted file mode 100644 index bab3dcaf..00000000 --- a/algo/cryptonight-lite/cryptonight_lite_softaes.h +++ /dev/null @@ -1,237 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __CRYPTONIGHT_LITE_SOFTAES_H__ -#define __CRYPTONIGHT_LITE_SOFTAES_H__ - -#include - -extern __m128i soft_aesenc(__m128i in, __m128i key); -extern __m128i soft_aeskeygenassist(__m128i key, uint8_t rcon); - - -// This will shift and xor tmp1 into itself as 4 32-bit vals such as -// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1) -static inline __m128i sl_xor(__m128i tmp1) -{ - __m128i tmp4; - tmp4 = _mm_slli_si128(tmp1, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - return tmp1; -} - - -static inline void aes_genkey_sub(__m128i* xout0, __m128i* xout2, uint8_t rcon) -{ - __m128i xout1 = soft_aeskeygenassist(*xout2, rcon); - xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem - *xout0 = sl_xor(*xout0); - *xout0 = _mm_xor_si128(*xout0, xout1); - xout1 = soft_aeskeygenassist(*xout0, 0x00); - xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem - *xout2 = sl_xor(*xout2); - *xout2 = _mm_xor_si128(*xout2, xout1); -} - - -static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7) -{ - *x0 = soft_aesenc(*x0, key); - *x1 = soft_aesenc(*x1, key); - *x2 = soft_aesenc(*x2, key); - *x3 = soft_aesenc(*x3, key); - *x4 = soft_aesenc(*x4, key); - *x5 = soft_aesenc(*x5, key); - *x6 = soft_aesenc(*x6, key); - *x7 = soft_aesenc(*x7, key); -} - - -static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9) -{ - __m128i xout0 = _mm_load_si128(memory); - __m128i xout2 = _mm_load_si128(memory + 1); - *k0 = xout0; - *k1 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x1); - *k2 = xout0; - *k3 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x2); - *k4 = xout0; - *k5 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x4); - *k6 = xout0; - *k7 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x8); - *k8 = xout0; - *k9 = xout2; -} - - -static inline void cn_explode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xin0 = _mm_load_si128(input + 4); - xin1 = _mm_load_si128(input + 5); - xin2 = _mm_load_si128(input + 6); - xin3 = _mm_load_si128(input + 7); - xin4 = _mm_load_si128(input + 8); - xin5 = _mm_load_si128(input + 9); - xin6 = _mm_load_si128(input + 10); - xin7 = _mm_load_si128(input + 11); - - for (size_t i = 0; i < MEMORY_LITE / sizeof(__m128i); i += 8) { - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - _mm_store_si128(output + i + 0, xin0); - _mm_store_si128(output + i + 1, xin1); - _mm_store_si128(output + i + 2, xin2); - _mm_store_si128(output + i + 3, xin3); - _mm_store_si128(output + i + 4, xin4); - _mm_store_si128(output + i + 5, xin5); - _mm_store_si128(output + i + 6, xin6); - _mm_store_si128(output + i + 7, xin7); - } -} - - -static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xout0 = _mm_load_si128(output + 4); - xout1 = _mm_load_si128(output + 5); - xout2 = _mm_load_si128(output + 6); - xout3 = _mm_load_si128(output + 7); - xout4 = _mm_load_si128(output + 8); - xout5 = _mm_load_si128(output + 9); - xout6 = _mm_load_si128(output + 10); - xout7 = _mm_load_si128(output + 11); - - for (size_t i = 0; __builtin_expect(i < MEMORY_LITE / sizeof(__m128i), 1); i += 8) - { - xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); - xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); - xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); - xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); - xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); - xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); - xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); - xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - - _mm_store_si128(output + 4, xout0); - _mm_store_si128(output + 5, xout1); - _mm_store_si128(output + 6, xout2); - _mm_store_si128(output + 7, xout3); - _mm_store_si128(output + 8, xout4); - _mm_store_si128(output + 9, xout5); - _mm_store_si128(output + 10, xout6); - _mm_store_si128(output + 11, xout7); -} - - -#if defined(__x86_64__) -# define EXTRACT64(X) _mm_cvtsi128_si64(X) - -static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) -{ - unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; - *hi = r >> 64; - return (uint64_t) r; -} -#elif defined(__i386__) -# define HI32(X) \ - _mm_srli_si128((X), 4) - - -# define EXTRACT64(X) \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32)) - -static inline uint64_t _umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = multiplier >> 32; - uint64_t b = multiplier & 0xFFFFFFFF; - uint64_t c = multiplicand >> 32; - uint64_t d = multiplicand & 0xFFFFFFFF; - - //uint64_t ac = a * c; - uint64_t ad = a * d; - //uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + (b * c); - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - - return product_lo; -} -#endif - - -#endif /* __CRYPTONIGHT_LITE_SOFTAES_H__ */ diff --git a/algo/cryptonight/cryptonight.c b/algo/cryptonight/cryptonight.c deleted file mode 100644 index 73018728..00000000 --- a/algo/cryptonight/cryptonight.c +++ /dev/null @@ -1,244 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include - -#ifndef BUILD_TEST -# include "xmrig.h" -#endif - -#include "crypto/c_groestl.h" -#include "crypto/c_blake256.h" -#include "crypto/c_jh.h" -#include "crypto/c_skein.h" -#include "cryptonight.h" -#include "options.h" - - -const static char test_input[152] = { - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, - 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, - 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, - 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, - 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01 -}; - - -const static char test_output0[64] = { - 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, - 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, - 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, - 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00 -}; - - -void cryptonight_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); - -#ifndef XMRIG_NO_AEON -const static char test_output1[64] = { - 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, - 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, - 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, - 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, -}; - -void cryptonight_lite_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -#endif - -void (*cryptonight_hash_ctx)(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) = NULL; - - -static bool self_test() { - if (cryptonight_hash_ctx == NULL) { - return false; - } - - char output[64]; - - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16); - ctx->memory = (uint8_t *) _mm_malloc(MEMORY * 2, 16); - - cryptonight_hash_ctx(test_input, 76, output, ctx); - - _mm_free(ctx->memory); - _mm_free(ctx); - -# ifndef XMRIG_NO_AEON - if (opt_algo == ALGO_CRYPTONIGHT_LITE) { - return memcmp(output, test_output1, (opt_double_hash ? 64 : 32)) == 0; - } -# endif - - return memcmp(output, test_output0, (opt_double_hash ? 64 : 32)) == 0; -} - - -#ifndef XMRIG_NO_AEON -bool cryptonight_lite_init(int variant) { - switch (variant) { - case AEON_AV1_AESNI: - cryptonight_hash_ctx = cryptonight_lite_av1_aesni; - break; - - case AEON_AV2_AESNI_DOUBLE: - opt_double_hash = true; - cryptonight_hash_ctx = cryptonight_lite_av2_aesni_double; - break; - - case AEON_AV3_SOFT_AES: - cryptonight_hash_ctx = cryptonight_lite_av3_softaes; - break; - - case AEON_AV4_SOFT_AES_DOUBLE: - opt_double_hash = true; - cryptonight_hash_ctx = cryptonight_lite_av4_softaes_double; - break; - - default: - break; - } - - return self_test(); -} -#endif - - -bool cryptonight_init(int variant) -{ -# ifndef XMRIG_NO_AEON - if (opt_algo == ALGO_CRYPTONIGHT_LITE) { - return cryptonight_lite_init(variant); - } -# endif - - switch (variant) { - case XMR_AV1_AESNI: - cryptonight_hash_ctx = cryptonight_av1_aesni; - break; - - case XMR_AV2_AESNI_DOUBLE: - opt_double_hash = true; - cryptonight_hash_ctx = cryptonight_av2_aesni_double; - break; - - case XMR_AV3_SOFT_AES: - cryptonight_hash_ctx = cryptonight_av3_softaes; - break; - - case XMR_AV4_SOFT_AES_DOUBLE: - opt_double_hash = true; - cryptonight_hash_ctx = cryptonight_av4_softaes_double; - break; - - default: - break; - } - - return self_test(); -} - - -static inline void do_blake_hash(const void* input, size_t len, char* output) { - blake256_hash((uint8_t*)output, input, len); -} - - -static inline void do_groestl_hash(const void* input, size_t len, char* output) { - groestl(input, len * 8, (uint8_t*)output); -} - - -static inline void do_jh_hash(const void* input, size_t len, char* output) { - jh_hash(32 * 8, input, 8 * len, (uint8_t*)output); -} - - -static inline void do_skein_hash(const void* input, size_t len, char* output) { - skein_hash(8 * 32, input, 8 * len, (uint8_t*)output); -} - - -void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash}; - - -#ifndef BUILD_TEST -int scanhash_cryptonight(int thr_id, uint32_t *hash, uint32_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx) { - uint32_t *nonceptr = (uint32_t*) (((char*) blob) + 39); - - do { - cryptonight_hash_ctx(blob, blob_size, hash, ctx); - (*hashes_done)++; - - if (unlikely(hash[7] < target)) { - return 1; - } - - (*nonceptr)++; - } while (likely(((*nonceptr) < max_nonce && !work_restart[thr_id].restart))); - - return 0; -} - - -int scanhash_cryptonight_double(int thr_id, uint32_t *hash, uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx) { - int rc = 0; - uint32_t *nonceptr0 = (uint32_t*) (((char*) blob) + 39); - uint32_t *nonceptr1 = (uint32_t*) (((char*) blob) + 39 + blob_size); - - do { - cryptonight_hash_ctx(blob, blob_size, hash, ctx); - (*hashes_done) += 2; - - if (unlikely(hash[7] < target)) { - return rc |= 1; - } - - if (unlikely(hash[15] < target)) { - return rc |= 2; - } - - if (rc) { - break; - } - - (*nonceptr0)++; - (*nonceptr1)++; - } while (likely(((*nonceptr0) < max_nonce && !work_restart[thr_id].restart))); - - return rc; -} -#endif diff --git a/algo/cryptonight/cryptonight.h b/algo/cryptonight/cryptonight.h deleted file mode 100644 index 0b017073..00000000 --- a/algo/cryptonight/cryptonight.h +++ /dev/null @@ -1,47 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __CRYPTONIGHT_H__ -#define __CRYPTONIGHT_H__ - -#include -#include -#include - -#define MEMORY 2097152 /* 2 MiB */ -#define MEMORY_LITE 1048576 /* 1 MiB */ - -struct cryptonight_ctx { - uint8_t state0[200] __attribute__((aligned(16))); - uint8_t state1[200] __attribute__((aligned(16))); - uint8_t* memory __attribute__((aligned(16))); -}; - - -extern void (* const extra_hashes[4])(const void *, size_t, char *); - -bool cryptonight_init(int variant); -int scanhash_cryptonight(int thr_id, uint32_t *hash, uint32_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx); -int scanhash_cryptonight_double(int thr_id, uint32_t *hash, uint8_t *restrict blob, size_t blob_size, uint32_t target, uint32_t max_nonce, unsigned long *restrict hashes_done, struct cryptonight_ctx *restrict ctx); - -#endif /* __CRYPTONIGHT_H__ */ diff --git a/algo/cryptonight/cryptonight_aesni.h b/algo/cryptonight/cryptonight_aesni.h deleted file mode 100644 index e4d6d42f..00000000 --- a/algo/cryptonight/cryptonight_aesni.h +++ /dev/null @@ -1,256 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __CRYPTONIGHT_AESNI_H__ -#define __CRYPTONIGHT_AESNI_H__ - -#include - - -#define aes_genkey_sub(imm8) \ - __m128i xout1 = _mm_aeskeygenassist_si128(*xout2, (imm8)); \ - xout1 = _mm_shuffle_epi32(xout1, 0xFF); \ - *xout0 = sl_xor(*xout0); \ - *xout0 = _mm_xor_si128(*xout0, xout1); \ - xout1 = _mm_aeskeygenassist_si128(*xout0, 0x00);\ - xout1 = _mm_shuffle_epi32(xout1, 0xAA); \ - *xout2 = sl_xor(*xout2); \ - *xout2 = _mm_xor_si128(*xout2, xout1); \ - - -// This will shift and xor tmp1 into itself as 4 32-bit vals such as -// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1) -static inline __m128i sl_xor(__m128i tmp1) -{ - __m128i tmp4; - tmp4 = _mm_slli_si128(tmp1, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - return tmp1; -} - - -static inline void aes_genkey_sub1(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x1) -} - - -static inline void aes_genkey_sub2(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x2) -} - - -static inline void aes_genkey_sub4(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x4) -} - - -static inline void aes_genkey_sub8(__m128i* xout0, __m128i* xout2) -{ - aes_genkey_sub(0x8) -} - - -static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7) -{ - *x0 = _mm_aesenc_si128(*x0, key); - *x1 = _mm_aesenc_si128(*x1, key); - *x2 = _mm_aesenc_si128(*x2, key); - *x3 = _mm_aesenc_si128(*x3, key); - *x4 = _mm_aesenc_si128(*x4, key); - *x5 = _mm_aesenc_si128(*x5, key); - *x6 = _mm_aesenc_si128(*x6, key); - *x7 = _mm_aesenc_si128(*x7, key); -} - - -static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9) -{ - __m128i xout0 = _mm_load_si128(memory); - __m128i xout2 = _mm_load_si128(memory + 1); - *k0 = xout0; - *k1 = xout2; - - aes_genkey_sub1(&xout0, &xout2); - *k2 = xout0; - *k3 = xout2; - - aes_genkey_sub2(&xout0, &xout2); - *k4 = xout0; - *k5 = xout2; - - aes_genkey_sub4(&xout0, &xout2); - *k6 = xout0; - *k7 = xout2; - - aes_genkey_sub8(&xout0, &xout2); - *k8 = xout0; - *k9 = xout2; -} - - -static inline void cn_explode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xin0 = _mm_load_si128(input + 4); - xin1 = _mm_load_si128(input + 5); - xin2 = _mm_load_si128(input + 6); - xin3 = _mm_load_si128(input + 7); - xin4 = _mm_load_si128(input + 8); - xin5 = _mm_load_si128(input + 9); - xin6 = _mm_load_si128(input + 10); - xin7 = _mm_load_si128(input + 11); - - for (size_t i = 0; __builtin_expect(i < MEMORY / sizeof(__m128i), 1); i += 8) { - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - _mm_store_si128(output + i + 0, xin0); - _mm_store_si128(output + i + 1, xin1); - _mm_store_si128(output + i + 2, xin2); - _mm_store_si128(output + i + 3, xin3); - _mm_store_si128(output + i + 4, xin4); - _mm_store_si128(output + i + 5, xin5); - _mm_store_si128(output + i + 6, xin6); - _mm_store_si128(output + i + 7, xin7); - } -} - - -static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xout0 = _mm_load_si128(output + 4); - xout1 = _mm_load_si128(output + 5); - xout2 = _mm_load_si128(output + 6); - xout3 = _mm_load_si128(output + 7); - xout4 = _mm_load_si128(output + 8); - xout5 = _mm_load_si128(output + 9); - xout6 = _mm_load_si128(output + 10); - xout7 = _mm_load_si128(output + 11); - - for (size_t i = 0; __builtin_expect(i < MEMORY / sizeof(__m128i), 1); i += 8) - { - xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); - xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); - xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); - xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); - xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); - xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); - xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); - xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - - _mm_store_si128(output + 4, xout0); - _mm_store_si128(output + 5, xout1); - _mm_store_si128(output + 6, xout2); - _mm_store_si128(output + 7, xout3); - _mm_store_si128(output + 8, xout4); - _mm_store_si128(output + 9, xout5); - _mm_store_si128(output + 10, xout6); - _mm_store_si128(output + 11, xout7); -} - - -#if defined(__x86_64__) -# define EXTRACT64(X) _mm_cvtsi128_si64(X) - -static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) -{ - unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; - *hi = r >> 64; - return (uint64_t) r; -} -#elif defined(__i386__) -# define HI32(X) \ - _mm_srli_si128((X), 4) - - -# define EXTRACT64(X) \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32)) - -static inline uint64_t _umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = multiplier >> 32; - uint64_t b = multiplier & 0xFFFFFFFF; - uint64_t c = multiplicand >> 32; - uint64_t d = multiplicand & 0xFFFFFFFF; - - //uint64_t ac = a * c; - uint64_t ad = a * d; - //uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + (b * c); - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - - return product_lo; -} -#endif - - -#endif /* __CRYPTONIGHT_AESNI_H__ */ diff --git a/algo/cryptonight/cryptonight_av1_aesni.c b/algo/cryptonight/cryptonight_av1_aesni.c deleted file mode 100644 index 3f30544e..00000000 --- a/algo/cryptonight/cryptonight_av1_aesni.c +++ /dev/null @@ -1,77 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "cryptonight.h" -#include "cryptonight_aesni.h" -#include "crypto/c_keccak.h" - - -void cryptonight_av1_aesni(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); - - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = (uint64_t*) ctx->state0; - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - - for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i cx; - cx = _mm_load_si128((__m128i *) &l0[idx0 & 0x1FFFF0]); - cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); - - _mm_store_si128((__m128i *) &l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx)); - idx0 = EXTRACT64(cx); - bx0 = cx; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0]; - ch = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0; - ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - } - - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); - - keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); -} diff --git a/algo/cryptonight/cryptonight_av2_aesni_double.c b/algo/cryptonight/cryptonight_av2_aesni_double.c deleted file mode 100644 index 779b9bc3..00000000 --- a/algo/cryptonight/cryptonight_av2_aesni_double.c +++ /dev/null @@ -1,111 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "cryptonight.h" -#include "cryptonight_aesni.h" -#include "crypto/c_keccak.h" - - -void cryptonight_av2_aesni_double(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - keccak((const uint8_t *) input + size, size, ctx->state1, 200); - - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEMORY; - uint64_t* h0 = (uint64_t*) ctx->state0; - uint64_t* h1 = (uint64_t*) ctx->state1; - - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t al1 = h1[0] ^ h1[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - uint64_t ah1 = h1[1] ^ h1[5]; - - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - uint64_t idx1 = h1[0] ^ h1[4]; - - for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & 0x1FFFF0]); - __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & 0x1FFFF0]); - - cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); - cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); - - _mm_store_si128((__m128i *) &l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & 0x1FFFF0], _mm_xor_si128(bx1, cx1)); - - idx0 = EXTRACT64(cx0); - idx1 = EXTRACT64(cx1); - - bx0 = cx0; - bx1 = cx1; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0]; - ch = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0] = al0; - ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - - cl = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[0]; - ch = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[1]; - lo = _umul128(idx1, cl, &hi); - - al1 += hi; - ah1 += lo; - - ((uint64_t*) &l1[idx1 & 0x1FFFF0])[0] = al1; - ((uint64_t*) &l1[idx1 & 0x1FFFF0])[1] = ah1; - - ah1 ^= ch; - al1 ^= cl; - idx1 = al1; - } - - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); - - keccakf(h0, 24); - keccakf(h1, 24); - - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, (char*) output + 32); -} diff --git a/algo/cryptonight/cryptonight_av3_softaes.c b/algo/cryptonight/cryptonight_av3_softaes.c deleted file mode 100644 index 22be894d..00000000 --- a/algo/cryptonight/cryptonight_av3_softaes.c +++ /dev/null @@ -1,77 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "cryptonight.h" -#include "cryptonight_softaes.h" -#include "crypto/c_keccak.h" - - -void cryptonight_av3_softaes(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); - - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = (uint64_t*) ctx->state0; - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - - for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i cx; - cx = _mm_load_si128((__m128i *)&l0[idx0 & 0x1FFFF0]); - cx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0)); - - _mm_store_si128((__m128i *)&l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx)); - idx0 = EXTRACT64(cx); - bx0 = cx; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0]; - ch = ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*)&l0[idx0 & 0x1FFFF0])[0] = al0; - ((uint64_t*)&l0[idx0 & 0x1FFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - } - - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); - - keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); -} diff --git a/algo/cryptonight/cryptonight_av4_softaes_double.c b/algo/cryptonight/cryptonight_av4_softaes_double.c deleted file mode 100644 index afd4bebe..00000000 --- a/algo/cryptonight/cryptonight_av4_softaes_double.c +++ /dev/null @@ -1,111 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "cryptonight.h" -#include "cryptonight_softaes.h" -#include "crypto/c_keccak.h" - - -void cryptonight_av4_softaes_double(const void *restrict input, size_t size, void *restrict output, struct cryptonight_ctx *restrict ctx) -{ - keccak((const uint8_t *) input, size, ctx->state0, 200); - keccak((const uint8_t *) input + size, size, ctx->state1, 200); - - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEMORY; - uint64_t* h0 = (uint64_t*) ctx->state0; - uint64_t* h1 = (uint64_t*) ctx->state1; - - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); - - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t al1 = h1[0] ^ h1[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - uint64_t ah1 = h1[1] ^ h1[5]; - - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - - uint64_t idx0 = h0[0] ^ h0[4]; - uint64_t idx1 = h1[0] ^ h1[4]; - - for (size_t i = 0; __builtin_expect(i < 0x80000, 1); i++) { - __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & 0x1FFFF0]); - __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & 0x1FFFF0]); - - cx0 = soft_aesenc(cx0, _mm_set_epi64x(ah0, al0)); - cx1 = soft_aesenc(cx1, _mm_set_epi64x(ah1, al1)); - - _mm_store_si128((__m128i *) &l0[idx0 & 0x1FFFF0], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & 0x1FFFF0], _mm_xor_si128(bx1, cx1)); - - idx0 = EXTRACT64(cx0); - idx1 = EXTRACT64(cx1); - - bx0 = cx0; - bx1 = cx1; - - uint64_t hi, lo, cl, ch; - cl = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0]; - ch = ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1]; - lo = _umul128(idx0, cl, &hi); - - al0 += hi; - ah0 += lo; - - ((uint64_t*) &l0[idx0 & 0x1FFFF0])[0] = al0; - ((uint64_t*) &l0[idx0 & 0x1FFFF0])[1] = ah0; - - ah0 ^= ch; - al0 ^= cl; - idx0 = al0; - - cl = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[0]; - ch = ((uint64_t*) &l1[idx1 & 0x1FFFF0])[1]; - lo = _umul128(idx1, cl, &hi); - - al1 += hi; - ah1 += lo; - - ((uint64_t*) &l1[idx1 & 0x1FFFF0])[0] = al1; - ((uint64_t*) &l1[idx1 & 0x1FFFF0])[1] = ah1; - - ah1 ^= ch; - al1 ^= cl; - idx1 = al1; - } - - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); - - keccakf(h0, 24); - keccakf(h1, 24); - - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, (char*) output + 32); -} diff --git a/algo/cryptonight/cryptonight_softaes.h b/algo/cryptonight/cryptonight_softaes.h deleted file mode 100644 index f12ab8c6..00000000 --- a/algo/cryptonight/cryptonight_softaes.h +++ /dev/null @@ -1,237 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017 fireice-uk - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __CRYPTONIGHT_SOFTAES_H__ -#define __CRYPTONIGHT_SOFTAES_H__ - -#include - -extern __m128i soft_aesenc(__m128i in, __m128i key); -extern __m128i soft_aeskeygenassist(__m128i key, uint8_t rcon); - - -// This will shift and xor tmp1 into itself as 4 32-bit vals such as -// sl_xor(a1 a2 a3 a4) = a1 (a2^a1) (a3^a2^a1) (a4^a3^a2^a1) -static inline __m128i sl_xor(__m128i tmp1) -{ - __m128i tmp4; - tmp4 = _mm_slli_si128(tmp1, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - tmp4 = _mm_slli_si128(tmp4, 0x04); - tmp1 = _mm_xor_si128(tmp1, tmp4); - return tmp1; -} - - -static inline void aes_genkey_sub(__m128i* xout0, __m128i* xout2, uint8_t rcon) -{ - __m128i xout1 = soft_aeskeygenassist(*xout2, rcon); - xout1 = _mm_shuffle_epi32(xout1, 0xFF); // see PSHUFD, set all elems to 4th elem - *xout0 = sl_xor(*xout0); - *xout0 = _mm_xor_si128(*xout0, xout1); - xout1 = soft_aeskeygenassist(*xout0, 0x00); - xout1 = _mm_shuffle_epi32(xout1, 0xAA); // see PSHUFD, set all elems to 3rd elem - *xout2 = sl_xor(*xout2); - *xout2 = _mm_xor_si128(*xout2, xout1); -} - - -static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, __m128i* x3, __m128i* x4, __m128i* x5, __m128i* x6, __m128i* x7) -{ - *x0 = soft_aesenc(*x0, key); - *x1 = soft_aesenc(*x1, key); - *x2 = soft_aesenc(*x2, key); - *x3 = soft_aesenc(*x3, key); - *x4 = soft_aesenc(*x4, key); - *x5 = soft_aesenc(*x5, key); - *x6 = soft_aesenc(*x6, key); - *x7 = soft_aesenc(*x7, key); -} - - -static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, __m128i* k2, __m128i* k3, __m128i* k4, __m128i* k5, __m128i* k6, __m128i* k7, __m128i* k8, __m128i* k9) -{ - __m128i xout0 = _mm_load_si128(memory); - __m128i xout2 = _mm_load_si128(memory + 1); - *k0 = xout0; - *k1 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x1); - *k2 = xout0; - *k3 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x2); - *k4 = xout0; - *k5 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x4); - *k6 = xout0; - *k7 = xout2; - - aes_genkey_sub(&xout0, &xout2, 0x8); - *k8 = xout0; - *k9 = xout2; -} - - -static inline void cn_explode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(input, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xin0 = _mm_load_si128(input + 4); - xin1 = _mm_load_si128(input + 5); - xin2 = _mm_load_si128(input + 6); - xin3 = _mm_load_si128(input + 7); - xin4 = _mm_load_si128(input + 8); - xin5 = _mm_load_si128(input + 9); - xin6 = _mm_load_si128(input + 10); - xin7 = _mm_load_si128(input + 11); - - for (size_t i = 0; i < MEMORY / sizeof(__m128i); i += 8) { - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - _mm_store_si128(output + i + 0, xin0); - _mm_store_si128(output + i + 1, xin1); - _mm_store_si128(output + i + 2, xin2); - _mm_store_si128(output + i + 3, xin3); - _mm_store_si128(output + i + 4, xin4); - _mm_store_si128(output + i + 5, xin5); - _mm_store_si128(output + i + 6, xin6); - _mm_store_si128(output + i + 7, xin7); - } -} - - -static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output) -{ - // This is more than we have registers, compiler will assign 2 keys on the stack - __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; - __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; - - aes_genkey(output + 2, &k0, &k1, &k2, &k3, &k4, &k5, &k6, &k7, &k8, &k9); - - xout0 = _mm_load_si128(output + 4); - xout1 = _mm_load_si128(output + 5); - xout2 = _mm_load_si128(output + 6); - xout3 = _mm_load_si128(output + 7); - xout4 = _mm_load_si128(output + 8); - xout5 = _mm_load_si128(output + 9); - xout6 = _mm_load_si128(output + 10); - xout7 = _mm_load_si128(output + 11); - - for (size_t i = 0; __builtin_expect(i < MEMORY / sizeof(__m128i), 1); i += 8) - { - xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); - xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); - xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); - xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); - xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); - xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); - xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); - xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - - _mm_store_si128(output + 4, xout0); - _mm_store_si128(output + 5, xout1); - _mm_store_si128(output + 6, xout2); - _mm_store_si128(output + 7, xout3); - _mm_store_si128(output + 8, xout4); - _mm_store_si128(output + 9, xout5); - _mm_store_si128(output + 10, xout6); - _mm_store_si128(output + 11, xout7); -} - - -#if defined(__x86_64__) -# define EXTRACT64(X) _mm_cvtsi128_si64(X) - -static inline uint64_t _umul128(uint64_t a, uint64_t b, uint64_t* hi) -{ - unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; - *hi = r >> 64; - return (uint64_t) r; -} -#elif defined(__i386__) -# define HI32(X) \ - _mm_srli_si128((X), 4) - - -# define EXTRACT64(X) \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(X) | \ - ((uint64_t)(uint32_t)_mm_cvtsi128_si32(HI32(X)) << 32)) - -inline uint64_t _umul128(uint64_t multiplier, uint64_t multiplicand, uint64_t *product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = multiplier >> 32; - uint64_t b = multiplier & 0xFFFFFFFF; - uint64_t c = multiplicand >> 32; - uint64_t d = multiplicand & 0xFFFFFFFF; - - //uint64_t ac = a * c; - uint64_t ad = a * d; - //uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + (b * c); - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = (a * c) + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - - return product_lo; -} -#endif - - -#endif /* __CRYPTONIGHT_SOFTAES_H__ */ diff --git a/crypto/hash.c b/crypto/hash.c deleted file mode 100644 index f3a16f0c..00000000 --- a/crypto/hash.c +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include - -#include "hash-ops.h" -#include "c_keccak.h" - -void hash_permutation(union hash_state *state) { - keccakf((uint64_t*)state, 24); -} - -void hash_process(union hash_state *state, const uint8_t *buf, size_t count) { - keccak1600(buf, count, (uint8_t*)state); -} - -void cn_fast_hash(const void *data, size_t length, char *hash) { - union hash_state state; - hash_process(&state, data, length); - memcpy(hash, &state, HASH_SIZE); -} diff --git a/src/Options.cpp b/src/Options.cpp index 11f01d00..3cd3ac5f 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -28,10 +28,11 @@ #include "Console.h" -#include "Options.h" -#include "version.h" +#include "Cpu.h" #include "donate.h" #include "net/Url.h" +#include "Options.h" +#include "version.h" #ifndef ARRAY_SIZE @@ -198,9 +199,9 @@ Options::~Options() bool Options::parseArg(int key, char *arg) { -// char *p; + char *p; int v; -// uint64_t ul; + uint64_t ul; Url *url; switch (key) { @@ -243,7 +244,7 @@ bool Options::parseArg(int key, char *arg) break; case 'r': /* --retries */ - v = atoi(arg); + v = strtol(arg, nullptr, 10); if (v < 1 || v > 1000) { showUsage(1); return false; @@ -253,7 +254,7 @@ bool Options::parseArg(int key, char *arg) break; case 'R': /* --retry-pause */ - v = atoi(arg); + v = strtol(arg, nullptr, 10); if (v < 1 || v > 3600) { showUsage(1); return false; @@ -263,7 +264,7 @@ bool Options::parseArg(int key, char *arg) break; case 't': /* --threads */ - v = atoi(arg); + v = strtol(arg, nullptr, 10); if (v < 1 || v > 1024) { showUsage(1); return false; @@ -273,7 +274,7 @@ bool Options::parseArg(int key, char *arg) break; case 1004: /* --max-cpu-usage */ - v = atoi(arg); + v = strtol(arg, nullptr, 10); if (v < 1 || v > 100) { showUsage(1); return false; @@ -304,7 +305,7 @@ bool Options::parseArg(int key, char *arg) break; case 'v': /* --av */ - v = atoi(arg); + v = strtol(arg, nullptr, 10); if (v < 0 || v > 1000) { showUsage(1); return false; @@ -314,13 +315,13 @@ bool Options::parseArg(int key, char *arg) break; case 1020: /* --cpu-affinity */ -// p = strstr(arg, "0x"); -// ul = p ? strtoul(p, NULL, 16) : atol(arg); -// if (ul > (1UL << cpu_info.total_logical_cpus) -1) { -// ul = -1; -// } + p = strstr(arg, "0x"); + ul = p ? strtoul(p, NULL, 16) : atol(arg); + if (ul > (1UL << Cpu::threads()) -1) { + ul = -1; + } -// opt_affinity = ul; + m_affinity = ul; break; case 1002: /* --no-color */ @@ -328,7 +329,7 @@ bool Options::parseArg(int key, char *arg) break; case 1003: /* --donate-level */ - v = atoi(arg); + v = strtol(arg, nullptr, 10); if (v < 1 || v > 99) { showUsage(1); return false; diff --git a/src/Options.h b/src/Options.h index cbad99fa..e9f4a743 100644 --- a/src/Options.h +++ b/src/Options.h @@ -55,6 +55,7 @@ public: inline bool doubleHash() const { return m_doubleHash; } inline bool isReady() const { return m_ready; } inline bool keepAlive() const { return m_keepAlive; } + inline bool nicehash() const { return m_nicehash; } inline const char *pass() const { return m_pass; } inline const char *user() const { return m_user; } inline const Url *backupUrl() const { return m_backupUrl; } @@ -64,6 +65,8 @@ public: inline int donateLevel() const { return m_donateLevel; } inline int retries() const { return m_retries; } inline int retryPause() const { return m_retryPause; } + inline int threads() const { return m_threads; } + inline int64_t affinity() const { return m_affinity; } const char *algoName() const; diff --git a/src/Summary.cpp b/src/Summary.cpp index 38f1b1c5..b7e97a0f 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -34,7 +34,7 @@ static void print_versions() { - char *buf = static_cast(malloc(16)); + char *buf = static_cast(alloca(16)); # ifdef __GNUC__ snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); @@ -48,8 +48,6 @@ static void print_versions() } else { Console::i()->text(" * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf); } - - free(buf); } @@ -74,10 +72,40 @@ static void print_cpu() } +static void print_threads() +{ + char *buf = static_cast(alloca(32)); + if (Options::i()->affinity() != -1L) { + snprintf(buf, 32, ", affinity=0x%llX", Options::i()->affinity()); + } + else { + buf[0] = '\0'; + } + + if (Options::i()->colors()) { + Console::i()->text("\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s", + Options::i()->threads(), + Options::i()->algoName(), + Options::i()->algoVariant(), + Options::i()->donateLevel(), + Options::i()->nicehash() ? ", nicehash" : "", buf); + } + else { + Console::i()->text(" * THREADS: %d, %s, av=%d, donate=%d%%%s%s", + Options::i()->threads(), + Options::i()->algoName(), + Options::i()->algoVariant(), + Options::i()->donateLevel(), + Options::i()->nicehash() ? ", nicehash" : "", buf); + } +} + + void Summary::print() { print_versions(); print_cpu(); + print_threads(); } From ef3af1c4fdfe4402c46b4439b04161c5f335b198 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 9 Jun 2017 03:37:56 +0300 Subject: [PATCH 20/92] Restore autoconf. --- src/Options.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/Options.h | 5 +++++ 2 files changed, 52 insertions(+) diff --git a/src/Options.cpp b/src/Options.cpp index 3cd3ac5f..a2702a65 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -179,10 +179,21 @@ Options::Options(int argc, char **argv) : m_pass = strdup("x"); } + m_algoVariant = getAlgoVariant(); if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) { m_doubleHash = true; } + if (!m_threads) { + m_threads = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); + } + else if (m_safe) { + const int count = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); + if (m_threads > count) { + m_threads = count; + } + } + m_ready = true; } @@ -442,3 +453,39 @@ bool Options::setUserpass(const char *userpass) return true; } + + +int Options::getAlgoVariant() const +{ +# ifndef XMRIG_NO_AEON + if (m_algo == ALGO_CRYPTONIGHT_LITE) { + return getAlgoVariantLite(); + } +# endif + + if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { + return Cpu::hasAES() ? AV1_AESNI : AV3_SOFT_AES; + } + + if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { + return m_algoVariant + 2; + } + + return m_algoVariant; +} + + +#ifndef XMRIG_NO_AEON +int Options::getAlgoVariantLite() const +{ + if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { + return Cpu::hasAES() ? AV2_AESNI_DOUBLE : AV4_SOFT_AES_DOUBLE; + } + + if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { + return m_algoVariant + 2; + } + + return m_algoVariant; +} +#endif diff --git a/src/Options.h b/src/Options.h index e9f4a743..4955a7f3 100644 --- a/src/Options.h +++ b/src/Options.h @@ -84,6 +84,11 @@ private: bool setAlgo(const char *algo); bool setUserpass(const char *userpass); + int getAlgoVariant() const; +# ifndef XMRIG_NO_AEON + int getAlgoVariantLite() const; +# endif + bool m_background; bool m_colors; bool m_doubleHash; From 30642881bf8c6698a4e0773b12627283f4d1197f Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 9 Jun 2017 15:09:21 +0300 Subject: [PATCH 21/92] Add Mem class. --- CMakeLists.txt | 9 +++-- src/App.cpp | 2 ++ src/Mem.cpp | 28 ++++++++++++++++ src/Mem.h | 51 +++++++++++++++++++++++++++++ win/memory_win.c => src/Mem_win.cpp | 44 +++++++++++-------------- 5 files changed, 107 insertions(+), 27 deletions(-) create mode 100644 src/Mem.cpp create mode 100644 src/Mem.h rename win/memory_win.c => src/Mem_win.cpp (79%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f34e234..9d43b639 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,14 +6,15 @@ option(WITH_AEON "CryptoNight-Lite support" ON) set(HEADERS src/App.h + src/Console.h + src/Cpu.h src/interfaces/IClientListener.h + src/Mem.h src/net/Client.h src/net/Job.h src/net/Network.h src/net/Url.h src/Options.h - src/Console.h - src/Cpu.h src/Summary.h src/version.h ) @@ -34,12 +35,13 @@ set(HEADERS_CRYPTO set(SOURCES src/App.cpp + src/Console.cpp + src/Mem.cpp src/net/Client.cpp src/net/Job.cpp src/net/Network.cpp src/net/Url.cpp src/Options.cpp - src/Console.cpp src/Summary.cpp src/xmrig.cpp ) @@ -61,6 +63,7 @@ if (WIN32) src/3rdparty/winansi.cpp src/3rdparty/winansi.h src/Cpu_win.cpp + src/Mem_win.cpp src/net/Network_win.cpp ) diff --git a/src/App.cpp b/src/App.cpp index 6608554c..b6a0720a 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -29,6 +29,7 @@ #include "Console.h" #include "Cpu.h" #include "crypto/CryptoNight.h" +#include "Mem.h" #include "net/Client.h" #include "net/Network.h" #include "Options.h" @@ -67,6 +68,7 @@ App::exec() return 1; } + Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); m_network->connect(); diff --git a/src/Mem.cpp b/src/Mem.cpp new file mode 100644 index 00000000..b7bf2511 --- /dev/null +++ b/src/Mem.cpp @@ -0,0 +1,28 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "Mem.h" + + +uint8_t *Mem::m_memory = nullptr; +int Mem::m_flags = 0; diff --git a/src/Mem.h b/src/Mem.h new file mode 100644 index 00000000..d3841735 --- /dev/null +++ b/src/Mem.h @@ -0,0 +1,51 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __MEM_H__ +#define __MEM_H__ + + +#include "crypto/CryptoNight.h" + + +class Mem +{ +public: + enum Flags { + HUGEPAGES_AVAILABLE = 1, + HUGEPAGES_ENABLED = 2, + LOCK = 4 + }; + + static bool allocate(int algo, int threads, bool doubleHash); + static void release(); + + static inline int flags() { return m_flags; } + +private: + static uint8_t *m_memory __attribute__((aligned(16))); + static int m_flags; +}; + + +#endif /* __MEM_H__ */ diff --git a/win/memory_win.c b/src/Mem_win.cpp similarity index 79% rename from win/memory_win.c rename to src/Mem_win.cpp index 9ff63dad..bab483bb 100644 --- a/win/memory_win.c +++ b/src/Mem_win.cpp @@ -21,20 +21,16 @@ * along with this program. If not, see . */ -#ifndef __MEMORY_H__ -#define __MEMORY_H__ +#include #include #include #include -#include "options.h" -#include "persistent_memory.h" -#include "utils/applog.h" - -char *persistent_memory; -int persistent_memory_flags = 0; +#include "Mem.h" +#include "Console.h" +#include "Options.h" /***************************************************************** @@ -122,7 +118,7 @@ static BOOL ObtainLockPagesPrivilege() { LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME)); if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) { - applog_notime(LOG_WARNING, "Huge pages support was successfully enabled, but reboot required to use it"); + LOG_DEBUG("Huge pages support was successfully enabled, but reboot required to use it"); result = TRUE; } @@ -143,33 +139,33 @@ static BOOL TrySetLockPagesPrivilege() { } -const char * persistent_memory_allocate() { - const int ratio = (opt_double_hash && opt_algo != ALGO_CRYPTONIGHT_LITE) ? 2 : 1; - const int size = MEMORY * (opt_n_threads * ratio + 1); +bool Mem::allocate(int algo, int threads, bool doubleHash) +{ + const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; + const size_t size = MEMORY * (threads * ratio + 1); if (TrySetLockPagesPrivilege()) { - persistent_memory_flags |= MEMORY_HUGEPAGES_AVAILABLE; + m_flags |= HUGEPAGES_AVAILABLE; } - persistent_memory = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE); - if (!persistent_memory) { - persistent_memory = _mm_malloc(size, 16); + m_memory = static_cast(VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE)); + if (!m_memory) { + m_memory = static_cast(_mm_malloc(size, 16)); } else { - persistent_memory_flags |= MEMORY_HUGEPAGES_ENABLED; + m_flags |= HUGEPAGES_ENABLED; } - return persistent_memory; + return true; } -void persistent_memory_free() { - if (persistent_memory_flags & MEMORY_HUGEPAGES_ENABLED) { - VirtualFree(persistent_memory, 0, MEM_RELEASE); +void Mem::release() +{ + if (m_flags & HUGEPAGES_ENABLED) { + VirtualFree(m_memory, 0, MEM_RELEASE); } else { - _mm_free(persistent_memory); + _mm_free(m_memory); } } - -#endif /* __MEMORY_H__ */ From c5fbc1a182637f508b72468d3bf7b93fd79c61ed Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 10 Jun 2017 00:43:23 +0300 Subject: [PATCH 22/92] Restore persistent memory. --- CMakeLists.txt | 2 +- src/Mem.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++- src/Mem.h | 17 ++++++++++++-- src/Mem_unix.cpp | 26 +++++++++++++++++++++ src/Mem_win.cpp | 4 +++- 5 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 src/Mem_unix.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d43b639..2442a75a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ if (WIN32) set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) else() - set(SOURCES_OS src/Cpu_unix.cpp) + set(SOURCES_OS src/Cpu_unix.cpp src/Mem_unix.cpp) set(EXTRA_LIBS pthread) endif() diff --git a/src/Mem.cpp b/src/Mem.cpp index b7bf2511..f9554052 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -21,8 +21,67 @@ * along with this program. If not, see . */ + +#include + + +#include "crypto/CryptoNight.h" #include "Mem.h" +#include "Options.h" +bool Mem::m_doubleHash = false; +int Mem::m_algo = 0; +int Mem::m_flags = 0; +int Mem::m_threads = 0; +size_t Mem::m_offset = 0; uint8_t *Mem::m_memory = nullptr; -int Mem::m_flags = 0; + + +cryptonight_ctx *Mem::create(int algo, int threadId, bool doubleHash) +{ +# ifndef XMRIG_NO_AEON + if (algo == Options::ALGO_CRYPTONIGHT_LITE) { + return createLite(threadId, doubleHash); + } +# endif + + cryptonight_ctx *ctx = reinterpret_cast(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); + + const int ratio = doubleHash ? 2 : 1; + ctx->memory = &m_memory[MEMORY * (threadId * ratio + 1)]; + + return ctx; +} + + + +void *Mem::calloc(size_t num, size_t size) +{ + void *mem = &m_memory[m_offset]; + m_offset += (num * size); + + memset(mem, 0, num * size); + + return mem; +} + + +#ifndef XMRIG_NO_AEON +cryptonight_ctx *Mem::createLite(int threadId, bool doubleHash) { + cryptonight_ctx *ctx; + + if (!doubleHash) { + const size_t offset = MEMORY * (threadId + 1); + + ctx = reinterpret_cast(&m_memory[offset + MEMORY_LITE]); + ctx->memory = &m_memory[offset]; + return ctx; + } + + ctx = reinterpret_cast(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); + ctx->memory = &m_memory[MEMORY * (threadId + 1)]; + + return ctx; +} +#endif diff --git a/src/Mem.h b/src/Mem.h index d3841735..21a9f0f9 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -25,7 +25,10 @@ #define __MEM_H__ -#include "crypto/CryptoNight.h" +#include + + +struct cryptonight_ctx; class Mem @@ -38,13 +41,23 @@ public: }; static bool allocate(int algo, int threads, bool doubleHash); + static cryptonight_ctx *create(int algo, int threadId, bool doubleHash); + static void *calloc(size_t num, size_t size); static void release(); static inline int flags() { return m_flags; } private: - static uint8_t *m_memory __attribute__((aligned(16))); + static bool m_doubleHash; + static int m_algo; static int m_flags; + static int m_threads; + static size_t m_offset; + static uint8_t *m_memory __attribute__((aligned(16))); + +# ifndef XMRIG_NO_AEON + static cryptonight_ctx *createLite(int threadId, bool doubleHash); +# endif }; diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp new file mode 100644 index 00000000..a0690e79 --- /dev/null +++ b/src/Mem_unix.cpp @@ -0,0 +1,26 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/CryptoNight.h" +#include "Mem.h" diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index bab483bb..42114eaf 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -26,10 +26,12 @@ #include #include #include +#include -#include "Mem.h" #include "Console.h" +#include "crypto/CryptoNight.h" +#include "Mem.h" #include "Options.h" From b772349f698f02f02cdc4eff7cd7ef899dd74d64 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 10 Jun 2017 01:20:54 +0300 Subject: [PATCH 23/92] Add memory summary. --- mac/cpu_mac.c | 47 ---- mac/memory_mac.c | 76 ------- mac/xmrig_mac.c | 91 -------- memory.c | 76 ------- options.c | 520 -------------------------------------------- options.h | 91 -------- persistent_memory.h | 50 ----- src/Mem.h | 10 +- src/Mem_win.cpp | 6 +- src/Summary.cpp | 14 ++ unix/memory_unix.c | 76 ------- unix/xmrig_unix.c | 91 -------- win/xmrig_win.c | 84 ------- 13 files changed, 23 insertions(+), 1209 deletions(-) delete mode 100644 mac/cpu_mac.c delete mode 100644 mac/memory_mac.c delete mode 100644 mac/xmrig_mac.c delete mode 100644 memory.c delete mode 100644 options.c delete mode 100644 options.h delete mode 100644 persistent_memory.h delete mode 100644 unix/memory_unix.c delete mode 100644 unix/xmrig_unix.c delete mode 100644 win/xmrig_win.c diff --git a/mac/cpu_mac.c b/mac/cpu_mac.c deleted file mode 100644 index 88bda541..00000000 --- a/mac/cpu_mac.c +++ /dev/null @@ -1,47 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "cpu.h" - - -struct cpu_info cpu_info = { 0 }; -void cpu_init_common(); - - -void cpu_init() { -# ifdef XMRIG_NO_LIBCPUID - cpu_info.total_logical_cpus = sysconf(_SC_NPROCESSORS_CONF); -# endif - - cpu_init_common(); -} - - -int affine_to_cpu_mask(int id, unsigned long mask) -{ - return 0; -} diff --git a/mac/memory_mac.c b/mac/memory_mac.c deleted file mode 100644 index 3f5f714c..00000000 --- a/mac/memory_mac.c +++ /dev/null @@ -1,76 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "persistent_memory.h" -#include "options.h" -#include "utils/applog.h" - -char *persistent_memory; -int persistent_memory_flags = 0; - - -const char * persistent_memory_allocate() { - const int ratio = (opt_double_hash && opt_algo != ALGO_CRYPTONIGHT_LITE) ? 2 : 1; - const int size = MEMORY * (opt_n_threads * ratio + 1); - persistent_memory_flags |= MEMORY_HUGEPAGES_AVAILABLE; - - persistent_memory = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0); - - if (persistent_memory == MAP_FAILED) { - persistent_memory = _mm_malloc(size, 16); - return persistent_memory; - } - - persistent_memory_flags |= MEMORY_HUGEPAGES_ENABLED; - - if (madvise(persistent_memory, size, MADV_RANDOM | MADV_WILLNEED) != 0) { - applog(LOG_ERR, "madvise failed"); - } - - if (mlock(persistent_memory, size) == 0) { - persistent_memory_flags |= MEMORY_LOCK; - } - - return persistent_memory; -} - - -void persistent_memory_free() { - const int size = MEMORY * (opt_n_threads + 1); - - if (persistent_memory_flags & MEMORY_HUGEPAGES_ENABLED) { - if (persistent_memory_flags & MEMORY_LOCK) { - munlock(persistent_memory, size); - } - - munmap(persistent_memory, size); - } - else { - _mm_free(persistent_memory); - } -} diff --git a/mac/xmrig_mac.c b/mac/xmrig_mac.c deleted file mode 100644 index f7278c6d..00000000 --- a/mac/xmrig_mac.c +++ /dev/null @@ -1,91 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "options.h" -#include "cpu.h" -#include "utils/applog.h" - - -static void signal_handler(int sig) -{ - switch (sig) { - case SIGHUP: - applog(LOG_WARNING, "SIGHUP received"); - break; - - case SIGINT: - applog(LOG_WARNING, "SIGINT received, exiting"); - proper_exit(0); - break; - - case SIGTERM: - applog(LOG_WARNING, "SIGTERM received, exiting"); - proper_exit(0); - break; - } -} - - -void proper_exit(int reason) { - exit(reason); -} - - -void os_specific_init() -{ - if (opt_affinity != -1) { - affine_to_cpu_mask(-1, opt_affinity); - } - - if (opt_background) { - int i = fork(); - if (i < 0) { - exit(1); - } - - if (i > 0) { - exit(0); - } - - i = setsid(); - - if (i < 0) { - applog(LOG_ERR, "setsid() failed (errno = %d)", errno); - } - - i = chdir("/"); - if (i < 0) { - applog(LOG_ERR, "chdir() failed (errno = %d)", errno); - } - - signal(SIGHUP, signal_handler); - signal(SIGTERM, signal_handler); - } - - signal(SIGINT, signal_handler); -} diff --git a/memory.c b/memory.c deleted file mode 100644 index 112f1115..00000000 --- a/memory.c +++ /dev/null @@ -1,76 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "persistent_memory.h" -#include "algo/cryptonight/cryptonight.h" -#include "options.h" - -static size_t offset = 0; - - -#ifndef XMRIG_NO_AEON -static void * create_persistent_ctx_lite(int thr_id) { - struct cryptonight_ctx *ctx = NULL; - - if (!opt_double_hash) { - const size_t offset = MEMORY * (thr_id + 1); - - ctx = (struct cryptonight_ctx *) &persistent_memory[offset + MEMORY_LITE]; - ctx->memory = (uint8_t*) &persistent_memory[offset]; - return ctx; - } - - ctx = (struct cryptonight_ctx *) &persistent_memory[MEMORY - sizeof(struct cryptonight_ctx) * (thr_id + 1)]; - ctx->memory = (uint8_t*) &persistent_memory[MEMORY * (thr_id + 1)]; - - return ctx; -} -#endif - - -void * persistent_calloc(size_t num, size_t size) { - void *mem = &persistent_memory[offset]; - offset += (num * size); - - memset(mem, 0, num * size); - - return mem; -} - - -void * create_persistent_ctx(int thr_id) { -# ifndef XMRIG_NO_AEON - if (opt_algo == ALGO_CRYPTONIGHT_LITE) { - return create_persistent_ctx_lite(thr_id); - } -# endif - - struct cryptonight_ctx *ctx = (struct cryptonight_ctx *) &persistent_memory[MEMORY - sizeof(struct cryptonight_ctx) * (thr_id + 1)]; - - const int ratio = opt_double_hash ? 2 : 1; - ctx->memory = (uint8_t*) &persistent_memory[MEMORY * (thr_id * ratio + 1)]; - - return ctx; -} diff --git a/options.c b/options.c deleted file mode 100644 index eb88bcb0..00000000 --- a/options.c +++ /dev/null @@ -1,520 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "version.h" -#include "utils/applog.h" -#include "options.h" -#include "cpu.h" -#include "donate.h" -#include "algo/cryptonight/cryptonight.h" - - -int64_t opt_affinity = -1L; -int opt_n_threads = 0; -int opt_algo_variant = 0; -int opt_retries = 5; -int opt_retry_pause = 5; -int opt_donate_level = DONATE_LEVEL; -int opt_max_cpu_usage = 75; -bool opt_colors = true; -bool opt_keepalive = false; -bool opt_background = false; -bool opt_double_hash = false; -bool opt_safe = false; -bool opt_nicehash = false; -char *opt_url = NULL; -char *opt_backup_url = NULL; -char *opt_userpass = NULL; -char *opt_user = NULL; -char *opt_pass = NULL; - -enum mining_algo opt_algo = ALGO_CRYPTONIGHT; - - -static char const usage[] = "\ -Usage: " APP_ID " [OPTIONS]\n\ -Options:\n\ - -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ - -o, --url=URL URL of mining server\n\ - -b, --backup-url=URL URL of backup mining server\n\ - -O, --userpass=U:P username:password pair for mining server\n\ - -u, --user=USERNAME username for mining server\n\ - -p, --pass=PASSWORD password for mining server\n\ - -t, --threads=N number of miner threads\n\ - -v, --av=N algorithm variation, 0 auto select\n\ - -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ - -r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ - -R, --retry-pause=N time to pause between retries (default: 5)\n\ - --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ - --no-color disable colored output\n\ - --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ - -B, --background run the miner in the background\n\ - -c, --config=FILE load a JSON-format configuration file\n\ - --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ - --safe safe adjust threads and av settings for current CPU\n\ - --nicehash enable nicehash support\n\ - -h, --help display this help and exit\n\ - -V, --version output version information and exit\n\ -"; - - -static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:"; - - -static struct option const options[] = { - { "algo", 1, NULL, 'a' }, - { "av", 1, NULL, 'v' }, - { "background", 0, NULL, 'B' }, - { "backup-url", 1, NULL, 'b' }, - { "config", 1, NULL, 'c' }, - { "cpu-affinity", 1, NULL, 1020 }, - { "donate-level", 1, NULL, 1003 }, - { "help", 0, NULL, 'h' }, - { "keepalive", 0, NULL ,'k' }, - { "max-cpu-usage", 1, NULL, 1004 }, - { "nicehash", 0, NULL, 1006 }, - { "no-color", 0, NULL, 1002 }, - { "pass", 1, NULL, 'p' }, - { "retries", 1, NULL, 'r' }, - { "retry-pause", 1, NULL, 'R' }, - { "safe", 0, NULL, 1005 }, - { "threads", 1, NULL, 't' }, - { "url", 1, NULL, 'o' }, - { "user", 1, NULL, 'u' }, - { "userpass", 1, NULL, 'O' }, - { "version", 0, NULL, 'V' }, - { 0, 0, 0, 0 } -}; - - -static const char *algo_names[] = { - [ALGO_CRYPTONIGHT] = "cryptonight", -# ifndef XMRIG_NO_AEON - [ALGO_CRYPTONIGHT_LITE] = "cryptonight-lite" -# endif -}; - - -#ifndef XMRIG_NO_AEON -static int get_cryptonight_lite_variant(int variant) { - if (variant <= AEON_AV0_AUTO || variant >= AEON_AV_MAX) { - return (cpu_info.flags & CPU_FLAG_AES) ? AEON_AV2_AESNI_DOUBLE : AEON_AV4_SOFT_AES_DOUBLE; - } - - if (opt_safe && !(cpu_info.flags & CPU_FLAG_AES) && variant <= AEON_AV2_AESNI_DOUBLE) { - return variant + 2; - } - - return variant; -} -#endif - - -static int get_algo_variant(int algo, int variant) { -# ifndef XMRIG_NO_AEON - if (algo == ALGO_CRYPTONIGHT_LITE) { - return get_cryptonight_lite_variant(variant); - } -# endif - - if (variant <= XMR_AV0_AUTO || variant >= XMR_AV_MAX) { - return (cpu_info.flags & CPU_FLAG_AES) ? XMR_AV1_AESNI : XMR_AV3_SOFT_AES; - } - - if (opt_safe && !(cpu_info.flags & CPU_FLAG_AES) && variant <= XMR_AV2_AESNI_DOUBLE) { - return variant + 2; - } - - return variant; -} - - -static void parse_config(json_t *config, char *ref); -static char *parse_url(const char *arg); - - -static void parse_arg(int key, char *arg) { - char *p; - int v; - uint64_t ul; - - switch (key) - { - case 'a': - for (int i = 0; i < ARRAY_SIZE(algo_names); i++) { - if (algo_names[i] && !strcmp(arg, algo_names[i])) { - opt_algo = i; - break; - } - -# ifndef XMRIG_NO_AEON - if (i == ARRAY_SIZE(algo_names) && !strcmp(arg, "cryptonight-light")) { - opt_algo = i = ALGO_CRYPTONIGHT_LITE; - } -# endif - - if (i == ARRAY_SIZE(algo_names)) { - show_usage_and_exit(1); - } - } - break; - - case 'O': /* --userpass */ - p = strchr(arg, ':'); - if (!p) { - show_usage_and_exit(1); - } - - free(opt_userpass); - opt_userpass = strdup(arg); - free(opt_user); - opt_user = calloc(p - arg + 1, 1); - strncpy(opt_user, arg, p - arg); - free(opt_pass); - opt_pass = strdup(p + 1); - break; - - case 'o': /* --url */ - p = parse_url(arg); - if (p) { - free(opt_url); - opt_url = p; - } - break; - - case 'b': /* --backup-url */ - p = parse_url(arg); - if (p) { - free(opt_backup_url); - opt_backup_url = p; - } - break; - - case 'u': /* --user */ - free(opt_user); - opt_user = strdup(arg); - break; - - case 'p': /* --pass */ - free(opt_pass); - opt_pass = strdup(arg); - break; - - case 'r': /* --retries */ - v = atoi(arg); - if (v < 1 || v > 1000) { - show_usage_and_exit(1); - } - - opt_retries = v; - break; - - case 'R': /* --retry-pause */ - v = atoi(arg); - if (v < 1 || v > 3600) { - show_usage_and_exit(1); - } - - opt_retry_pause = v; - break; - - case 't': /* --threads */ - v = atoi(arg); - if (v < 1 || v > 1024) { - show_usage_and_exit(1); - } - - opt_n_threads = v; - break; - - case 1004: /* --max-cpu-usage */ - v = atoi(arg); - if (v < 1 || v > 100) { - show_usage_and_exit(1); - } - - opt_max_cpu_usage = v; - break; - - case 1005: /* --safe */ - opt_safe = true; - break; - - case 'k': /* --keepalive */ - opt_keepalive = true; - break; - - case 'V': /* --version */ - show_version_and_exit(); - break; - - case 'h': /* --help */ - show_usage_and_exit(0); - break; - - case 'c': { /* --config */ - json_error_t err; - json_t *config = json_load_file(arg, 0, &err); - - if (!json_is_object(config)) { - if (err.line < 0) { - applog(LOG_ERR, "%s\n", err.text); - } - else { - applog(LOG_ERR, "%s:%d: %s\n", arg, err.line, err.text); - } - } else { - parse_config(config, arg); - json_decref(config); - } - break; - } - - case 'B': /* --background */ - opt_background = true; - opt_colors = false; - break; - - case 'v': /* --av */ - v = atoi(arg); - if (v < 0 || v > 1000) { - show_usage_and_exit(1); - } - - opt_algo_variant = v; - break; - - case 1020: /* --cpu-affinity */ - p = strstr(arg, "0x"); - ul = p ? strtoul(p, NULL, 16) : atol(arg); - if (ul > (1UL << cpu_info.total_logical_cpus) -1) { - ul = -1; - } - - opt_affinity = ul; - break; - - case 1002: /* --no-color */ - opt_colors = false; - break; - - case 1003: /* --donate-level */ - v = atoi(arg); - if (v < 1 || v > 99) { - show_usage_and_exit(1); - } - - opt_donate_level = v; - break; - - case 1006: /* --nicehash */ - opt_nicehash = true; - break; - - default: - show_usage_and_exit(1); - } -} - - -static void parse_config(json_t *config, char *ref) -{ - int i; - char buf[16]; - json_t *val; - - applog(LOG_ERR, ref); - - for (i = 0; i < ARRAY_SIZE(options); i++) { - if (!options[i].name) { - break; - } - - val = json_object_get(config, options[i].name); - if (!val) { - continue; - } - - if (options[i].has_arg && json_is_string(val)) { - char *s = strdup(json_string_value(val)); - if (!s) { - break; - } - - parse_arg(options[i].val, s); - free(s); - } - else if (options[i].has_arg && json_is_integer(val)) { - sprintf(buf, "%d", (int) json_integer_value(val)); - parse_arg(options[i].val, buf); - } - else if (options[i].has_arg && json_is_real(val)) { - sprintf(buf, "%f", json_real_value(val)); - parse_arg(options[i].val, buf); - } - else if (!options[i].has_arg) { - if (json_is_true(val)) { - parse_arg(options[i].val, ""); - } - } - else { - applog(LOG_ERR, "JSON option %s invalid", options[i].name); - } - } -} - - -static char *parse_url(const char *arg) -{ - char *p = strstr(arg, "://"); - if (p) { - if (strncasecmp(arg, "stratum+tcp://", 14)) { - show_usage_and_exit(1); - } - - return strdup(arg); - } - - - if (!strlen(arg) || *arg == '/') { - show_usage_and_exit(1); - } - - char *dest = malloc(strlen(arg) + 16); - sprintf(dest, "stratum+tcp://%s", arg); - - return dest; -} - - -/** - * Parse application command line via getopt. - */ -void parse_cmdline(int argc, char *argv[]) { - opt_user = strdup("x"); - opt_pass = strdup("x"); - - int key; - - while (1) { - key = getopt_long(argc, argv, short_options, options, NULL); - if (key < 0) { - break; - } - - parse_arg(key, optarg); - } - - if (optind < argc) { - fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]); - show_usage_and_exit(1); - } - - if (!opt_url) { - applog_notime(LOG_ERR, "No pool URL supplied. Exiting.\n", argv[0]); - proper_exit(1); - } - - if (strstr(opt_url, ".nicehash.com:") != NULL) { - opt_nicehash = true; - } - - if (!opt_userpass) { - opt_userpass = malloc(strlen(opt_user) + strlen(opt_pass) + 2); - if (!opt_userpass) { - proper_exit(1); - } - - sprintf(opt_userpass, "%s:%s", opt_user, opt_pass); - } - - opt_algo_variant = get_algo_variant(opt_algo, opt_algo_variant); - - if (!cryptonight_init(opt_algo_variant)) { - applog(LOG_ERR, "Cryptonight hash self-test failed. This might be caused by bad compiler optimizations."); - proper_exit(1); - } - - if (!opt_n_threads) { - opt_n_threads = get_optimal_threads_count(opt_algo, opt_double_hash, opt_max_cpu_usage); - } - - if (opt_safe) { - const int count = get_optimal_threads_count(opt_algo, opt_double_hash, opt_max_cpu_usage); - if (opt_n_threads > count) { - opt_n_threads = count; - } - } -} - - -void show_usage_and_exit(int status) { - if (status) { - fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n"); - } - else { - printf(usage); - } - - proper_exit(status); -} - - -void show_version_and_exit(void) { - printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ - - #ifdef __GNUC__ - " with GCC"); - printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); - #endif - - printf("\n features:" - #ifdef __i386__ - " i386" - #endif - #ifdef __x86_64__ - " x86_64" - #endif - #ifdef __AES__ - " AES-NI" - #endif - "\n"); - - printf("\n%s\n", curl_version()); - #ifdef JANSSON_VERSION - printf("libjansson/%s\n", JANSSON_VERSION); - #endif - proper_exit(0); -} - - -const char* get_current_algo_name(void) { - return algo_names[opt_algo]; -} diff --git a/options.h b/options.h deleted file mode 100644 index a14aaeeb..00000000 --- a/options.h +++ /dev/null @@ -1,91 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __OPTIONS_H__ -#define __OPTIONS_H__ - -#include -#include - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -#endif - - -enum mining_algo { - ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ - ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ -}; - - -enum xmr_algo_variant { - XMR_AV0_AUTO, - XMR_AV1_AESNI, - XMR_AV2_AESNI_DOUBLE, - XMR_AV3_SOFT_AES, - XMR_AV4_SOFT_AES_DOUBLE, - XMR_AV_MAX -}; - - -#ifndef XMRIG_NO_AEON -enum aeon_algo_variant { - AEON_AV0_AUTO, - AEON_AV1_AESNI, - AEON_AV2_AESNI_DOUBLE, - AEON_AV3_SOFT_AES, - AEON_AV4_SOFT_AES_DOUBLE, - AEON_AV_MAX -}; -#endif - - -extern bool opt_colors; -extern bool opt_keepalive; -extern bool opt_background; -extern bool opt_double_hash; -extern bool opt_safe; -extern bool opt_nicehash; -extern char *opt_url; -extern char *opt_backup_url; -extern char *opt_userpass; -extern char *opt_user; -extern char *opt_pass; -extern int opt_n_threads; -extern int opt_algo_variant; -extern int opt_retry_pause; -extern int opt_retries; -extern int opt_donate_level; -extern int opt_max_cpu_usage; -extern int64_t opt_affinity; -extern enum mining_algo opt_algo; - -void parse_cmdline(int argc, char *argv[]); -void show_usage_and_exit(int status); -void show_version_and_exit(void); -const char* get_current_algo_name(void); - -extern void proper_exit(int reason); - - -#endif /* __OPTIONS_H__ */ diff --git a/persistent_memory.h b/persistent_memory.h deleted file mode 100644 index 5a6d6ca7..00000000 --- a/persistent_memory.h +++ /dev/null @@ -1,50 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __PERSISTENT_MEMORY_H__ -#define __PERSISTENT_MEMORY_H__ - -#include - - -enum memory_flags { - MEMORY_HUGEPAGES_AVAILABLE = 1, - MEMORY_HUGEPAGES_ENABLED = 2, - MEMORY_LOCK = 4 -}; - - -#define MEMORY 2097152 - - -extern char *persistent_memory; -extern int persistent_memory_flags; - - -const char * persistent_memory_allocate(); -void persistent_memory_free(); -void * persistent_calloc(size_t num, size_t size); -void * create_persistent_ctx(int thr_id); - - -#endif /* __PERSISTENT_MEMORY_H__ */ diff --git a/src/Mem.h b/src/Mem.h index 21a9f0f9..ac89c363 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -35,9 +35,9 @@ class Mem { public: enum Flags { - HUGEPAGES_AVAILABLE = 1, - HUGEPAGES_ENABLED = 2, - LOCK = 4 + HugepagesAvailable = 1, + HugepagesEnabled = 2, + Lock = 4 }; static bool allocate(int algo, int threads, bool doubleHash); @@ -45,7 +45,9 @@ public: static void *calloc(size_t num, size_t size); static void release(); - static inline int flags() { return m_flags; } + static inline bool isHugepagesAvailable() { return m_flags & HugepagesAvailable; } + static inline bool isHugepagesEnabled() { return m_flags & HugepagesEnabled; } + static inline int flags() { return m_flags; } private: static bool m_doubleHash; diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 42114eaf..18b54ba3 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -147,7 +147,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash) const size_t size = MEMORY * (threads * ratio + 1); if (TrySetLockPagesPrivilege()) { - m_flags |= HUGEPAGES_AVAILABLE; + m_flags |= HugepagesAvailable; } m_memory = static_cast(VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE)); @@ -155,7 +155,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash) m_memory = static_cast(_mm_malloc(size, 16)); } else { - m_flags |= HUGEPAGES_ENABLED; + m_flags |= HugepagesEnabled; } return true; @@ -164,7 +164,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash) void Mem::release() { - if (m_flags & HUGEPAGES_ENABLED) { + if (m_flags & HugepagesEnabled) { VirtualFree(m_memory, 0, MEM_RELEASE); } else { diff --git a/src/Summary.cpp b/src/Summary.cpp index b7e97a0f..502747c9 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -27,6 +27,7 @@ #include "Console.h" #include "Cpu.h" +#include "Mem.h" #include "Options.h" #include "Summary.h" #include "version.h" @@ -51,6 +52,18 @@ static void print_versions() } +static void print_memory() { + if (Options::i()->colors()) { + Console::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s", + Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable", + Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled"); + } + else { + Console::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled"); + } +} + + static void print_cpu() { if (Options::i()->colors()) { @@ -104,6 +117,7 @@ static void print_threads() void Summary::print() { print_versions(); + print_memory(); print_cpu(); print_threads(); } diff --git a/unix/memory_unix.c b/unix/memory_unix.c deleted file mode 100644 index 2e794a03..00000000 --- a/unix/memory_unix.c +++ /dev/null @@ -1,76 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "persistent_memory.h" -#include "options.h" -#include "utils/applog.h" - - -char *persistent_memory; -int persistent_memory_flags = 0; - - -const char * persistent_memory_allocate() { - const int ratio = (opt_double_hash && opt_algo != ALGO_CRYPTONIGHT_LITE) ? 2 : 1; - const int size = MEMORY * (opt_n_threads * ratio + 1); - persistent_memory_flags |= MEMORY_HUGEPAGES_AVAILABLE; - - persistent_memory = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0); - - if (persistent_memory == MAP_FAILED) { - persistent_memory = _mm_malloc(size, 16); - return persistent_memory; - } - - persistent_memory_flags |= MEMORY_HUGEPAGES_ENABLED; - - if (madvise(persistent_memory, size, MADV_RANDOM | MADV_WILLNEED) != 0) { - applog(LOG_ERR, "madvise failed"); - } - - if (mlock(persistent_memory, size) == 0) { - persistent_memory_flags |= MEMORY_LOCK; - } - - return persistent_memory; -} - - -void persistent_memory_free() { - const int size = MEMORY * (opt_n_threads + 1); - - if (persistent_memory_flags & MEMORY_HUGEPAGES_ENABLED) { - if (persistent_memory_flags & MEMORY_LOCK) { - munlock(persistent_memory, size); - } - - munmap(persistent_memory, size); - } - else { - _mm_free(persistent_memory); - } -} diff --git a/unix/xmrig_unix.c b/unix/xmrig_unix.c deleted file mode 100644 index cd25934a..00000000 --- a/unix/xmrig_unix.c +++ /dev/null @@ -1,91 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "options.h" -#include "cpu.h" -#include "utils/applog.h" - - -static void signal_handler(int sig) -{ - switch (sig) { - case SIGHUP: - applog(LOG_WARNING, "SIGHUP received"); - break; - - case SIGINT: - applog(LOG_WARNING, "SIGINT received, exiting"); - proper_exit(0); - break; - - case SIGTERM: - applog(LOG_WARNING, "SIGTERM received, exiting"); - proper_exit(0); - break; - } -} - - -void proper_exit(int reason) { - exit(reason); -} - - -void os_specific_init() -{ - if (opt_affinity != -1) { - affine_to_cpu_mask(-1, opt_affinity); - } - - if (opt_background) { - int i = fork(); - if (i < 0) { - exit(1); - } - - if (i > 0) { - exit(0); - } - - i = setsid(); - - if (i < 0) { - applog(LOG_ERR, "setsid() failed (errno = %d)", errno); - } - - i = chdir("/"); - if (i < 0) { - applog(LOG_ERR, "chdir() failed (errno = %d)", errno); - } - - signal(SIGHUP, signal_handler); - signal(SIGTERM, signal_handler); - } - - signal(SIGINT, signal_handler); -} diff --git a/win/xmrig_win.c b/win/xmrig_win.c deleted file mode 100644 index 96921faa..00000000 --- a/win/xmrig_win.c +++ /dev/null @@ -1,84 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "options.h" -#include "cpu.h" -#include "utils/applog.h" - - -BOOL WINAPI ConsoleHandler(DWORD dwType) -{ - switch (dwType) { - case CTRL_C_EVENT: - applog(LOG_WARNING, "CTRL_C_EVENT received, exiting"); - proper_exit(0); - break; - - case CTRL_BREAK_EVENT: - applog(LOG_WARNING, "CTRL_BREAK_EVENT received, exiting"); - proper_exit(0); - break; - - default: - return false; -} - - return true; -} - - -void proper_exit(int reason) { - if (opt_background) { - HWND hcon = GetConsoleWindow(); - if (hcon) { - // unhide parent command line windows - ShowWindow(hcon, SW_SHOWMINNOACTIVE); - } - } - - exit(reason); -} - - -void os_specific_init() -{ - if (opt_affinity != -1) { - affine_to_cpu_mask(-1, opt_affinity); - } - - SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE); - - if (opt_background) { - HWND hcon = GetConsoleWindow(); - if (hcon) { - // this method also hide parent command line window - ShowWindow(hcon, SW_HIDE); - } else { - HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); - CloseHandle(h); - FreeConsole(); - } - } -} From 29aa4660233977d8437133a981eaaf1bba5735d4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 10 Jun 2017 07:05:00 +0300 Subject: [PATCH 24/92] Add IWorker, Handle, SingleWorker, Worker classes. --- CMakeLists.txt | 11 ++++++-- src/App.cpp | 26 +++++++++++++++++++ src/App.h | 13 ++++++++-- src/Mem.cpp | 12 ++++----- src/Mem.h | 4 +-- src/Mem_win.cpp | 4 +++ src/interfaces/IWorker.h | 37 ++++++++++++++++++++++++++ src/workers/Handle.cpp | 39 ++++++++++++++++++++++++++++ src/workers/Handle.h | 50 ++++++++++++++++++++++++++++++++++++ src/workers/SingleWorker.cpp | 35 +++++++++++++++++++++++++ src/workers/SingleWorker.h | 41 +++++++++++++++++++++++++++++ src/workers/Worker.cpp | 48 ++++++++++++++++++++++++++++++++++ src/workers/Worker.h | 50 ++++++++++++++++++++++++++++++++++++ 13 files changed, 358 insertions(+), 12 deletions(-) create mode 100644 src/interfaces/IWorker.h create mode 100644 src/workers/Handle.cpp create mode 100644 src/workers/Handle.h create mode 100644 src/workers/SingleWorker.cpp create mode 100644 src/workers/SingleWorker.h create mode 100644 src/workers/Worker.cpp create mode 100644 src/workers/Worker.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2442a75a..e91fae3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(HEADERS src/Console.h src/Cpu.h src/interfaces/IClientListener.h + src/interfaces/IWorker.h src/Mem.h src/net/Client.h src/net/Job.h @@ -16,6 +17,9 @@ set(HEADERS src/net/Url.h src/Options.h src/Summary.h + src/workers/Handle.h + src/workers/SingleWorker.h + src/workers/Worker.h src/version.h ) @@ -43,6 +47,9 @@ set(SOURCES src/net/Url.cpp src/Options.cpp src/Summary.cpp + src/workers/Handle.cpp + src/workers/SingleWorker.cpp + src/workers/Worker.cpp src/xmrig.cpp ) @@ -85,11 +92,11 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -fno-exceptions") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-use -fprofile-correction") diff --git a/src/App.cpp b/src/App.cpp index b6a0720a..943690ec 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -35,6 +35,8 @@ #include "Options.h" #include "Summary.h" #include "version.h" +#include "workers/Handle.h" +#include "workers/SingleWorker.h" @@ -45,6 +47,8 @@ App::App(int argc, char **argv) m_options = Options::parse(argc, argv); m_network = new Network(m_options); + + } @@ -71,6 +75,8 @@ App::exec() Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); + startWorders(); + m_network->connect(); const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); @@ -78,3 +84,23 @@ App::exec() return r; } + + +void App::startWorders() +{ + for (int i = 0; i < m_options->threads(); ++i) { + Handle *handle = new Handle(i); + m_workers.push_back(handle); + handle->start(App::onWorkerStarted); + } +} + + +void *App::onWorkerStarted(void *arg) +{ + auto handle = static_cast(arg); + IWorker *worker = new SingleWorker(handle); + worker->start(); + + return nullptr; +} diff --git a/src/App.h b/src/App.h index a6aef6fa..25d91890 100644 --- a/src/App.h +++ b/src/App.h @@ -25,8 +25,12 @@ #define __APP_H__ -class Options; +#include + + +class Handle; class Network; +class Options; class App @@ -38,8 +42,13 @@ public: int exec(); private: - Options *m_options; + void startWorders(); + + static void* onWorkerStarted(void *arg); + Network *m_network; + Options *m_options; + std::vector m_workers; }; diff --git a/src/Mem.cpp b/src/Mem.cpp index f9554052..4437c673 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -38,17 +38,17 @@ size_t Mem::m_offset = 0; uint8_t *Mem::m_memory = nullptr; -cryptonight_ctx *Mem::create(int algo, int threadId, bool doubleHash) +cryptonight_ctx *Mem::create(int threadId) { # ifndef XMRIG_NO_AEON - if (algo == Options::ALGO_CRYPTONIGHT_LITE) { - return createLite(threadId, doubleHash); + if (m_algo == Options::ALGO_CRYPTONIGHT_LITE) { + return createLite(threadId); } # endif cryptonight_ctx *ctx = reinterpret_cast(&m_memory[MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); - const int ratio = doubleHash ? 2 : 1; + const int ratio = m_doubleHash ? 2 : 1; ctx->memory = &m_memory[MEMORY * (threadId * ratio + 1)]; return ctx; @@ -68,10 +68,10 @@ void *Mem::calloc(size_t num, size_t size) #ifndef XMRIG_NO_AEON -cryptonight_ctx *Mem::createLite(int threadId, bool doubleHash) { +cryptonight_ctx *Mem::createLite(int threadId) { cryptonight_ctx *ctx; - if (!doubleHash) { + if (!m_doubleHash) { const size_t offset = MEMORY * (threadId + 1); ctx = reinterpret_cast(&m_memory[offset + MEMORY_LITE]); diff --git a/src/Mem.h b/src/Mem.h index ac89c363..9a438a17 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -41,7 +41,7 @@ public: }; static bool allocate(int algo, int threads, bool doubleHash); - static cryptonight_ctx *create(int algo, int threadId, bool doubleHash); + static cryptonight_ctx *create(int threadId); static void *calloc(size_t num, size_t size); static void release(); @@ -58,7 +58,7 @@ private: static uint8_t *m_memory __attribute__((aligned(16))); # ifndef XMRIG_NO_AEON - static cryptonight_ctx *createLite(int threadId, bool doubleHash); + static cryptonight_ctx *createLite(int threadId); # endif }; diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 18b54ba3..f9a7ab3d 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -143,6 +143,10 @@ static BOOL TrySetLockPagesPrivilege() { bool Mem::allocate(int algo, int threads, bool doubleHash) { + m_algo = algo; + m_threads = threads; + m_doubleHash = doubleHash; + const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; const size_t size = MEMORY * (threads * ratio + 1); diff --git a/src/interfaces/IWorker.h b/src/interfaces/IWorker.h new file mode 100644 index 00000000..f9010a2f --- /dev/null +++ b/src/interfaces/IWorker.h @@ -0,0 +1,37 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __IWORKER_H__ +#define __IWORKER_H__ + + +class IWorker +{ +public: + virtual ~IWorker() {} + + virtual void start() = 0; +}; + + +#endif // __IWORKER_H__ diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp new file mode 100644 index 00000000..6c1f5553 --- /dev/null +++ b/src/workers/Handle.cpp @@ -0,0 +1,39 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "workers/Handle.h" + + +Handle::Handle(int id) : + m_id(id), + m_worker(nullptr) +{ +} + + +void Handle::start(void *(*callback) (void *)) +{ + pthread_create(&m_thread, nullptr, callback, this); +// m_thread = std::thread([]() {}); +} diff --git a/src/workers/Handle.h b/src/workers/Handle.h new file mode 100644 index 00000000..e697a618 --- /dev/null +++ b/src/workers/Handle.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __HANDLE_H__ +#define __HANDLE_H__ + + +#include + + +class IWorker; + + +class Handle +{ +public: + Handle(int id); + void start(void *(*callback) (void *)); + + inline int id() const { return m_id; } + inline void setWorker(IWorker *worker) { m_worker = worker; } + +private: + int m_id; + IWorker *m_worker; + pthread_t m_thread; +}; + + +#endif /* __HANDLE_H__ */ diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp new file mode 100644 index 00000000..d9a8f8a6 --- /dev/null +++ b/src/workers/SingleWorker.cpp @@ -0,0 +1,35 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + +#include "Console.h" +#include "workers/SingleWorker.h" + + +SingleWorker::SingleWorker(Handle *handle) + : Worker(handle) +{ + LOG_WARN("SingleWorker %d", pthread_self()); +} diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h new file mode 100644 index 00000000..830c6f39 --- /dev/null +++ b/src/workers/SingleWorker.h @@ -0,0 +1,41 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SINGLEWORKER_H__ +#define __SINGLEWORKER_H__ + + +#include "workers/Worker.h" + + +class Handle; + + +class SingleWorker : public Worker +{ +public: + SingleWorker(Handle *handle); +}; + + +#endif /* __SINGLEWORKER_H__ */ diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp new file mode 100644 index 00000000..3e42d1bd --- /dev/null +++ b/src/workers/Worker.cpp @@ -0,0 +1,48 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "workers/Handle.h" +#include "workers/Worker.h" +#include "Mem.h" + + +Worker::Worker(Handle *handle) : + m_handle(handle), + m_id(handle->id()) +{ + m_handle->setWorker(this); + + m_ctx = Mem::create(m_id); +} + + +Worker::~Worker() +{ +} + + +void Worker::start() +{ + +} diff --git a/src/workers/Worker.h b/src/workers/Worker.h new file mode 100644 index 00000000..c24fa573 --- /dev/null +++ b/src/workers/Worker.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __WORKER_H__ +#define __WORKER_H__ + + +#include "interfaces/IWorker.h" + + +struct cryptonight_ctx; +class Handle; + + +class Worker : public IWorker +{ +public: + Worker(Handle *handle); + ~Worker(); + + void start() override; + +protected: + cryptonight_ctx *m_ctx; + Handle *m_handle; + int m_id; +}; + + +#endif /* __WORKER_H__ */ From f9c244f0aa3a1cf132cfad34b1c79792d63c9162 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 10 Jun 2017 09:41:08 +0300 Subject: [PATCH 25/92] Add Workers class. --- CMakeLists.txt | 4 +- src/App.cpp | 25 +------------ src/App.h | 9 ----- src/workers/Handle.cpp | 1 - src/workers/SingleWorker.cpp | 9 +++++ src/workers/SingleWorker.h | 2 + src/workers/Worker.cpp | 6 --- src/workers/Worker.h | 2 - src/workers/Workers.cpp | 72 ++++++++++++++++++++++++++++++++++++ src/workers/Workers.h | 50 +++++++++++++++++++++++++ 10 files changed, 138 insertions(+), 42 deletions(-) create mode 100644 src/workers/Workers.cpp create mode 100644 src/workers/Workers.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e91fae3c..801b33bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set(HEADERS src/workers/Handle.h src/workers/SingleWorker.h src/workers/Worker.h + src/workers/Workers.h src/version.h ) @@ -50,6 +51,7 @@ set(SOURCES src/workers/Handle.cpp src/workers/SingleWorker.cpp src/workers/Worker.cpp + src/workers/Workers.cpp src/xmrig.cpp ) @@ -95,7 +97,7 @@ endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -fno-exceptions") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") diff --git a/src/App.cpp b/src/App.cpp index 943690ec..1a4f6d06 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -35,8 +35,7 @@ #include "Options.h" #include "Summary.h" #include "version.h" -#include "workers/Handle.h" -#include "workers/SingleWorker.h" +#include "workers/Workers.h" @@ -75,7 +74,7 @@ App::exec() Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); - startWorders(); + Workers::start(m_options->threads()); m_network->connect(); @@ -84,23 +83,3 @@ App::exec() return r; } - - -void App::startWorders() -{ - for (int i = 0; i < m_options->threads(); ++i) { - Handle *handle = new Handle(i); - m_workers.push_back(handle); - handle->start(App::onWorkerStarted); - } -} - - -void *App::onWorkerStarted(void *arg) -{ - auto handle = static_cast(arg); - IWorker *worker = new SingleWorker(handle); - worker->start(); - - return nullptr; -} diff --git a/src/App.h b/src/App.h index 25d91890..b2d5e5f0 100644 --- a/src/App.h +++ b/src/App.h @@ -25,10 +25,6 @@ #define __APP_H__ -#include - - -class Handle; class Network; class Options; @@ -42,13 +38,8 @@ public: int exec(); private: - void startWorders(); - - static void* onWorkerStarted(void *arg); - Network *m_network; Options *m_options; - std::vector m_workers; }; diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 6c1f5553..527b5d6d 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -35,5 +35,4 @@ Handle::Handle(int id) : void Handle::start(void *(*callback) (void *)) { pthread_create(&m_thread, nullptr, callback, this); -// m_thread = std::thread([]() {}); } diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index d9a8f8a6..95eb4157 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -22,10 +22,13 @@ */ +#include #include + #include "Console.h" #include "workers/SingleWorker.h" +#include "workers/Workers.h" SingleWorker::SingleWorker(Handle *handle) @@ -33,3 +36,9 @@ SingleWorker::SingleWorker(Handle *handle) { LOG_WARN("SingleWorker %d", pthread_self()); } + + +void SingleWorker::start() +{ +// Workers::submit(); +} diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h index 830c6f39..1c569d97 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/SingleWorker.h @@ -35,6 +35,8 @@ class SingleWorker : public Worker { public: SingleWorker(Handle *handle); + + void start() override; }; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 3e42d1bd..24f275e9 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -40,9 +40,3 @@ Worker::Worker(Handle *handle) : Worker::~Worker() { } - - -void Worker::start() -{ - -} diff --git a/src/workers/Worker.h b/src/workers/Worker.h index c24fa573..e68534ae 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -38,8 +38,6 @@ public: Worker(Handle *handle); ~Worker(); - void start() override; - protected: cryptonight_ctx *m_ctx; Handle *m_handle; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp new file mode 100644 index 00000000..004d49b6 --- /dev/null +++ b/src/workers/Workers.cpp @@ -0,0 +1,72 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "Console.h" +#include "workers/Handle.h" +#include "workers/SingleWorker.h" +#include "workers/Workers.h" + + +std::vector Workers::m_workers; +uv_async_t Workers::m_async; + + +void Workers::start(int threads) +{ + LOG_NOTICE("start %d", pthread_self()); + + uv_async_init(uv_default_loop(), &m_async, Workers::onResult); + + for (int i = 0; i < threads; ++i) { + Handle *handle = new Handle(i); + m_workers.push_back(handle); + handle->start(Workers::onReady); + } +} + + +void Workers::submit() +{ + uv_async_send(&m_async); +} + + + +void *Workers::onReady(void *arg) +{ + auto handle = static_cast(arg); + IWorker *worker = new SingleWorker(handle); + worker->start(); + + return nullptr; +} + + + +void Workers::onResult(uv_async_t *handle) +{ +} diff --git a/src/workers/Workers.h b/src/workers/Workers.h new file mode 100644 index 00000000..48485770 --- /dev/null +++ b/src/workers/Workers.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __WORKERS_H__ +#define __WORKERS_H__ + + +#include +#include + + +class Handle; + + +class Workers +{ +public: + static void start(int threads); + static void submit(); + +private: + static void *onReady(void *arg); + static void onResult(uv_async_t *handle); + + static std::vector m_workers; + static uv_async_t m_async; +}; + + +#endif /* __WORKERS_H__ */ From bcef4b12ec70d6c039379718d450f3e291f0b0ee Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 10 Jun 2017 13:32:27 +0300 Subject: [PATCH 26/92] Job flow. --- src/net/Client.cpp | 6 +++++- src/net/Client.h | 2 ++ src/net/Job.cpp | 3 ++- src/net/Job.h | 12 ++++++++---- src/net/Network.cpp | 27 ++++++++++++++++++++++++++- src/net/Network.h | 2 ++ src/workers/Workers.cpp | 1 - 7 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 8fdf09e9..91f582a0 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -22,6 +22,9 @@ */ +#include + + #include "Console.h" #include "interfaces/IClientListener.h" #include "net/Client.h" @@ -168,7 +171,8 @@ bool Client::parseJob(const json_t *params, int *code) return false; } - m_job = job; + job.setPoolId(m_id); + m_job = std::move(job); LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_host, m_port, job.id(), job.diff()); return true; diff --git a/src/net/Client.h b/src/net/Client.h index 6110488d..b46a8bf0 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -60,7 +60,9 @@ public: void send(char *data); void setUrl(const Url *url); + inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline const char *host() const { return m_host; } + inline const Job &job() const { return m_job; } inline int id() const { return m_id; } inline SocketState state() const { return m_state; } inline uint16_t port() const { return m_port; } diff --git a/src/net/Job.cpp b/src/net/Job.cpp index 65feabb7..52123485 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -57,7 +57,8 @@ static inline char hf_bin2hex(unsigned char c) } -Job::Job() : +Job::Job(int poolId) : + m_poolId(poolId), m_size(0), m_diff(0), m_target(0) diff --git a/src/net/Job.h b/src/net/Job.h index d213ec34..4dc18650 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -31,22 +31,26 @@ class Job { public: - Job(); + Job(int poolId = -2); bool setBlob(const char *blob); bool setId(const char *id); bool setTarget(const char *target); - inline const uint8_t *blob() const { return m_blob; } + inline bool isValid() const { return m_size > 0 && m_diff > 0; } inline const char *id() const { return m_id; } - inline uint32_t size() const { return m_size; } + inline const uint8_t *blob() const { return m_blob; } + inline int poolId() const { return m_poolId; } inline uint32_t diff() const { return m_diff; } + inline uint32_t size() const { return m_size; } inline uint64_t target() const { return m_target; } + inline void setPoolId(int poolId) { m_poolId = poolId; } static bool fromHex(const char* in, unsigned int len, unsigned char* out); static void toHex(const unsigned char* in, unsigned int len, char* out); - inline static uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } + static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } private: + int m_poolId; char m_id[64] __attribute__((aligned(16))); uint8_t m_blob[84] __attribute__((aligned(16))); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. uint32_t m_size; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index d513fdda..c6862e3b 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -35,7 +35,8 @@ Network::Network(const Options *options) : m_donate(false), m_options(options), - m_pool(0) + m_pool(0), + m_diff(0) { m_pools.reserve(2); m_agent = userAgent(); @@ -92,7 +93,11 @@ void Network::onClose(Client *client, int failures) void Network::onJobReceived(Client *client, const Job &job) { + if (m_donate && client->id() != 0) { + return; + } + setJob(client, job); } @@ -138,6 +143,18 @@ void Network::addPool(const Url *url) } +void Network::setJob(Client *client, const Job &job) +{ + if (m_options->colors()){ + LOG_INFO("\x1B[01;33mnew job\x1B[0m from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff()); + + } + else { + LOG_INFO("new job from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff()); + } +} + + void Network::startDonate() { if (m_donate) { @@ -159,6 +176,14 @@ void Network::stopDonate() LOG_NOTICE("dev donate finished"); m_donate = false; + if (!m_pool) { + return; + } + + Client *client = m_pools[m_pool]; + if (client->isReady()) { + setJob(client, client->job()); + } } diff --git a/src/net/Network.h b/src/net/Network.h index c8191a6e..af1ddbbf 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -54,6 +54,7 @@ protected: private: void addPool(const Url *url); + void setJob(Client *client, const Job &job); void startDonate(); void stopDonate(); @@ -64,6 +65,7 @@ private: const Options *m_options; int m_pool; std::vector m_pools; + uint64_t m_diff; uv_timer_t m_timer; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 004d49b6..b9dbc484 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -30,7 +30,6 @@ #include "workers/SingleWorker.h" #include "workers/Workers.h" - std::vector Workers::m_workers; uv_async_t Workers::m_async; From 3ad11685cca13791ab3daec98e2223454757b20a Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 11 Jun 2017 06:52:23 +0300 Subject: [PATCH 27/92] Job flow WIP. --- CMakeLists.txt | 2 +- src/App.cpp | 2 +- src/Console.cpp | 10 +++++----- src/Console.h | 4 ++-- src/net/Job.h | 1 + src/net/Network.cpp | 4 ++++ src/workers/Handle.cpp | 6 ++++-- src/workers/Handle.h | 11 ++++++++--- src/workers/SingleWorker.cpp | 33 +++++++++++++++++++++++++++++++- src/workers/SingleWorker.h | 6 ++++++ src/workers/Worker.cpp | 10 ++++++++-- src/workers/Worker.h | 5 +++++ src/workers/Workers.cpp | 37 ++++++++++++++++++++++++++++++------ src/workers/Workers.h | 20 +++++++++++++++++-- 14 files changed, 126 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 801b33bb..c22bf176 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,7 +84,7 @@ endif() add_definitions(/D_GNU_SOURCE) add_definitions(/DUNICODE) -add_definitions(/DAPP_DEBUG) +#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/App.cpp b/src/App.cpp index 1a4f6d06..4078f4b7 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -74,7 +74,7 @@ App::exec() Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); - Workers::start(m_options->threads()); + Workers::start(m_options->threads(), m_options->affinity(), m_options->nicehash()); m_network->connect(); diff --git a/src/Console.cpp b/src/Console.cpp index f57a7141..fd4ff4a5 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -97,12 +97,12 @@ void Console::message(Console::Level level, const char* fmt, ...) m_colors ? kCL_N : "" ); - uv_mutex_lock(&m_mutex); + pthread_mutex_lock(&m_mutex); vfprintf(stdout, buf, ap); fflush(stdout); - uv_mutex_unlock(&m_mutex); + pthread_mutex_unlock(&m_mutex); va_end(ap); } @@ -121,12 +121,12 @@ void Console::text(const char* fmt, ...) m_colors ? kCL_N : "" ); - uv_mutex_lock(&m_mutex); + pthread_mutex_lock(&m_mutex); vfprintf(stdout, buf, ap); fflush(stdout); - uv_mutex_unlock(&m_mutex); + pthread_mutex_unlock(&m_mutex); va_end(ap); } @@ -135,5 +135,5 @@ void Console::text(const char* fmt, ...) Console::Console() : m_colors(true) { - uv_mutex_init(&m_mutex); + pthread_mutex_init(&m_mutex, nullptr); } diff --git a/src/Console.h b/src/Console.h index 73e04706..edd5ae8c 100644 --- a/src/Console.h +++ b/src/Console.h @@ -25,7 +25,7 @@ #define __CONSOLE_H__ -#include +#include class Console @@ -61,7 +61,7 @@ private: static Console *m_self; bool m_colors; - uv_mutex_t m_mutex; + pthread_mutex_t m_mutex; }; diff --git a/src/net/Job.h b/src/net/Job.h index 4dc18650..4f08e84c 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -40,6 +40,7 @@ public: inline const char *id() const { return m_id; } inline const uint8_t *blob() const { return m_blob; } inline int poolId() const { return m_poolId; } + inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } inline uint32_t diff() const { return m_diff; } inline uint32_t size() const { return m_size; } inline uint64_t target() const { return m_target; } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index c6862e3b..02c68fd1 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -30,6 +30,7 @@ #include "net/Network.h" #include "net/Url.h" #include "Options.h" +#include "workers/Workers.h" Network::Network(const Options *options) : @@ -83,6 +84,7 @@ void Network::onClose(Client *client, int failures) if (m_pool == id) { m_pool = 0; + Workers::pause(); } if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { @@ -152,6 +154,8 @@ void Network::setJob(Client *client, const Job &job) else { LOG_INFO("new job from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff()); } + + Workers::setJob(job); } diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 527b5d6d..6e4d78ed 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,8 +25,10 @@ #include "workers/Handle.h" -Handle::Handle(int id) : - m_id(id), +Handle::Handle(int threadId, int64_t affinity, bool nicehash) : + m_nicehash(nicehash), + m_threadId(threadId), + m_affinity(affinity), m_worker(nullptr) { } diff --git a/src/workers/Handle.h b/src/workers/Handle.h index e697a618..59bd4793 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -26,6 +26,7 @@ #include +#include class IWorker; @@ -34,14 +35,18 @@ class IWorker; class Handle { public: - Handle(int id); + Handle(int threadId, int64_t affinity, bool nicehash); void start(void *(*callback) (void *)); - inline int id() const { return m_id; } + inline bool nicehash() const { return m_nicehash; } + inline int threadId() const { return m_threadId; } + inline int64_t affinity() const { return m_affinity; } inline void setWorker(IWorker *worker) { m_worker = worker; } private: - int m_id; + bool m_nicehash; + int m_threadId; + int64_t m_affinity; IWorker *m_worker; pthread_t m_thread; }; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 95eb4157..eacab941 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -22,6 +22,7 @@ */ +#include #include #include @@ -40,5 +41,35 @@ SingleWorker::SingleWorker(Handle *handle) void SingleWorker::start() { -// Workers::submit(); + while (true) { + if (Workers::isPaused()) { + do { + LOG_ERR("SLEEP WAIT FOR WORK"); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + while (Workers::isPaused()); + + consumeJob(); + } + + while (!Workers::isOutdated(m_sequence)) { + LOG_ERR("WORK %lld %lld", Workers::sequence(), m_sequence); + + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + + sched_yield(); + } + + consumeJob(); + } +} + + + +void SingleWorker::consumeJob() +{ + m_job = Workers::job(); + m_sequence = Workers::sequence(); + + LOG_WARN("consumeJob"); } diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h index 1c569d97..9820172c 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/SingleWorker.h @@ -25,6 +25,7 @@ #define __SINGLEWORKER_H__ +#include "net/Job.h" #include "workers/Worker.h" @@ -37,6 +38,11 @@ public: SingleWorker(Handle *handle); void start() override; + +private: + void consumeJob(); + + Job m_job; }; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 24f275e9..1756dbc1 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -22,17 +22,23 @@ */ +#include "Cpu.h" +#include "Mem.h" #include "workers/Handle.h" #include "workers/Worker.h" -#include "Mem.h" Worker::Worker(Handle *handle) : + m_nicehash(handle->nicehash()), m_handle(handle), - m_id(handle->id()) + m_id(handle->threadId()) { m_handle->setWorker(this); + if (Cpu::threads() > 1 && m_handle->affinity() != -1L) { + Cpu::setAffinity(m_id, m_handle->affinity()); + } + m_ctx = Mem::create(m_id); } diff --git a/src/workers/Worker.h b/src/workers/Worker.h index e68534ae..f62083d0 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -25,6 +25,9 @@ #define __WORKER_H__ +#include + + #include "interfaces/IWorker.h" @@ -39,9 +42,11 @@ public: ~Worker(); protected: + bool m_nicehash; cryptonight_ctx *m_ctx; Handle *m_handle; int m_id; + uint64_t m_sequence; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index b9dbc484..1916be72 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -21,27 +21,52 @@ * along with this program. If not, see . */ - -#include - - #include "Console.h" #include "workers/Handle.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" + +Job Workers::m_job; +pthread_rwlock_t Workers::m_rwlock; +std::atomic Workers::m_paused; +std::atomic Workers::m_sequence; std::vector Workers::m_workers; uv_async_t Workers::m_async; -void Workers::start(int threads) +Job Workers::job() +{ + pthread_rwlock_rdlock(&m_rwlock); + Job job = m_job; + pthread_rwlock_unlock(&m_rwlock); + + return std::move(job); +} + + +void Workers::setJob(const Job &job) +{ + pthread_rwlock_wrlock(&m_rwlock); + m_job = job; + pthread_rwlock_unlock(&m_rwlock); + + m_sequence++; + m_paused = 0; +} + + +void Workers::start(int threads, int64_t affinity, bool nicehash) { LOG_NOTICE("start %d", pthread_self()); + m_sequence = 0; + m_paused = 1; + uv_async_init(uv_default_loop(), &m_async, Workers::onResult); for (int i = 0; i < threads; ++i) { - Handle *handle = new Handle(i); + Handle *handle = new Handle(i, affinity, nicehash); m_workers.push_back(handle); handle->start(Workers::onReady); } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 48485770..7d6328ca 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -25,8 +25,13 @@ #define __WORKERS_H__ -#include +#include +#include #include +#include + + +#include "net/Job.h" class Handle; @@ -35,13 +40,24 @@ class Handle; class Workers { public: - static void start(int threads); + static Job job(); + static void setJob(const Job &job); + static void start(int threads, int64_t affinity, bool nicehash); static void submit(); + static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } + static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } + static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } + static inline void pause() { m_paused = 1; } + private: static void *onReady(void *arg); static void onResult(uv_async_t *handle); + static Job m_job; + static pthread_rwlock_t m_rwlock; + static std::atomic m_paused; + static std::atomic m_sequence; static std::vector m_workers; static uv_async_t m_async; }; From a0a8711dab60b32340f6f5bd904a1395ebc9c2cb Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 11 Jun 2017 10:58:46 +0300 Subject: [PATCH 28/92] Add class JobResult. --- CMakeLists.txt | 5 +++-- src/crypto/CryptoNight.cpp | 10 +++++++++ src/crypto/CryptoNight.h | 5 +++++ src/net/JobResult.h | 40 ++++++++++++++++++++++++++++++++++++ src/workers/Handle.cpp | 3 ++- src/workers/Handle.h | 4 +++- src/workers/SingleWorker.cpp | 21 +++++++++++++------ src/workers/SingleWorker.h | 2 ++ src/workers/Worker.cpp | 12 ++++++----- src/workers/Worker.h | 3 ++- src/workers/Workers.cpp | 22 ++++++++++++++++---- src/workers/Workers.h | 7 +++++-- 12 files changed, 112 insertions(+), 22 deletions(-) create mode 100644 src/net/JobResult.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c22bf176..15c1d35d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ set(HEADERS src/Mem.h src/net/Client.h src/net/Job.h + src/net/JobResult.h src/net/Network.h src/net/Url.h src/Options.h @@ -84,7 +85,7 @@ endif() add_definitions(/D_GNU_SOURCE) add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") @@ -99,7 +100,7 @@ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvari set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") -#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -gdwarf-2") +#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-use -fprofile-correction") diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index b6273dc5..e19e66ca 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -25,6 +25,8 @@ #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_p.h" #include "crypto/CryptoNight_test.h" +#include "net/Job.h" +#include "net/JobResult.h" #include "Options.h" @@ -91,6 +93,14 @@ void (*cryptonight_variations[4])(const void *input, size_t size, void *output, #endif +bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx) +{ + cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx); + + return *reinterpret_cast(result.result + 24) < job.target(); +} + + bool CryptoNight::init(int algo, int variant) { if (variant < 1 || variant > 4) { diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index ce1b7ba8..fbb2f975 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -39,9 +39,14 @@ struct cryptonight_ctx { }; +class Job; +class JobResult; + + class CryptoNight { public: + static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx); static bool init(int algo, int variant); private: diff --git a/src/net/JobResult.h b/src/net/JobResult.h new file mode 100644 index 00000000..ba067cdc --- /dev/null +++ b/src/net/JobResult.h @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __JOBRESULT_H__ +#define __JOBRESULT_H__ + + +#include + + +class JobResult +{ +public: + char jobId[64]; + int poolId; + uint32_t nonce; + uint8_t result[32]; +}; + +#endif /* __JOBRESULT_H__ */ diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 6e4d78ed..76fea588 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,9 +25,10 @@ #include "workers/Handle.h" -Handle::Handle(int threadId, int64_t affinity, bool nicehash) : +Handle::Handle(int threadId, int threads, int64_t affinity, bool nicehash) : m_nicehash(nicehash), m_threadId(threadId), + m_threads(threads), m_affinity(affinity), m_worker(nullptr) { diff --git a/src/workers/Handle.h b/src/workers/Handle.h index 59bd4793..a8ad84c1 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -35,17 +35,19 @@ class IWorker; class Handle { public: - Handle(int threadId, int64_t affinity, bool nicehash); + Handle(int threadId, int threads, int64_t affinity, bool nicehash); void start(void *(*callback) (void *)); inline bool nicehash() const { return m_nicehash; } inline int threadId() const { return m_threadId; } + inline int threads() const { return m_threads; } inline int64_t affinity() const { return m_affinity; } inline void setWorker(IWorker *worker) { m_worker = worker; } private: bool m_nicehash; int m_threadId; + int m_threads; int64_t m_affinity; IWorker *m_worker; pthread_t m_thread; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index eacab941..c102029c 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -24,10 +24,10 @@ #include #include -#include #include "Console.h" +#include "crypto/CryptoNight.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" @@ -35,7 +35,6 @@ SingleWorker::SingleWorker(Handle *handle) : Worker(handle) { - LOG_WARN("SingleWorker %d", pthread_self()); } @@ -44,7 +43,6 @@ void SingleWorker::start() while (true) { if (Workers::isPaused()) { do { - LOG_ERR("SLEEP WAIT FOR WORK"); std::this_thread::sleep_for(std::chrono::milliseconds(200)); } while (Workers::isPaused()); @@ -53,9 +51,12 @@ void SingleWorker::start() } while (!Workers::isOutdated(m_sequence)) { - LOG_ERR("WORK %lld %lld", Workers::sequence(), m_sequence); + m_count++; + *m_job.nonce() = ++m_result.nonce; - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + if (CryptoNight::hash(m_job, m_result, m_ctx)) { + Workers::submit(m_result); + } sched_yield(); } @@ -71,5 +72,13 @@ void SingleWorker::consumeJob() m_job = Workers::job(); m_sequence = Workers::sequence(); - LOG_WARN("consumeJob"); + memcpy(m_result.jobId, m_job.id(), sizeof(m_result.jobId)); + m_result.poolId = m_job.poolId(); + + if (m_nicehash) { + m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id); + } + else { + m_result.nonce = 0xffffffffU / m_threads * m_id; + } } diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h index 9820172c..6ba59468 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/SingleWorker.h @@ -26,6 +26,7 @@ #include "net/Job.h" +#include "net/JobResult.h" #include "workers/Worker.h" @@ -43,6 +44,7 @@ private: void consumeJob(); Job m_job; + JobResult m_result; }; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 1756dbc1..d39ebdc3 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -30,13 +30,15 @@ Worker::Worker(Handle *handle) : m_nicehash(handle->nicehash()), - m_handle(handle), - m_id(handle->threadId()) + m_id(handle->threadId()), + m_threads(handle->threads()), + m_count(0), + m_sequence(0) { - m_handle->setWorker(this); + handle->setWorker(this); - if (Cpu::threads() > 1 && m_handle->affinity() != -1L) { - Cpu::setAffinity(m_id, m_handle->affinity()); + if (Cpu::threads() > 1 && handle->affinity() != -1L) { + Cpu::setAffinity(m_id, handle->affinity()); } m_ctx = Mem::create(m_id); diff --git a/src/workers/Worker.h b/src/workers/Worker.h index f62083d0..35b55b90 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -44,8 +44,9 @@ public: protected: bool m_nicehash; cryptonight_ctx *m_ctx; - Handle *m_handle; int m_id; + int m_threads; + uint64_t m_count; uint64_t m_sequence; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 1916be72..1f7b76c6 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -21,16 +21,17 @@ * along with this program. If not, see . */ -#include "Console.h" #include "workers/Handle.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" Job Workers::m_job; +pthread_mutex_t Workers::m_mutex; pthread_rwlock_t Workers::m_rwlock; std::atomic Workers::m_paused; std::atomic Workers::m_sequence; +std::list Workers::m_queue; std::vector Workers::m_workers; uv_async_t Workers::m_async; @@ -58,7 +59,8 @@ void Workers::setJob(const Job &job) void Workers::start(int threads, int64_t affinity, bool nicehash) { - LOG_NOTICE("start %d", pthread_self()); + pthread_mutex_init(&m_mutex, nullptr); + pthread_rwlock_init(&m_rwlock, nullptr); m_sequence = 0; m_paused = 1; @@ -66,15 +68,19 @@ void Workers::start(int threads, int64_t affinity, bool nicehash) uv_async_init(uv_default_loop(), &m_async, Workers::onResult); for (int i = 0; i < threads; ++i) { - Handle *handle = new Handle(i, affinity, nicehash); + Handle *handle = new Handle(i, threads, affinity, nicehash); m_workers.push_back(handle); handle->start(Workers::onReady); } } -void Workers::submit() +void Workers::submit(const JobResult &result) { + pthread_mutex_lock(&m_mutex); + m_queue.push_back(result); + pthread_mutex_unlock(&m_mutex); + uv_async_send(&m_async); } @@ -93,4 +99,12 @@ void *Workers::onReady(void *arg) void Workers::onResult(uv_async_t *handle) { + std::list results; + + pthread_mutex_lock(&m_mutex); + while (!m_queue.empty()) { + results.push_back(std::move(m_queue.front())); + m_queue.pop_front(); + } + pthread_mutex_unlock(&m_mutex); } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 7d6328ca..68bc6f15 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -26,12 +26,13 @@ #include +#include #include #include #include - #include "net/Job.h" +#include "net/JobResult.h" class Handle; @@ -43,7 +44,7 @@ public: static Job job(); static void setJob(const Job &job); static void start(int threads, int64_t affinity, bool nicehash); - static void submit(); + static void submit(const JobResult &result); static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } @@ -55,9 +56,11 @@ private: static void onResult(uv_async_t *handle); static Job m_job; + static pthread_mutex_t m_mutex; static pthread_rwlock_t m_rwlock; static std::atomic m_paused; static std::atomic m_sequence; + static std::list m_queue; static std::vector m_workers; static uv_async_t m_async; }; From 6774f86fcd217bbdd40d0b0ae14f3579b2867fc4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 11 Jun 2017 15:32:15 +0300 Subject: [PATCH 29/92] Implement job result submitting. --- CMakeLists.txt | 1 + src/interfaces/IJobResultListener.h | 41 +++++++++++++++++++++++++++++ src/net/Client.cpp | 20 ++++++++++++++ src/net/Client.h | 4 ++- src/net/Network.cpp | 9 +++++++ src/net/Network.h | 4 ++- src/workers/Workers.cpp | 8 ++++++ src/workers/Workers.h | 11 +++++--- 8 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 src/interfaces/IJobResultListener.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 15c1d35d..18e5a06e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,7 @@ set(HEADERS src/Console.h src/Cpu.h src/interfaces/IClientListener.h + src/interfaces/IJobResultListener.h src/interfaces/IWorker.h src/Mem.h src/net/Client.h diff --git a/src/interfaces/IJobResultListener.h b/src/interfaces/IJobResultListener.h new file mode 100644 index 00000000..483a2062 --- /dev/null +++ b/src/interfaces/IJobResultListener.h @@ -0,0 +1,41 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __IJOBRESULTLISTENER_H__ +#define __IJOBRESULTLISTENER_H__ + + +class Client; +class JobResult; + + +class IJobResultListener +{ +public: + virtual ~IJobResultListener() {} + + virtual void onJobResult(const JobResult &result) = 0; +}; + + +#endif // __IJOBRESULTLISTENER_H__ diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 91f582a0..eb776da1 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -28,6 +28,7 @@ #include "Console.h" #include "interfaces/IClientListener.h" #include "net/Client.h" +#include "net/JobResult.h" #include "net/Url.h" @@ -148,6 +149,25 @@ void Client::setUrl(const Url *url) } +void Client::submit(const JobResult &result) +{ + char *req = static_cast(malloc(345)); + char nonce[9]; + char data[65]; + + Job::toHex(reinterpret_cast(&result.nonce), 4, nonce); + nonce[8] = '\0'; + + Job::toHex(result.result, 32, data); + data[64] = '\0'; + + snprintf(req, 345, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n", + m_sequence, m_rpcId, result.jobId, nonce, data); + + send(req); +} + + bool Client::parseJob(const json_t *params, int *code) { if (!json_is_object(params)) { diff --git a/src/net/Client.h b/src/net/Client.h index b46a8bf0..75c5b283 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -32,8 +32,9 @@ #include "net/Job.h" -class Url; class IClientListener; +class JobResult; +class Url; class Client @@ -59,6 +60,7 @@ public: void login(const char *user, const char *pass, const char *agent); void send(char *data); void setUrl(const Url *url); + void submit(const JobResult &result); inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline const char *host() const { return m_host; } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 02c68fd1..eef52cd1 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -39,6 +39,8 @@ Network::Network(const Options *options) : m_pool(0), m_diff(0) { + Workers::setListener(this); + m_pools.reserve(2); m_agent = userAgent(); @@ -103,6 +105,13 @@ void Network::onJobReceived(Client *client, const Job &job) } +void Network::onJobResult(const JobResult &result) +{ + LOG_NOTICE("SHARE FOUND"); + m_pools[result.poolId]->submit(result); +} + + void Network::onLoginCredentialsRequired(Client *client) { client->login(m_options->user(), m_options->pass(), m_agent); diff --git a/src/net/Network.h b/src/net/Network.h index af1ddbbf..d9192c9f 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -30,13 +30,14 @@ #include "interfaces/IClientListener.h" +#include "interfaces/IJobResultListener.h" class Options; class Url; -class Network : public IClientListener +class Network : public IClientListener, public IJobResultListener { public: Network(const Options *options); @@ -49,6 +50,7 @@ public: protected: void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; + void onJobResult(const JobResult &result); void onLoginCredentialsRequired(Client *client) override; void onLoginSuccess(Client *client) override; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 1f7b76c6..f3a26cd0 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -21,11 +21,13 @@ * along with this program. If not, see . */ +#include "interfaces/IJobResultListener.h" #include "workers/Handle.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" +IJobResultListener *Workers::m_listener = nullptr; Job Workers::m_job; pthread_mutex_t Workers::m_mutex; pthread_rwlock_t Workers::m_rwlock; @@ -107,4 +109,10 @@ void Workers::onResult(uv_async_t *handle) m_queue.pop_front(); } pthread_mutex_unlock(&m_mutex); + + for (auto result : results) { + m_listener->onJobResult(result); + } + + results.clear(); } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 68bc6f15..93913b4b 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -36,6 +36,7 @@ class Handle; +class IJobResultListener; class Workers @@ -46,15 +47,17 @@ public: static void start(int threads, int64_t affinity, bool nicehash); static void submit(const JobResult &result); - static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } - static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } - static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } - static inline void pause() { m_paused = 1; } + static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } + static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } + static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } + static inline void pause() { m_paused = 1; } + static inline void setListener(IJobResultListener *listener) { m_listener = listener; } private: static void *onReady(void *arg); static void onResult(uv_async_t *handle); + static IJobResultListener *m_listener; static Job m_job; static pthread_mutex_t m_mutex; static pthread_rwlock_t m_rwlock; From a370b8fd3020e5effa0dac5b2e6f20779c00433c Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 12 Jun 2017 07:18:14 +0300 Subject: [PATCH 30/92] Add class Telemetry. --- CMakeLists.txt | 4 +- src/interfaces/IClientListener.h | 6 +- src/interfaces/IWorker.h | 7 +- src/workers/Handle.h | 1 + src/workers/SingleWorker.cpp | 4 ++ src/workers/Telemetry.cpp | 107 +++++++++++++++++++++++++++++++ src/workers/Telemetry.h | 49 ++++++++++++++ src/workers/Worker.cpp | 15 +++++ src/workers/Worker.h | 8 +++ src/workers/Workers.cpp | 40 ++++++++++++ src/workers/Workers.h | 5 ++ 11 files changed, 241 insertions(+), 5 deletions(-) create mode 100644 src/workers/Telemetry.cpp create mode 100644 src/workers/Telemetry.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 18e5a06e..753ee492 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ set(HEADERS src/Summary.h src/workers/Handle.h src/workers/SingleWorker.h + src/workers/Telemetry.h src/workers/Worker.h src/workers/Workers.h src/version.h @@ -52,6 +53,7 @@ set(SOURCES src/Summary.cpp src/workers/Handle.cpp src/workers/SingleWorker.cpp + src/workers/Telemetry.cpp src/workers/Worker.cpp src/workers/Workers.cpp src/xmrig.cpp @@ -86,7 +88,7 @@ endif() add_definitions(/D_GNU_SOURCE) add_definitions(/DUNICODE) -add_definitions(/DAPP_DEBUG) +#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h index 73a85516..57019035 100644 --- a/src/interfaces/IClientListener.h +++ b/src/interfaces/IClientListener.h @@ -34,10 +34,10 @@ class IClientListener public: virtual ~IClientListener() {} - virtual void onClose(Client *client, int failures); + virtual void onClose(Client *client, int failures) = 0; virtual void onJobReceived(Client *client, const Job &job) = 0; - virtual void onLoginCredentialsRequired(Client *client) = 0; - virtual void onLoginSuccess(Client *client) = 0; + virtual void onLoginCredentialsRequired(Client *client) = 0; + virtual void onLoginSuccess(Client *client) = 0; }; diff --git a/src/interfaces/IWorker.h b/src/interfaces/IWorker.h index f9010a2f..b9b6eb0a 100644 --- a/src/interfaces/IWorker.h +++ b/src/interfaces/IWorker.h @@ -25,12 +25,17 @@ #define __IWORKER_H__ +#include + + class IWorker { public: virtual ~IWorker() {} - virtual void start() = 0; + virtual uint64_t hashCount() const = 0; + virtual uint64_t timestamp() const = 0; + virtual void start() = 0; }; diff --git a/src/workers/Handle.h b/src/workers/Handle.h index a8ad84c1..6b2b1d37 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -42,6 +42,7 @@ public: inline int threadId() const { return m_threadId; } inline int threads() const { return m_threads; } inline int64_t affinity() const { return m_affinity; } + inline IWorker *worker() const { return m_worker; } inline void setWorker(IWorker *worker) { m_worker = worker; } private: diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index c102029c..263f0859 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -51,6 +51,10 @@ void SingleWorker::start() } while (!Workers::isOutdated(m_sequence)) { + if ((m_count & 0xF) == 0) { + storeStats(); + } + m_count++; *m_job.nonce() = ++m_result.nonce; diff --git a/src/workers/Telemetry.cpp b/src/workers/Telemetry.cpp new file mode 100644 index 00000000..b1a36633 --- /dev/null +++ b/src/workers/Telemetry.cpp @@ -0,0 +1,107 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include + +#include "Console.h" +#include "workers/Telemetry.h" + + +Telemetry::Telemetry(int threads) : + m_threads(threads) +{ + m_counts = new uint64_t*[threads]; + m_timestamps = new uint64_t*[threads]; + m_top = new uint32_t[threads]; + + for (int i = 0; i < threads; i++) { + m_counts[i] = new uint64_t[kBucketSize]; + m_timestamps[i] = new uint64_t[kBucketSize]; + m_top[i] = 0; + + memset(m_counts[0], 0, sizeof(uint64_t) * kBucketSize); + memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize); + } +} + + +double Telemetry::calc(size_t threadId, size_t ms) const +{ + using namespace std::chrono; + const uint64_t now = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + + uint64_t earliestHashCount = 0; + uint64_t earliestStamp = 0; + uint64_t lastestStamp = 0; + uint64_t lastestHashCnt = 0; + bool haveFullSet = false; + + for (size_t i = 1; i < kBucketSize; i++) { + const size_t idx = (m_top[threadId] - i) & kBucketMask; + + if (m_timestamps[threadId][idx] == 0) { + break; + } + + if (lastestStamp == 0) { + lastestStamp = m_timestamps[threadId][idx]; + lastestHashCnt = m_counts[threadId][idx]; + } + + if (now - m_timestamps[threadId][idx] > ms) { + haveFullSet = true; + break; + } + + earliestStamp = m_timestamps[threadId][idx]; + earliestHashCount = m_counts[threadId][idx]; + } + + if (!haveFullSet || earliestStamp == 0 || lastestStamp == 0) { + return nan(""); + } + + if (lastestStamp - earliestStamp == 0) { + return nan(""); + } + + double hashes, time; + hashes = lastestHashCnt - earliestHashCount; + time = lastestStamp - earliestStamp; + time /= 1000.0; + + return hashes / time; +} + + +void Telemetry::add(size_t threadId, uint64_t count, uint64_t timestamp) +{ + const size_t top = m_top[threadId]; + m_counts[threadId][top] = count; + m_timestamps[threadId][top] = timestamp; + + m_top[threadId] = (top + 1) & kBucketMask; +} diff --git a/src/workers/Telemetry.h b/src/workers/Telemetry.h new file mode 100644 index 00000000..007ba536 --- /dev/null +++ b/src/workers/Telemetry.h @@ -0,0 +1,49 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TELEMETRY_H__ +#define __TELEMETRY_H__ + + +#include + + +class Telemetry +{ +public: + Telemetry(int threads); + double calc(size_t threadId, size_t ms) const; + void add(size_t threadId, uint64_t count, uint64_t timestamp); + +private: + constexpr static size_t kBucketSize = 2 << 11; + constexpr static size_t kBucketMask = kBucketSize - 1; + + int m_threads; + uint32_t* m_top; + uint64_t** m_counts; + uint64_t** m_timestamps; +}; + + +#endif /* __TELEMETRY_H__ */ diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index d39ebdc3..5478bcf7 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -21,6 +21,9 @@ * along with this program. If not, see . */ +#include + +#include "Console.h" #include "Cpu.h" #include "Mem.h" @@ -32,6 +35,8 @@ Worker::Worker(Handle *handle) : m_nicehash(handle->nicehash()), m_id(handle->threadId()), m_threads(handle->threads()), + m_hashCount(0), + m_timestamp(0), m_count(0), m_sequence(0) { @@ -48,3 +53,13 @@ Worker::Worker(Handle *handle) : Worker::~Worker() { } + + +void Worker::storeStats() +{ + using namespace std::chrono; + + const uint64_t timestamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + m_hashCount.store(m_count, std::memory_order_relaxed); + m_timestamp.store(timestamp, std::memory_order_relaxed); +} diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 35b55b90..84f3ccf8 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -25,6 +25,7 @@ #define __WORKER_H__ +#include #include @@ -41,11 +42,18 @@ public: Worker(Handle *handle); ~Worker(); + inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } + inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } + protected: + void storeStats(); + bool m_nicehash; cryptonight_ctx *m_ctx; int m_id; int m_threads; + std::atomic m_hashCount; + std::atomic m_timestamp; uint64_t m_count; uint64_t m_sequence; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index f3a26cd0..832d7da0 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -21,9 +21,14 @@ * along with this program. If not, see . */ +#include + + +#include "Console.h" #include "interfaces/IJobResultListener.h" #include "workers/Handle.h" #include "workers/SingleWorker.h" +#include "workers/Telemetry.h" #include "workers/Workers.h" @@ -35,7 +40,10 @@ std::atomic Workers::m_paused; std::atomic Workers::m_sequence; std::list Workers::m_queue; std::vector Workers::m_workers; +Telemetry *Workers::m_telemetry = nullptr; +uint64_t Workers::m_ticks = 0; uv_async_t Workers::m_async; +uv_timer_t Workers::m_timer; Job Workers::job() @@ -61,6 +69,8 @@ void Workers::setJob(const Job &job) void Workers::start(int threads, int64_t affinity, bool nicehash) { + m_telemetry = new Telemetry(threads); + pthread_mutex_init(&m_mutex, nullptr); pthread_rwlock_init(&m_rwlock, nullptr); @@ -68,6 +78,8 @@ void Workers::start(int threads, int64_t affinity, bool nicehash) m_paused = 1; uv_async_init(uv_default_loop(), &m_async, Workers::onResult); + uv_timer_init(uv_default_loop(), &m_timer); + uv_timer_start(&m_timer, Workers::onPerfTick, 500, 500); for (int i = 0; i < threads; ++i) { Handle *handle = new Handle(i, threads, affinity, nicehash); @@ -98,6 +110,34 @@ void *Workers::onReady(void *arg) } +void Workers::onPerfTick(uv_timer_t *handle) +{ + for (Handle *handle : m_workers) { + m_telemetry->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp()); + } + + if ((m_ticks++ & 0xF) == 0) { + double hps = 0.0; + double telem; + bool normal = true; + + for (Handle *handle : m_workers) { + telem = m_telemetry->calc(handle->threadId(), 2500); + if (!std::isnormal(telem)) { + normal = false; + break; + } + else { + hps += telem; + } + } + + if (normal) { + LOG_NOTICE("%03.1f H/s", hps); + } + } +} + void Workers::onResult(uv_async_t *handle) { diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 93913b4b..f7a0e43a 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -37,6 +37,7 @@ class Handle; class IJobResultListener; +class Telemetry; class Workers @@ -55,6 +56,7 @@ public: private: static void *onReady(void *arg); + static void onPerfTick(uv_timer_t *handle); static void onResult(uv_async_t *handle); static IJobResultListener *m_listener; @@ -65,7 +67,10 @@ private: static std::atomic m_sequence; static std::list m_queue; static std::vector m_workers; + static Telemetry *m_telemetry; + static uint64_t m_ticks; static uv_async_t m_async; + static uv_timer_t m_timer; }; From 3df545cfc56c1af4ae4068f74f0e4f0662f8e8ea Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 12 Jun 2017 16:19:07 +0300 Subject: [PATCH 31/92] Initial MSVC support. --- CMakeLists.txt | 34 +- src/3rdparty/align.h | 33 + src/3rdparty/getopt/getopt.h | 653 ++++++++++++++++++ src/3rdparty/jansson/jansson_private_config.h | 28 +- src/App.cpp | 2 +- src/Console.cpp | 12 +- src/Console.h | 4 +- src/Cpu_stub.cpp | 15 +- src/Mem.h | 5 +- src/Mem_win.cpp | 6 +- src/Options.cpp | 12 +- src/Summary.cpp | 4 +- src/crypto/CryptoNight.h | 9 +- src/crypto/CryptoNight_p.h | 21 +- src/net/Job.h | 7 +- src/net/Url.cpp | 7 +- src/workers/Handle.cpp | 4 +- src/workers/Handle.h | 6 +- src/workers/SingleWorker.cpp | 4 +- src/workers/Workers.cpp | 66 +- src/workers/Workers.h | 9 +- 21 files changed, 845 insertions(+), 96 deletions(-) create mode 100644 src/3rdparty/align.h create mode 100644 src/3rdparty/getopt/getopt.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 753ee492..ed96a8c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_AEON "CryptoNight-Lite support" ON) set(HEADERS + src/3rdparty/align.h src/App.h src/Console.h src/Cpu.h @@ -19,12 +20,12 @@ set(HEADERS src/net/Url.h src/Options.h src/Summary.h + src/version.h src/workers/Handle.h src/workers/SingleWorker.h src/workers/Telemetry.h src/workers/Worker.h src/workers/Workers.h - src/version.h ) set(HEADERS_CRYPTO @@ -86,7 +87,6 @@ else() set(EXTRA_LIBS pthread) endif() -add_definitions(/D_GNU_SOURCE) add_definitions(/DUNICODE) #add_definitions(/DAPP_DEBUG) @@ -98,17 +98,31 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "") set(CMAKE_BUILD_TYPE Release) endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -fno-exceptions") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") -#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") -#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-generate") -#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fprofile-use -fprofile-correction") +# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html +if (CMAKE_C_COMPILER_ID STREQUAL GNU) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -fno-exceptions") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") -if (WIN32) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + + add_definitions(/D_GNU_SOURCE) + + #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") + +elseif (CMAKE_C_COMPILER_ID STREQUAL MSVC) + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MT") + +elseif (CMAKE_C_COMPILER_ID MATCHES "Clang") + + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") + endif() if (WITH_LIBCPUID) diff --git a/src/3rdparty/align.h b/src/3rdparty/align.h new file mode 100644 index 00000000..b61179b9 --- /dev/null +++ b/src/3rdparty/align.h @@ -0,0 +1,33 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ALIGN_H__ +#define __ALIGN_H__ + +#ifdef _MSC_VER +# define VAR_ALIGN(x, decl) __declspec(align(x)) decl +#else +# define VAR_ALIGN(x, decl) decl __attribute__ ((aligned(x))) +#endif + +#endif /* __ALIGN_H__ */ diff --git a/src/3rdparty/getopt/getopt.h b/src/3rdparty/getopt/getopt.h new file mode 100644 index 00000000..0cb88895 --- /dev/null +++ b/src/3rdparty/getopt/getopt.h @@ -0,0 +1,653 @@ +#ifndef __GETOPT_H__ +/** + * DISCLAIMER + * This file is part of the mingw-w64 runtime package. + * + * The mingw-w64 runtime package and its code is distributed in the hope that it + * will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR + * IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to + * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + /* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma warning(disable:4996); + +#define __GETOPT_H__ + +/* All the headers include this file. */ +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ + +#ifdef REPLACE_GETOPT +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +#undef optreset /* see getopt.h */ +#define optreset __mingw_optreset +int optreset; /* reset getopt */ +char *optarg; /* argument associated with option */ +#endif + +//extern int optind; /* index of first non-option in argv */ +//extern int optopt; /* single option character, as parsed */ +//extern int opterr; /* flag to enable built-in diagnostics... */ +// /* (user may set to zero, to suppress) */ +// +//extern char *optarg; /* pointer to argument of current option */ + +#define PRINT_ERROR ((opterr) && (*options != ':')) + +#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ +#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ +#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#ifndef __CYGWIN__ +#define __progname __argv[0] +#else +extern char __declspec(dllimport) *__progname; +#endif + +#ifdef __CYGWIN__ +static char EMSG[] = ""; +#else +#define EMSG "" +#endif + +static int getopt_internal(int, char * const *, const char *, + const struct option *, int *, int); +static int parse_long_options(char * const *, const char *, + const struct option *, int *, int); +static int gcd(int, int); +static void permute_args(int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +static void +_vwarnx(const char *fmt,va_list ap) +{ + (void)fprintf(stderr,"%s: ",__progname); + if (fmt != NULL) + (void)vfprintf(stderr,fmt,ap); + (void)fprintf(stderr,"\n"); +} + +static void +warnx(const char *fmt,...) +{ + va_list ap; + va_start(ap,fmt); + _vwarnx(fmt,ap); + va_end(ap); +} + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, + char * const *nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the BSD getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + + /* + * We don't pass FLAG_PERMUTE to getopt_internal() since + * the BSD getopt(3) (unlike GNU) has never done this. + * + * Furthermore, since many privileged programs call getopt() + * before dropping privileges it makes sense to keep things + * as simple (and bug-free) as possible. + */ + return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); +} +#endif /* REPLACE_GETOPT */ + +//extern int getopt(int nargc, char * const *nargv, const char *options); + +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset +extern int optreset; +#endif +#ifdef __cplusplus +} +#endif +/* + * POSIX requires the `getopt' API to be specified in `unistd.h'; + * thus, `unistd.h' includes this header. However, we do not want + * to expose the `getopt_long' or `getopt_long_only' APIs, when + * included in this manner. Thus, close the standard __GETOPT_H__ + * declarations block, and open an additional __GETOPT_LONG_H__ + * specific block, only when *not* __UNISTD_H_SOURCED__, in which + * to declare the extended API. + */ +#endif /* !defined(__GETOPT_H__) */ + +#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) +#define __GETOPT_LONG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +struct option /* specification for a long form option... */ +{ + const char *name; /* option name, without leading hyphens */ + int has_arg; /* does it take an argument? */ + int *flag; /* where to save its status, or NULL */ + int val; /* its associated status value */ +}; + +enum /* permitted values for its `has_arg' field... */ +{ + no_argument = 0, /* option never takes an argument */ + required_argument, /* option always requires an argument */ + optional_argument /* option may take an argument */ +}; + +/* + * parse_long_options -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ +static int +parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) +{ + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; + +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ + long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) + + current_argv = place; + match = -1; + ambiguous = 0; + + optind++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; + } + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return (BADCH); + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return (BADARG); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (PRINT_ERROR) + warnx(recargstring, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return (BADARG); + } + } else { /* unknown option */ + if (short_too) { + --optind; + return (-1); + } + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return (BADCH); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); +#undef IDENTICAL_INTERPRETATION +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + */ +static int +getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) +{ + char *oli; /* option letter list index */ + int optchar, short_too; + static int posixly_correct = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreset. Work around this braindamage. + */ + if (optind == 0) + optind = optreset = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + * + * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or + * optreset != 0 for GNU compatibility. + */ + if (posixly_correct == -1 || optreset != 0) + posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= FLAG_ALLARGS; + else if (posixly_correct || *options == '+') + flags &= ~FLAG_PERMUTE; + if (*options == '+' || *options == '-') + options++; + + optarg = NULL; + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + if (*(place = nargv[optind]) != '-' || + (place[1] == '\0' && strchr(options, '-') == NULL)) { + place = EMSG; /* found non-option */ + if (flags & FLAG_ALLARGS) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return (INORDER); + } + if (!(flags & FLAG_PERMUTE)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { + optind++; + place = EMSG; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are getopt_long_only() + */ + if (long_options != NULL && place != nargv[optind] && + (*place == '-' || (flags & FLAG_LONGONLY))) { + short_too = 0; + if (*place == '-') + place++; /* --foo long option */ + else if (*place != ':' && strchr(options, *place) != NULL) + short_too = 1; /* could be short option too */ + + optchar = parse_long_options(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + place = EMSG; + return (optchar); + } + } + + if ((optchar = (int)*place++) == (int)':' || + (optchar == (int)'-' && *place != '\0') || + (oli = (char*)strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *place == '\0') + return (-1); + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return (BADCH); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*place) /* no space */ + /* NOTHING */; + else if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else /* white space */ + place = nargv[optind]; + optchar = parse_long_options(nargv, options, long_options, + idx, 0); + place = EMSG; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return (BADARG); + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return (optchar); +} + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE)); +} + +/* + * getopt_long_only -- + * Parse argc/argv argument vector. + */ +int +getopt_long_only(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + + return (getopt_internal(nargc, nargv, options, long_options, idx, + FLAG_PERMUTE|FLAG_LONGONLY)); +} + +//extern int getopt_long(int nargc, char * const *nargv, const char *options, +// const struct option *long_options, int *idx); +//extern int getopt_long_only(int nargc, char * const *nargv, const char *options, +// const struct option *long_options, int *idx); +/* + * Previous MinGW implementation had... + */ +#ifndef HAVE_DECL_GETOPT +/* + * ...for the long form API only; keep this for compatibility. + */ +# define HAVE_DECL_GETOPT 1 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ diff --git a/src/3rdparty/jansson/jansson_private_config.h b/src/3rdparty/jansson/jansson_private_config.h index 2b17f182..671993d9 100644 --- a/src/3rdparty/jansson/jansson_private_config.h +++ b/src/3rdparty/jansson/jansson_private_config.h @@ -2,7 +2,9 @@ /* jansson_private_config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if gcc's __atomic builtins are available */ -#define HAVE_ATOMIC_BUILTINS 1 +#ifndef _MSC_VER +# define HAVE_ATOMIC_BUILTINS 1 +#endif /* Define to 1 if you have the `close' function. */ #define HAVE_CLOSE 1 @@ -20,7 +22,9 @@ #define HAVE_GETPID 1 /* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 +#ifndef _MSC_VER +# define HAVE_GETTIMEOFDAY 1 +#endif /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 @@ -44,10 +48,14 @@ #define HAVE_READ 1 /* Define to 1 if you have the header file. */ -#define HAVE_SCHED_H 1 +#ifndef _MSC_VER +# define HAVE_SCHED_H 1 +#endif /* Define to 1 if you have the `sched_yield' function. */ -#define HAVE_SCHED_YIELD 1 +#ifndef _MSC_VER +# define HAVE_SCHED_YIELD 1 +#endif /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 @@ -68,19 +76,25 @@ #define HAVE_SYNC_BUILTINS 1 /* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 +#ifndef _MSC_VER +# define HAVE_SYS_PARAM_H 1 +#endif /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 +#ifndef _MSC_VER +# define HAVE_SYS_TIME_H 1 +#endif /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 +#ifndef _MSC_VER +# define HAVE_UNISTD_H 1 +#endif /* Define to 1 if the system has the type 'unsigned long long int'. */ #define HAVE_UNSIGNED_LONG_LONG_INT 1 diff --git a/src/App.cpp b/src/App.cpp index 4078f4b7..b897be8a 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -60,7 +60,7 @@ App::~App() } -App::exec() +int App::exec() { if (!m_options->isReady()) { return 0; diff --git a/src/Console.cpp b/src/Console.cpp index fd4ff4a5..b3b7ed3e 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -22,8 +22,10 @@ */ +#include #include + #ifdef WIN32 # include # include "3rdparty/winansi.h" @@ -97,12 +99,12 @@ void Console::message(Console::Level level, const char* fmt, ...) m_colors ? kCL_N : "" ); - pthread_mutex_lock(&m_mutex); + uv_mutex_lock(&m_mutex); vfprintf(stdout, buf, ap); fflush(stdout); - pthread_mutex_unlock(&m_mutex); + uv_mutex_unlock(&m_mutex); va_end(ap); } @@ -121,12 +123,12 @@ void Console::text(const char* fmt, ...) m_colors ? kCL_N : "" ); - pthread_mutex_lock(&m_mutex); + uv_mutex_lock(&m_mutex); vfprintf(stdout, buf, ap); fflush(stdout); - pthread_mutex_unlock(&m_mutex); + uv_mutex_unlock(&m_mutex); va_end(ap); } @@ -135,5 +137,5 @@ void Console::text(const char* fmt, ...) Console::Console() : m_colors(true) { - pthread_mutex_init(&m_mutex, nullptr); + uv_mutex_init(&m_mutex); } diff --git a/src/Console.h b/src/Console.h index edd5ae8c..73e04706 100644 --- a/src/Console.h +++ b/src/Console.h @@ -25,7 +25,7 @@ #define __CONSOLE_H__ -#include +#include class Console @@ -61,7 +61,7 @@ private: static Console *m_self; bool m_colors; - pthread_mutex_t m_mutex; + uv_mutex_t m_mutex; }; diff --git a/src/Cpu_stub.cpp b/src/Cpu_stub.cpp index a04bce26..4bf0ba08 100644 --- a/src/Cpu_stub.cpp +++ b/src/Cpu_stub.cpp @@ -22,7 +22,12 @@ */ -#include +#ifdef _MSC_VER +# include +#else +# include +#endif + #include @@ -45,7 +50,7 @@ static inline void cpuid(int level, int output[4]) { int a, b, c, d; - __cpuid_count(level, 0, a, b, c, d); + //__cpuid_count(level, 0, a, b, c, d); output[0] = a; output[1] = b; @@ -73,7 +78,8 @@ static inline bool has_aes_ni() int cpu_info[4] = { 0 }; cpuid(PROCESSOR_INFO, cpu_info); - return cpu_info[ECX_Reg] & bit_AES; + return false; + //return cpu_info[ECX_Reg] & bit_AES; } @@ -81,7 +87,8 @@ static inline bool has_bmi2() { int cpu_info[4] = { 0 }; cpuid(EXTENDED_FEATURES, cpu_info); - return cpu_info[EBX_Reg] & bit_BMI2; + return false; + //return cpu_info[EBX_Reg] & bit_BMI2; } diff --git a/src/Mem.h b/src/Mem.h index 9a438a17..89635e33 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -28,6 +28,9 @@ #include +#include "align.h" + + struct cryptonight_ctx; @@ -55,7 +58,7 @@ private: static int m_flags; static int m_threads; static size_t m_offset; - static uint8_t *m_memory __attribute__((aligned(16))); + VAR_ALIGN(16, static uint8_t *m_memory); # ifndef XMRIG_NO_AEON static cryptonight_ctx *createLite(int threadId); diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index f9a7ab3d..c5e606f7 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -26,8 +26,12 @@ #include #include #include -#include +#ifdef __GNUC__ +# include +#else +# include +#endif #include "Console.h" #include "crypto/CryptoNight.h" diff --git a/src/Options.cpp b/src/Options.cpp index a2702a65..9ba9acf7 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -24,8 +24,12 @@ #include #include -#include +#ifdef _MSC_VER +#include "getopt/getopt.h" +#else +#include +#endif #include "Console.h" #include "Cpu.h" @@ -387,7 +391,7 @@ void Options::showUsage(int status) const void Options::showVersion() { - printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ + /* printf(APP_NAME " " APP_VERSION "\n built on " __DATE__) #ifdef __GNUC__ " with GCC"); @@ -404,7 +408,7 @@ void Options::showVersion() #ifdef __AES__ " AES-NI" #endif - "\n"); + "\n");*/ printf("\nlibuv/%s\n", uv_version_string()); printf("libjansson/%s\n", JANSSON_VERSION); @@ -438,7 +442,7 @@ bool Options::setAlgo(const char *algo) bool Options::setUserpass(const char *userpass) { - char *p = strchr(userpass, ':'); + const char *p = strchr(userpass, ':'); if (!p) { showUsage(1); return false; diff --git a/src/Summary.cpp b/src/Summary.cpp index 502747c9..7d5f920f 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -35,7 +35,7 @@ static void print_versions() { - char *buf = static_cast(alloca(16)); + char buf[16]; # ifdef __GNUC__ snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); @@ -87,7 +87,7 @@ static void print_cpu() static void print_threads() { - char *buf = static_cast(alloca(32)); + char buf[32]; if (Options::i()->affinity() != -1L) { snprintf(buf, 32, ", affinity=0x%llX", Options::i()->affinity()); } diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index fbb2f975..2ed5dfb2 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -28,14 +28,17 @@ #include +#include "align.h" + + #define MEMORY 2097152 /* 2 MiB */ #define MEMORY_LITE 1048576 /* 1 MiB */ struct cryptonight_ctx { - uint8_t state0[200] __attribute__((aligned(16))); - uint8_t state1[200] __attribute__((aligned(16))); - uint8_t* memory __attribute__((aligned(16))); + VAR_ALIGN(16, uint8_t state0[200]); + VAR_ALIGN(16, uint8_t state1[200]); + VAR_ALIGN(16, uint8_t* memory); }; diff --git a/src/crypto/CryptoNight_p.h b/src/crypto/CryptoNight_p.h index ed24a510..b44b6616 100644 --- a/src/crypto/CryptoNight_p.h +++ b/src/crypto/CryptoNight_p.h @@ -25,7 +25,12 @@ #define __CRYPTONIGHT_P_H__ -#include +#ifdef __GNUC__ +# include +#else +# include +# define __restrict__ __restrict +#endif #include "crypto/CryptoNight.h" @@ -68,15 +73,19 @@ void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, d -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(_WIN64) # define EXTRACT64(X) _mm_cvtsi128_si64(X) +# ifdef __GNUC__ static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) { unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; *hi = r >> 64; return (uint64_t) r; } +# else + #define __umul128 _umul128 +# endif #elif defined(__i386__) # define HI32(X) \ _mm_srli_si128((X), 4) @@ -224,7 +233,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) xin6 = _mm_load_si128(input + 10); xin7 = _mm_load_si128(input + 11); - for (size_t i = 0; __builtin_expect(i < MEM / sizeof(__m128i), 1); i += 8) { + for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -265,7 +274,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) xout6 = _mm_load_si128(output + 10); xout7 = _mm_load_si128(output + 11); - for (size_t i = 0; __builtin_expect(i < MEM / sizeof(__m128i), 1); i += 8) + for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); @@ -315,7 +324,7 @@ inline void cryptonight_hash(const void *__restrict__ input, size_t size, void * uint64_t idx0 = h0[0] ^ h0[4]; - for (size_t i = 0; __builtin_expect(i < ITERATIONS, 1); i++) { + for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx; cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); @@ -372,7 +381,7 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, uint64_t idx0 = h0[0] ^ h0[4]; uint64_t idx1 = h1[0] ^ h1[4]; - for (size_t i = 0; __builtin_expect(i < ITERATIONS, 1); i++) { + for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); diff --git a/src/net/Job.h b/src/net/Job.h index 4f08e84c..9848f128 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -28,6 +28,9 @@ #include +#include "align.h" + + class Job { public: @@ -52,8 +55,8 @@ public: private: int m_poolId; - char m_id[64] __attribute__((aligned(16))); - uint8_t m_blob[84] __attribute__((aligned(16))); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. + VAR_ALIGN(16, char m_id[64]); + VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. uint32_t m_size; uint64_t m_diff; uint64_t m_target; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 4e1dfd9f..d8264c20 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -29,6 +29,11 @@ #include "net/Url.h" +#ifdef _MSC_VER +# define strncasecmp(x,y,z) _strnicmp(x,y,z) +#endif + + Url::Url() : m_host(nullptr), m_port(3333) @@ -66,7 +71,7 @@ Url::Url(const char *url) : return; } - char *port = strchr(base, ':'); + const char *port = strchr(base, ':'); if (!port) { m_host = strdup(base); return; diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 76fea588..c97d10b1 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -35,7 +35,7 @@ Handle::Handle(int threadId, int threads, int64_t affinity, bool nicehash) : } -void Handle::start(void *(*callback) (void *)) +void Handle::start(void (*callback) (void *)) { - pthread_create(&m_thread, nullptr, callback, this); + uv_thread_create(&m_thread, callback, this); } diff --git a/src/workers/Handle.h b/src/workers/Handle.h index 6b2b1d37..96a512e3 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -25,8 +25,8 @@ #define __HANDLE_H__ -#include #include +#include class IWorker; @@ -36,7 +36,7 @@ class Handle { public: Handle(int threadId, int threads, int64_t affinity, bool nicehash); - void start(void *(*callback) (void *)); + void start(void (*callback) (void *)); inline bool nicehash() const { return m_nicehash; } inline int threadId() const { return m_threadId; } @@ -51,7 +51,7 @@ private: int m_threads; int64_t m_affinity; IWorker *m_worker; - pthread_t m_thread; + uv_thread_t m_thread; }; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 263f0859..3969e883 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -22,11 +22,9 @@ */ -#include #include -#include "Console.h" #include "crypto/CryptoNight.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" @@ -62,7 +60,7 @@ void SingleWorker::start() Workers::submit(m_result); } - sched_yield(); +// sched_yield(); } consumeJob(); diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 832d7da0..b3673445 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -34,8 +34,6 @@ IJobResultListener *Workers::m_listener = nullptr; Job Workers::m_job; -pthread_mutex_t Workers::m_mutex; -pthread_rwlock_t Workers::m_rwlock; std::atomic Workers::m_paused; std::atomic Workers::m_sequence; std::list Workers::m_queue; @@ -43,14 +41,16 @@ std::vector Workers::m_workers; Telemetry *Workers::m_telemetry = nullptr; uint64_t Workers::m_ticks = 0; uv_async_t Workers::m_async; +uv_mutex_t Workers::m_mutex; +uv_rwlock_t Workers::m_rwlock; uv_timer_t Workers::m_timer; Job Workers::job() { - pthread_rwlock_rdlock(&m_rwlock); + uv_rwlock_rdlock(&m_rwlock); Job job = m_job; - pthread_rwlock_unlock(&m_rwlock); + uv_rwlock_rdunlock(&m_rwlock); return std::move(job); } @@ -58,9 +58,9 @@ Job Workers::job() void Workers::setJob(const Job &job) { - pthread_rwlock_wrlock(&m_rwlock); + uv_rwlock_wrlock(&m_rwlock); m_job = job; - pthread_rwlock_unlock(&m_rwlock); + uv_rwlock_wrunlock(&m_rwlock); m_sequence++; m_paused = 0; @@ -71,15 +71,15 @@ void Workers::start(int threads, int64_t affinity, bool nicehash) { m_telemetry = new Telemetry(threads); - pthread_mutex_init(&m_mutex, nullptr); - pthread_rwlock_init(&m_rwlock, nullptr); + uv_mutex_init(&m_mutex); + uv_rwlock_init(&m_rwlock); m_sequence = 0; m_paused = 1; uv_async_init(uv_default_loop(), &m_async, Workers::onResult); uv_timer_init(uv_default_loop(), &m_timer); - uv_timer_start(&m_timer, Workers::onPerfTick, 500, 500); + uv_timer_start(&m_timer, Workers::onTick, 500, 500); for (int i = 0; i < threads; ++i) { Handle *handle = new Handle(i, threads, affinity, nicehash); @@ -91,26 +91,43 @@ void Workers::start(int threads, int64_t affinity, bool nicehash) void Workers::submit(const JobResult &result) { - pthread_mutex_lock(&m_mutex); + uv_mutex_lock(&m_mutex); m_queue.push_back(result); - pthread_mutex_unlock(&m_mutex); + uv_mutex_unlock(&m_mutex); uv_async_send(&m_async); } -void *Workers::onReady(void *arg) +void Workers::onReady(void *arg) { auto handle = static_cast(arg); IWorker *worker = new SingleWorker(handle); worker->start(); - - return nullptr; } -void Workers::onPerfTick(uv_timer_t *handle) +void Workers::onResult(uv_async_t *handle) +{ + std::list results; + + uv_mutex_lock(&m_mutex); + while (!m_queue.empty()) { + results.push_back(std::move(m_queue.front())); + m_queue.pop_front(); + } + uv_mutex_unlock(&m_mutex); + + for (auto result : results) { + m_listener->onJobResult(result); + } + + results.clear(); +} + + +void Workers::onTick(uv_timer_t *handle) { for (Handle *handle : m_workers) { m_telemetry->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp()); @@ -137,22 +154,3 @@ void Workers::onPerfTick(uv_timer_t *handle) } } } - - -void Workers::onResult(uv_async_t *handle) -{ - std::list results; - - pthread_mutex_lock(&m_mutex); - while (!m_queue.empty()) { - results.push_back(std::move(m_queue.front())); - m_queue.pop_front(); - } - pthread_mutex_unlock(&m_mutex); - - for (auto result : results) { - m_listener->onJobResult(result); - } - - results.clear(); -} diff --git a/src/workers/Workers.h b/src/workers/Workers.h index f7a0e43a..5e398109 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -27,7 +27,6 @@ #include #include -#include #include #include @@ -55,14 +54,12 @@ public: static inline void setListener(IJobResultListener *listener) { m_listener = listener; } private: - static void *onReady(void *arg); - static void onPerfTick(uv_timer_t *handle); + static void onReady(void *arg); static void onResult(uv_async_t *handle); + static void onTick(uv_timer_t *handle); static IJobResultListener *m_listener; static Job m_job; - static pthread_mutex_t m_mutex; - static pthread_rwlock_t m_rwlock; static std::atomic m_paused; static std::atomic m_sequence; static std::list m_queue; @@ -70,6 +67,8 @@ private: static Telemetry *m_telemetry; static uint64_t m_ticks; static uv_async_t m_async; + static uv_mutex_t m_mutex; + static uv_rwlock_t m_rwlock; static uv_timer_t m_timer; }; From 9580c30d8a6857e89c6b0399a422b958584b290f Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 12 Jun 2017 16:55:21 +0300 Subject: [PATCH 32/92] Fix cpuid stub for MSVC. --- src/Cpu_stub.cpp | 29 ++++++++++++++++++----------- src/crypto/CryptoNight_p.h | 4 ++-- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/Cpu_stub.cpp b/src/Cpu_stub.cpp index 4bf0ba08..0b9196ee 100644 --- a/src/Cpu_stub.cpp +++ b/src/Cpu_stub.cpp @@ -22,11 +22,14 @@ */ -#ifdef _MSC_VER -# include -#else -# include -#endif +#ifdef _MSC_VER +# include + +# define bit_AES (1 << 25) +# define bit_BMI2 (1 << 8) +#else +# include +#endif #include @@ -48,15 +51,21 @@ #define EDX_Reg (3) +#ifdef _MSC_VER +static inline void cpuid(int level, int output[4]) { + __cpuid(output, level); +} +#else static inline void cpuid(int level, int output[4]) { int a, b, c, d; - //__cpuid_count(level, 0, a, b, c, d); + __cpuid_count(level, 0, a, b, c, d); output[0] = a; output[1] = b; output[2] = c; output[3] = d; } +#endif static inline void cpu_brand_string(char* s) { @@ -78,8 +87,7 @@ static inline bool has_aes_ni() int cpu_info[4] = { 0 }; cpuid(PROCESSOR_INFO, cpu_info); - return false; - //return cpu_info[ECX_Reg] & bit_AES; + return cpu_info[ECX_Reg] & bit_AES; } @@ -87,8 +95,7 @@ static inline bool has_bmi2() { int cpu_info[4] = { 0 }; cpuid(EXTENDED_FEATURES, cpu_info); - return false; - //return cpu_info[EBX_Reg] & bit_BMI2; + return cpu_info[EBX_Reg] & bit_BMI2; } @@ -112,7 +119,7 @@ void Cpu::initCommon() { cpu_brand_string(m_brand); -# ifdef __x86_64__ +# if defined(__x86_64__) || defined(_M_AMD64) m_flags |= X86_64; # endif diff --git a/src/crypto/CryptoNight_p.h b/src/crypto/CryptoNight_p.h index b44b6616..8a5268f4 100644 --- a/src/crypto/CryptoNight_p.h +++ b/src/crypto/CryptoNight_p.h @@ -73,7 +73,7 @@ void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, d -#if defined(__x86_64__) || defined(_WIN64) +#if defined(__x86_64__) || defined(_M_AMD64) # define EXTRACT64(X) _mm_cvtsi128_si64(X) # ifdef __GNUC__ @@ -86,7 +86,7 @@ static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) # else #define __umul128 _umul128 # endif -#elif defined(__i386__) +#elif defined(__i386__) || defined(_M_IX86) # define HI32(X) \ _mm_srli_si128((X), 4) From 42bf85d10b9f77b9fc6853fb29420087d1989cf8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 13 Jun 2017 06:31:25 +0300 Subject: [PATCH 33/92] Fixes for MSVC. --- src/Options.cpp | 31 +++++++++++++++++++------------ src/Summary.cpp | 4 +++- src/net/Network_win.cpp | 18 +++++++++++++----- src/version.h | 16 ++++++++++++++++ 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 9ba9acf7..c38f417b 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -25,12 +25,14 @@ #include #include + #ifdef _MSC_VER -#include "getopt/getopt.h" +# include "getopt/getopt.h" #else -#include +# include #endif + #include "Console.h" #include "Cpu.h" #include "donate.h" @@ -391,24 +393,29 @@ void Options::showUsage(int status) const void Options::showVersion() { - /* printf(APP_NAME " " APP_VERSION "\n built on " __DATE__) + printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ - #ifdef __GNUC__ +# if defined(__GNUC__) " with GCC"); printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); - #endif +# elif defined(_MSC_VER) + " with MSVC"); + printf(" %d", MSVC_VERSION); +# else + ); +# endif printf("\n features:" - #ifdef __i386__ +# if defined(__i386__) || defined(_M_IX86) " i386" - #endif - #ifdef __x86_64__ +# elif defined(__x86_64__) || defined(_M_AMD64) " x86_64" - #endif - #ifdef __AES__ +# endif + +# if defined(__AES__) || defined(_MSC_VER) " AES-NI" - #endif - "\n");*/ +# endif + "\n"); printf("\nlibuv/%s\n", uv_version_string()); printf("libjansson/%s\n", JANSSON_VERSION); diff --git a/src/Summary.cpp b/src/Summary.cpp index 7d5f920f..8c7d3ea3 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -37,8 +37,10 @@ static void print_versions() { char buf[16]; -# ifdef __GNUC__ +# if defined(__GNUC__) snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# elif defined(_MSC_VER) + snprintf(buf, 16, " MSVC/%d", MSVC_VERSION); # else buf[0] = '\0'; # endif diff --git a/src/net/Network_win.cpp b/src/net/Network_win.cpp index 432ea71e..15b358b5 100644 --- a/src/net/Network_win.cpp +++ b/src/net/Network_win.cpp @@ -22,7 +22,7 @@ */ -#include +#include #include @@ -51,13 +51,21 @@ static inline OSVERSIONINFOEX winOsVersion() char *Network::userAgent() { const auto osver = winOsVersion(); + const size_t max = 128; - char *buf = static_cast(malloc(128)); + char *buf = static_cast(malloc(max)); + int length = snprintf(buf, max, "%s/%s (Windows NT %lu.%lu", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion); + +# if defined(__x86_64__) || defined(_M_AMD64) + length += snprintf(buf + length, max - length, "; Win64; x64) libuv/%s", uv_version_string()); +# else + length += snprintf(buf + length, max - length, ") libuv/%s", uv_version_string()); +# endif # ifdef __GNUC__ - snprintf(buf, 128, "%s/%s (Windows NT %lu.%lu; Win64; x64) libuv/%s gcc/%d.%d.%d", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion, uv_version_string(), __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); -# else - snprintf(buf, 128, "%s/%s (Windows NT %lu.%lu; Win64; x64) libuv/%s", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion, uv_version_string()); + length += snprintf(buf + length, max - length, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +#elif _MSC_VER + length += snprintf(buf + length, max - length, " msvc/%d", MSVC_VERSION); # endif return buf; diff --git a/src/version.h b/src/version.h index d7bde178..326b6567 100644 --- a/src/version.h +++ b/src/version.h @@ -37,4 +37,20 @@ #define APP_VER_BUILD 0 #define APP_VER_REV 0 +#ifdef _MSC_VER +# if _MSC_VER == 1910 +# define MSVC_VERSION 2017 +# elif _MSC_VER == 1900 +# define MSVC_VERSION 2015 +# elif _MSC_VER == 1800 +# define MSVC_VERSION 2013 +# elif _MSC_VER == 1700 +# define MSVC_VERSION 2012 +# elif _MSC_VER == 1600 +# define MSVC_VERSION 2010 +# else +# define MSVC_VERSION 0 +# endif +#endif + #endif /* __VERSION_H__ */ From de2c351a6616b852824931169add498a7c04a776 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 13 Jun 2017 10:08:32 +0300 Subject: [PATCH 34/92] Add MSVC optimization options. --- CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed96a8c2..9badb06d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,7 +100,7 @@ endif() # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html -if (CMAKE_C_COMPILER_ID STREQUAL GNU) +if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -fno-exceptions") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") @@ -114,11 +114,12 @@ if (CMAKE_C_COMPILER_ID STREQUAL GNU) #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") -elseif (CMAKE_C_COMPILER_ID STREQUAL MSVC) +elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MT") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL") -elseif (CMAKE_C_COMPILER_ID MATCHES "Clang") +elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") From 827e6119114f8e9d31af31a2501ffe67a97b478f Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 13 Jun 2017 11:17:40 +0300 Subject: [PATCH 35/92] Fix libcpuid support for MSVC. --- src/3rdparty/libcpuid/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/3rdparty/libcpuid/CMakeLists.txt b/src/3rdparty/libcpuid/CMakeLists.txt index ef541cc3..51eab1d3 100644 --- a/src/3rdparty/libcpuid/CMakeLists.txt +++ b/src/3rdparty/libcpuid/CMakeLists.txt @@ -26,7 +26,13 @@ set(SOURCES libcpuid_util.c ) +if (CMAKE_CL_64) + enable_language(ASM_MASM) + set(SOURCES_ASM masm-x64.asm) +endif() + add_library(cpuid STATIC ${HEADERS} ${SOURCES} + ${SOURCES_ASM} ) From 2d08f59184981d864cedd1a5c7fb42c464e04416 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 13 Jun 2017 11:51:49 +0300 Subject: [PATCH 36/92] Remove obsolete source files. --- compat.h | 47 ---- elist.h | 274 --------------------- stats.c | 137 ----------- stats.h | 37 --- stratum.c | 718 ------------------------------------------------------ stratum.h | 78 ------ util.c | 270 -------------------- util.h | 43 ---- xmrig.c | 677 -------------------------------------------------- xmrig.h | 57 ----- 10 files changed, 2338 deletions(-) delete mode 100644 compat.h delete mode 100644 elist.h delete mode 100644 stats.c delete mode 100644 stats.h delete mode 100644 stratum.c delete mode 100644 stratum.h delete mode 100644 util.c delete mode 100644 util.h delete mode 100644 xmrig.c delete mode 100644 xmrig.h diff --git a/compat.h b/compat.h deleted file mode 100644 index bf488226..00000000 --- a/compat.h +++ /dev/null @@ -1,47 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __COMPAT_H__ -#define __COMPAT_H__ - -#define unlikely(expr) (__builtin_expect(!!(expr), 0)) -#define likely(expr) (__builtin_expect(!!(expr), 1)) - -#ifdef WIN32 - -#include - -#define sleep(secs) Sleep((secs) * 1000) - -enum { - PRIO_PROCESS = 0, -}; - -static inline int setpriority(int which, int who, int prio) -{ - return -!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); -} - -#endif /* WIN32 */ - -#endif /* __COMPAT_H__ */ diff --git a/elist.h b/elist.h deleted file mode 100644 index a1356184..00000000 --- a/elist.h +++ /dev/null @@ -1,274 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head *prev, struct list_head *next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = (void *) 0; - entry->prev = (void *) 0; -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static inline void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_move - delete from one list and add as another's head - * @list: the entry to move - * @head: the head that will precede our entry - */ -static inline void list_move(struct list_head *list, struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add(list, head); -} - -/** - * list_move_tail - delete from one list and add as another's tail - * @list: the entry to move - * @head: the head that will follow our entry - */ -static inline void list_move_tail(struct list_head *list, - struct list_head *head) -{ - __list_del(list->prev, list->next); - list_add_tail(list, head); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(struct list_head *head) -{ - return head->next == head; -} - -static inline void __list_splice(struct list_head *list, - struct list_head *head) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice(struct list_head *list, struct list_head *head) -{ - if (!list_empty(list)) - __list_splice(list, head); -} - -/** - * list_splice_init - join two lists and reinitialise the emptied list. - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * The list at @list is reinitialised - */ -static inline void list_splice_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __list_splice(list, head); - INIT_LIST_HEAD(list); - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); \ - pos = pos->next) -/** - * list_for_each_prev - iterate over a list backwards - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; pos != (head); \ - pos = pos->prev) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -/** - * list_for_each_entry_continue - iterate over list of given type - * continuing after existing point - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member), \ - prefetch(pos->member.next); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member), \ - prefetch(pos->member.next)) - -#endif diff --git a/stats.c b/stats.c deleted file mode 100644 index ee131672..00000000 --- a/stats.c +++ /dev/null @@ -1,137 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "stats.h" -#include "options.h" -#include "utils/applog.h" -#include "persistent_memory.h" - - -static unsigned long accepted_count = 0L; -static unsigned long rejected_count = 0L; -static double *thr_hashrates; -static double *thr_times; -static uint32_t target = 0; - -pthread_mutex_t stats_lock; - - -static int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y); - - -/** - * @brief stats_init - */ -void stats_init() { - pthread_mutex_init(&stats_lock, NULL); - - thr_hashrates = (double *) persistent_calloc(opt_n_threads, sizeof(double)); - thr_times = (double *) persistent_calloc(opt_n_threads, sizeof(double)); -} - - - -/** - * @brief stats_set_target - * @param target - */ -void stats_set_target(uint32_t new_target) -{ - target = new_target; - - applog(LOG_DEBUG, "Pool set diff to %g", ((double) 0xffffffff) / target); -} - - -/** - * @brief stats_share_result - * @param result - */ -void stats_share_result(bool success) -{ - double hashrate = 0.0; - - pthread_mutex_lock(&stats_lock); - - for (int i = 0; i < opt_n_threads; i++) { - if (thr_times[i] > 0) { - hashrate += thr_hashrates[i] / thr_times[i]; - } - } - - success ? accepted_count++ : rejected_count++; - pthread_mutex_unlock(&stats_lock); - - applog(LOG_INFO, "accepted: %lu/%lu (%.2f%%), %.2f H/s at diff %g", - accepted_count, accepted_count + rejected_count, - 100. * accepted_count / (accepted_count + rejected_count), hashrate, - (((double) 0xffffffff) / target)); -} - - -void stats_add_hashes(int thr_id, struct timeval *tv_start, unsigned long hashes_done) -{ - struct timeval tv_end, diff; - - /* record scanhash elapsed time */ - gettimeofday(&tv_end, NULL); - timeval_subtract(&diff, &tv_end, tv_start); - - if (diff.tv_usec || diff.tv_sec) { - pthread_mutex_lock(&stats_lock); - thr_hashrates[thr_id] = hashes_done; - thr_times[thr_id] = (diff.tv_sec + 1e-6 * diff.tv_usec); - pthread_mutex_unlock(&stats_lock); - } -} - - -/* Subtract the `struct timeval' values X and Y, - storing the result in RESULT. - Return 1 if the difference is negative, otherwise 0. */ -static int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y) -{ - /* Perform the carry for the later subtraction by updating Y. */ - if (x->tv_usec < y->tv_usec) { - int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; - y->tv_usec -= 1000000 * nsec; - y->tv_sec += nsec; - } - if (x->tv_usec - y->tv_usec > 1000000) { - int nsec = (x->tv_usec - y->tv_usec) / 1000000; - y->tv_usec += 1000000 * nsec; - y->tv_sec -= nsec; - } - - /* Compute the time remaining to wait. - * `tv_usec' is certainly positive. */ - result->tv_sec = x->tv_sec - y->tv_sec; - result->tv_usec = x->tv_usec - y->tv_usec; - - /* Return 1 if result is negative. */ - return x->tv_sec < y->tv_sec; -} diff --git a/stats.h b/stats.h deleted file mode 100644 index 13ec117e..00000000 --- a/stats.h +++ /dev/null @@ -1,37 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __STATS_H__ -#define __STATS_H__ - -#include -#include - - -void stats_init(); -void stats_set_target(uint32_t new_target); -void stats_share_result(bool success); -void stats_add_hashes(int thr_id, struct timeval *tv_start, unsigned long hashes_done); - - -#endif /* __STATS_H__ */ diff --git a/stratum.c b/stratum.c deleted file mode 100644 index 4e937251..00000000 --- a/stratum.c +++ /dev/null @@ -1,718 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - -#if defined(WIN32) -# include -# include -#else -# include -# include -# include -#endif - -#ifdef __APPLE_CC__ -# include -#endif - -#include "stratum.h" -#include "version.h" -#include "stats.h" -#include "util.h" -#include "utils/applog.h" - - -#ifdef WIN32 -# define socket_blocks() (WSAGetLastError() == WSAEWOULDBLOCK) -# define poll(fdarray, nfds, timeout) WSAPoll(fdarray, nfds, timeout) -# define SHUT_RDWR SD_BOTH -#else -# define socket_blocks() (errno == EAGAIN || errno == EWOULDBLOCK) -# define closesocket(x) close((x)) -#endif - -#define RBUFSIZE 2048 -#define RECVSIZE (RBUFSIZE - 4) - -#define unlikely(expr) (__builtin_expect(!!(expr), 0)) - - -static struct work work; - - -static bool send_line(curl_socket_t sock, char *s); -static bool socket_full(curl_socket_t sock, int timeout); -static void buffer_append(struct stratum_ctx *sctx, const char *s); -static bool job(struct stratum_ctx *sctx, json_t *params); -static int sockopt_keepalive_cb(void *userdata, curl_socket_t fd, curlsocktype purpose); -static curl_socket_t opensocket_grab_cb(void *clientp, curlsocktype purpose, struct curl_sockaddr *addr); -static int closesocket_cb(void *clientp, curl_socket_t item); -static bool login_decode(struct stratum_ctx *sctx, const json_t *val); -static bool job_decode(const json_t *job); -static bool jobj_binary(const json_t *obj, const char *key, void *buf, size_t buflen); - - -/** - * @brief stratum_socket_full - * @param sctx - * @param timeout - * @return - */ -bool stratum_socket_full(struct stratum_ctx *sctx, int timeout) -{ - return strlen(sctx->sockbuf) || socket_full(sctx->sock, timeout); -} - - -/** - * @brief stratum_send_line - * @param sctx - * @param s - * @return - */ -bool stratum_send_line(struct stratum_ctx *sctx, char *s) -{ - bool ret = false; - - pthread_mutex_lock(&sctx->sock_lock); - ret = send_line(sctx->sock, s); - pthread_mutex_unlock(&sctx->sock_lock); - - return ret; -} - - -/** - * @brief stratum_recv_line - * @param sctx - * @return - */ -char *stratum_recv_line(struct stratum_ctx *sctx) -{ - if (!strstr(sctx->sockbuf, "\n")) { - bool ret = true; - time_t rstart; - - time(&rstart); - - if (!socket_full(sctx->sock, 60)) { - applog(LOG_ERR, "stratum_recv_line timed out"); - return NULL; - } - - do { - char s[RBUFSIZE]; - ssize_t n; - - memset(s, 0, RBUFSIZE); - n = recv(sctx->sock, s, RECVSIZE, 0); - if (!n) { - ret = false; - break; - } - - if (n < 0) { - if (!socket_blocks() || !socket_full(sctx->sock, 1)) { - ret = false; - break; - } - } else { - buffer_append(sctx, s); - } - } while (time(NULL) - rstart < 60 && !strstr(sctx->sockbuf, "\n")); - - if (!ret) { - applog(LOG_ERR, "stratum_recv_line failed"); - return NULL; - } - } - - ssize_t buflen = strlen(sctx->sockbuf); - char *tok = strtok(sctx->sockbuf, "\n"); - - if (!tok) { - applog(LOG_ERR, "stratum_recv_line failed to parse a newline-terminated string"); - return NULL; - } - - char *sret = strdup(tok); - ssize_t len = strlen(sret); - - if (buflen > len + 1) { - memmove(sctx->sockbuf, sctx->sockbuf + len + 1, buflen - len + 1); - } - else { - sctx->sockbuf[0] = '\0'; - } - - return sret; -} - - -/** - * @brief stratum_disconnect - * @param sctx - */ -void stratum_disconnect(struct stratum_ctx *sctx) -{ - pthread_mutex_lock(&sctx->sock_lock); - - sctx->ready = false; - - if (sctx->curl) { - curl_easy_cleanup(sctx->curl); - sctx->curl = NULL; - sctx->sockbuf[0] = '\0'; - } - - pthread_mutex_unlock(&sctx->sock_lock); -} - - -/** - * @brief stratum_handle_method - * @param sctx - * @param s - * @return - */ -bool stratum_handle_method(struct stratum_ctx *sctx, const char *s) -{ - bool ret = false; - const char *method; - json_t *val = json_decode(s); - - if (!val) { - return false; - } - - if (method = json_string_value(json_object_get(val, "method"))) { - if (!strcasecmp(method, "job")) { - ret = job(sctx, json_object_get(val, "params")); - } - else { - applog(LOG_WARNING, "Unknown method: \"%s\"", method); - } - } - - json_decref(val); - return ret; -} - - -/** - * @brief stratum_handle_response - * @param buf - * @return - */ -bool stratum_handle_response(char *buf) { - bool valid = false; - - json_t *val = json_decode(buf); - if (!val) { - return false; - } - - json_t *res_val = json_object_get(val, "result"); - json_t *err_val = json_object_get(val, "error"); - json_t *id_val = json_object_get(val, "id"); - - if (!id_val || json_is_null(id_val) || !res_val) { - const char* message; - - if (json_is_object(err_val) && (message = json_string_value(json_object_get(err_val, "message")))) { - applog(LOG_ERR, "error: \"%s\"", message); - } - - json_decref(val); - return false; - } - - json_t *status = json_object_get(res_val, "status"); - - if (status && !strcmp(json_string_value(status), "KEEPALIVED") ) { - applog(LOG_DEBUG, "Keepalived receveid"); - json_decref(val); - return true; - } - - if (status) { - valid = !strcmp(json_string_value(status), "OK") && json_is_null(err_val); - } else { - valid = json_is_null(err_val); - } - - stats_share_result(valid); - json_decref(val); - return true; -} - - -/** - * @brief stratum_keepalived - * @param sctx - * @return - */ -bool stratum_keepalived(struct stratum_ctx *sctx) -{ - char *s = malloc(128); - snprintf(s, 128, "{\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"},\"id\":1}", sctx->id); - bool ret = stratum_send_line(sctx, s); - - free(s); - return ret; -} - - -/** - * @brief stratum_authorize - * @param sctx - * @param user - * @param pass - * @return - */ -bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *pass) -{ - char *sret; - - char *req = malloc(128 + strlen(user) + strlen(pass)); - sprintf(req, "{\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s/%s\"},\"id\":1}", user, pass, APP_NAME, APP_VERSION); - - if (!stratum_send_line(sctx, req)) { - free(req); - return false; - } - - free(req); - - while (1) { - sret = stratum_recv_line(sctx); - if (!sret) { - return false; - } - - if (!stratum_handle_method(sctx, sret)) { - break; - } - - free(sret); - } - - json_t *val = json_decode(sret); - free(sret); - - if (!val) { - return false; - } - - json_t *result = json_object_get(val, "result"); - json_t *error = json_object_get(val, "error"); - - if (!result || json_is_false(result) || (error && !json_is_null(error))) { - const char* message; - - if (json_is_object(error) && (message = json_string_value(json_object_get(error, "message")))) { - applog(LOG_ERR, "Stratum authentication failed: \"%s\"", message); - } - else { - applog(LOG_ERR, "Stratum authentication failed"); - } - - json_decref(val); - return false; - } - - if (login_decode(sctx, val) && job(sctx, json_object_get(result, "job"))) { - pthread_mutex_lock(&sctx->sock_lock); - sctx->ready = true; - pthread_mutex_unlock(&sctx->sock_lock); - } - - json_decref(val); - return true; -} - - -/** - * @brief stratum_connect - * @param sctx - * @param url - * @return - */ -bool stratum_connect(struct stratum_ctx *sctx, const char *url) -{ - CURL *curl; - - pthread_mutex_lock(&sctx->sock_lock); - sctx->ready = false; - - if (sctx->curl) { - curl_easy_cleanup(sctx->curl); - } - - sctx->curl = curl_easy_init(); - if (!sctx->curl) { - applog(LOG_ERR, "CURL initialization failed"); - pthread_mutex_unlock(&sctx->sock_lock); - return false; - } - - curl = sctx->curl; - if (!sctx->sockbuf) { - sctx->sockbuf = calloc(RBUFSIZE, 1); - sctx->sockbuf_size = RBUFSIZE; - } - - sctx->sockbuf[0] = '\0'; - pthread_mutex_unlock(&sctx->sock_lock); - - if (url != sctx->url) { - free(sctx->url); - sctx->url = strdup(url); - } - - free(sctx->curl_url); - sctx->curl_url = malloc(strlen(url)); - sprintf(sctx->curl_url, "http%s/", strstr(url, "://")); - - curl_easy_setopt(curl, CURLOPT_VERBOSE, 0); - curl_easy_setopt(curl, CURLOPT_URL, sctx->curl_url); - curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30); - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, sctx->curl_err_str); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); - curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_keepalive_cb); - curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket_grab_cb); - curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closesocket_cb); - curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sctx->sock); - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1); - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); - - int rc = curl_easy_perform(curl); - if (rc) { - applog(LOG_ERR, "Stratum connection failed: code: %d, text: %s", rc, sctx->curl_err_str); - curl_easy_cleanup(curl); - sctx->curl = NULL; - return false; - } - - return true; -} - - -/** - * @brief send_line - * @param sock - * @param s - * @return - */ -static bool send_line(curl_socket_t sock, char *s) -{ - ssize_t len, sent = 0; - - len = strlen(s); - s[len++] = '\n'; - - while (len > 0) { - struct pollfd pfd; - pfd.fd = sock; - pfd.events = POLLOUT; - - if (poll(&pfd, 1, 0) < 1) { - return false; - } - - ssize_t n = send(sock, s + sent, len, 0); - if (n < 0) { - if (!socket_blocks()) { - return false; - } - - n = 0; - } - - sent += n; - len -= n; - } - - return true; -} - - -/** - * @brief socket_full - * @param sock - * @param timeout - * @return - */ -static bool socket_full(curl_socket_t sock, int timeout) -{ - struct pollfd pfd; - pfd.fd = sock; - pfd.events = POLLIN; - - return poll(&pfd, 1, timeout * 1000) > 0; -} - - -/** - * @brief buffer_append - * @param sctx - * @param s - */ -static void buffer_append(struct stratum_ctx *sctx, const char *s) -{ - size_t old, new; - - old = strlen(sctx->sockbuf); - new = old + strlen(s) + 1; - - if (new >= sctx->sockbuf_size) { - sctx->sockbuf_size = new + (RBUFSIZE - (new % RBUFSIZE)); - sctx->sockbuf = realloc(sctx->sockbuf, sctx->sockbuf_size); - } - - strcpy(sctx->sockbuf + old, s); -} - - -/** - * @brief job - * @param sctx - * @param params - * @return - */ -static bool job(struct stratum_ctx *sctx, json_t *params) -{ - if (!job_decode(params)) { - return false; - } - - pthread_mutex_lock(&sctx->work_lock); - - if (sctx->work.target != work.target) { - stats_set_target(work.target); - } - - memcpy(&sctx->work, &work, sizeof(struct work)); - pthread_mutex_unlock(&sctx->work_lock); - - return true; -} - - -/** - * @brief sockopt_keepalive_cb - * @param userdata - * @param fd - * @param purpose - * @return - */ -static int sockopt_keepalive_cb(void *userdata, curl_socket_t fd, curlsocktype purpose) -{ - int keepalive = 1; - int tcp_keepcnt = 3; - int tcp_keepidle = 50; - int tcp_keepintvl = 50; - -#ifndef WIN32 - if (unlikely(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive)))) { - return 1; - } - -# ifdef __linux - if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &tcp_keepcnt, sizeof(tcp_keepcnt)))) { - return 1; - } - - if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof(tcp_keepidle)))) { - return 1; - } - - if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof(tcp_keepintvl)))) { - return 1; - } -# endif /* __linux */ - -# ifdef __APPLE_CC__ - if (unlikely(setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &tcp_keepintvl, sizeof(tcp_keepintvl)))) { - return 1; - } -# endif /* __APPLE_CC__ */ -#else /* WIN32 */ - struct tcp_keepalive vals; - vals.onoff = 1; - vals.keepalivetime = tcp_keepidle * 1000; - vals.keepaliveinterval = tcp_keepintvl * 1000; - DWORD outputBytes; - - if (unlikely(WSAIoctl(fd, SIO_KEEPALIVE_VALS, &vals, sizeof(vals), NULL, 0, &outputBytes, NULL, NULL))) { - return 1; - } - -#endif /* WIN32 */ - - return 0; -} - - -static int closesocket_cb(void *clientp, curl_socket_t item) { - shutdown(item, SHUT_RDWR); - return closesocket(item); -} - - -/** - * @brief opensocket_grab_cb - * @param clientp - * @param purpose - * @param addr - * @return - */ -static curl_socket_t opensocket_grab_cb(void *clientp, curlsocktype purpose, struct curl_sockaddr *addr) -{ - curl_socket_t *sock = clientp; - *sock = socket(addr->family, addr->socktype, addr->protocol); - return *sock; -} - - -/** - * @brief login_decode - * @param sctx - * @param val - * @return - */ -static bool login_decode(struct stratum_ctx *sctx, const json_t *val) { - json_t *res = json_object_get(val, "result"); - if (!res) { - applog(LOG_ERR, "JSON invalid result"); - return false; - } - - const char *id = json_string_value(json_object_get(res, "id")); - if (!id || strlen(id) >= (sizeof(sctx->id))) { - applog(LOG_ERR, "JSON invalid id"); - return false; - } - - memset(&sctx->id, 0, sizeof(sctx->id)); - memcpy(&sctx->id, id, strlen(id)); - - const char *s = json_string_value(json_object_get(res, "status")); - if (!s) { - applog(LOG_ERR, "JSON invalid status"); - return false; - } - - if (strcmp(s, "OK")) { - applog(LOG_ERR, "JSON returned status \"%s\"", s); - return false; - } - - return true; -} - - -/** - * @brief job_decode - * @param sctx - * @param job - * @param work - * @return - */ -static bool job_decode(const json_t *job) { - const char *job_id = json_string_value(json_object_get(job, "job_id")); - if (!job_id || strlen(job_id) >= sizeof(work.job_id)) { - applog(LOG_ERR, "JSON invalid job id"); - return false; - } - - const char *blob = json_string_value(json_object_get(job, "blob")); - if (!blob) { - applog(LOG_ERR, "JSON invalid blob"); - return false; - } - - work.blob_size = strlen(blob); - if (work.blob_size % 2 != 0) { - applog(LOG_ERR, "JSON invalid blob length"); - return false; - } - - work.blob_size /= 2; - if (work.blob_size < 76 || work.blob_size > (sizeof(work.blob))) { - applog(LOG_ERR, "JSON invalid blob length"); - return false; - } - - if (!hex2bin((unsigned char *) work.blob, blob, work.blob_size)) { - applog(LOG_ERR, "JSON invalid blob"); - return false; - } - - jobj_binary(job, "target", &work.target, 4); - - memset(work.job_id, 0, sizeof(work.job_id)); - memcpy(work.job_id, job_id, strlen(job_id)); - - return true; -} - - -/** - * @brief jobj_binary - * @param obj - * @param key - * @param buf - * @param buflen - * @return - */ -static bool jobj_binary(const json_t *obj, const char *key, void *buf, size_t buflen) { - const char *hexstr; - json_t *tmp; - - tmp = json_object_get(obj, key); - if (unlikely(!tmp)) { - applog(LOG_ERR, "JSON key '%s' not found", key); - return false; - } - - hexstr = json_string_value(tmp); - if (unlikely(!hexstr)) { - applog(LOG_ERR, "JSON key '%s' is not a string", key); - return false; - } - - - if (!hex2bin(buf, hexstr, buflen)) { - return false; - } - - return true; -} diff --git a/stratum.h b/stratum.h deleted file mode 100644 index 48369567..00000000 --- a/stratum.h +++ /dev/null @@ -1,78 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __STRATUM_H__ -#define __STRATUM_H__ - -#include -#include -#include - - -/** - * 128tx exploit. - * - * Max blob size is 84 (75 fixed + 9 variable), aligned to 96. - * https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. - */ -struct work { - uint32_t blob[21] __attribute__((aligned(16))); - size_t blob_size __attribute__((aligned(16))); - uint32_t target __attribute__((aligned(16))); - uint32_t hash[8] __attribute__((aligned(16))); - char job_id[64] __attribute__((aligned(16))); -}; - - -struct stratum_ctx { - char *url; - - CURL *curl; - char *curl_url; - char curl_err_str[CURL_ERROR_SIZE]; - curl_socket_t sock; - size_t sockbuf_size; - char *sockbuf; - pthread_mutex_t sock_lock; - bool ready; - - char id[64]; - - struct work work; - struct work g_work; - time_t g_work_time; - pthread_mutex_t work_lock; -}; - - -bool stratum_send_line(struct stratum_ctx *sctx, char *s); -bool stratum_socket_full(struct stratum_ctx *sctx, int timeout); -char *stratum_recv_line(struct stratum_ctx *sctx); -bool stratum_connect(struct stratum_ctx *sctx, const char *url); -void stratum_disconnect(struct stratum_ctx *sctx); -bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *pass); -bool stratum_handle_method(struct stratum_ctx *sctx, const char *s); -bool stratum_handle_response(char *buf); -bool stratum_keepalived(struct stratum_ctx *sctx); - -#endif /* __STRATUM_H__ */ diff --git a/util.c b/util.c deleted file mode 100644 index 3dfec485..00000000 --- a/util.c +++ /dev/null @@ -1,270 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - -#include "util.h" -#include "elist.h" -#include "utils/applog.h" - - -struct tq_ent { - void *data; - struct list_head q_node; -}; - - -struct thread_q { - struct list_head q; - bool frozen; - pthread_mutex_t mutex; - pthread_cond_t cond; -}; - - -json_t *json_decode(const char *s) -{ - json_error_t err; - json_t *val = json_loads(s, 0, &err); - - if (!val) { - applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text); - } - - return val; -} - - -/** - * @brief bin2hex - * @param p - * @param len - * @return - */ -char *bin2hex(const unsigned char *p, size_t len) -{ - char *s = malloc((len * 2) + 1); - if (!s) { - return NULL; - } - - for (int i = 0; i < len; i++) { - sprintf(s + (i * 2), "%02x", (unsigned int) p[i]); - } - - return s; -} - - -/** - * @brief hex2bin - * @param p - * @param hexstr - * @param len - * @return - */ -bool hex2bin(unsigned char *p, const char *hexstr, size_t len) -{ - char hex_byte[3]; - char *ep; - - hex_byte[2] = '\0'; - - while (*hexstr && len) { - if (!hexstr[1]) { - applog(LOG_ERR, "hex2bin str truncated"); - return false; - } - - hex_byte[0] = hexstr[0]; - hex_byte[1] = hexstr[1]; - *p = (unsigned char) strtol(hex_byte, &ep, 16); - if (*ep) { - applog(LOG_ERR, "hex2bin failed on '%s'", hex_byte); - return false; - } - - p++; - hexstr += 2; - len--; - } - - return (len == 0 && *hexstr == 0) ? true : false; -} - - -/** - * @brief tq_new - * @return - */ -struct thread_q *tq_new(void) -{ - struct thread_q *tq; - - tq = calloc(1, sizeof(*tq)); - if (!tq) - return NULL; - - INIT_LIST_HEAD(&tq->q); - pthread_mutex_init(&tq->mutex, NULL); - pthread_cond_init(&tq->cond, NULL); - - return tq; -} - - -/** - * @brief tq_free - * @param tq - */ -void tq_free(struct thread_q *tq) -{ - struct tq_ent *ent, *iter; - - if (!tq) - return; - - list_for_each_entry_safe(ent, iter, &tq->q, q_node) { - list_del(&ent->q_node); - free(ent); - } - - pthread_cond_destroy(&tq->cond); - pthread_mutex_destroy(&tq->mutex); - - memset(tq, 0, sizeof(*tq)); /* poison */ - free(tq); -} - - -/** - * @brief tq_freezethaw - * @param tq - * @param frozen - */ -static void tq_freezethaw(struct thread_q *tq, bool frozen) -{ - pthread_mutex_lock(&tq->mutex); - - tq->frozen = frozen; - - pthread_cond_signal(&tq->cond); - pthread_mutex_unlock(&tq->mutex); -} - - -/** - * @brief tq_freeze - * @param tq - */ -void tq_freeze(struct thread_q *tq) -{ - tq_freezethaw(tq, true); -} - - -/** - * @brief tq_thaw - * @param tq - */ -void tq_thaw(struct thread_q *tq) -{ - tq_freezethaw(tq, false); -} - - -/** - * @brief tq_push - * @param tq - * @param data - * @return - */ -bool tq_push(struct thread_q *tq, void *data) -{ - struct tq_ent *ent; - bool rc = true; - - ent = calloc(1, sizeof(*ent)); - if (!ent) - return false; - - ent->data = data; - INIT_LIST_HEAD(&ent->q_node); - - pthread_mutex_lock(&tq->mutex); - - if (!tq->frozen) { - list_add_tail(&ent->q_node, &tq->q); - } else { - free(ent); - rc = false; - } - - pthread_cond_signal(&tq->cond); - pthread_mutex_unlock(&tq->mutex); - - return rc; -} - - -/** - * @brief tq_pop - * @param tq - * @param abstime - * @return - */ -void *tq_pop(struct thread_q *tq, const struct timespec *abstime) -{ - struct tq_ent *ent; - void *rval = NULL; - int rc; - - pthread_mutex_lock(&tq->mutex); - - if (!list_empty(&tq->q)) - goto pop; - - if (abstime) - rc = pthread_cond_timedwait(&tq->cond, &tq->mutex, abstime); - else - rc = pthread_cond_wait(&tq->cond, &tq->mutex); - if (rc) - goto out; - if (list_empty(&tq->q)) - goto out; - -pop: - ent = list_entry(tq->q.next, struct tq_ent, q_node); - rval = ent->data; - - list_del(&ent->q_node); - free(ent); - -out: - pthread_mutex_unlock(&tq->mutex); - return rval; -} diff --git a/util.h b/util.h deleted file mode 100644 index 47ab8904..00000000 --- a/util.h +++ /dev/null @@ -1,43 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __UTIL_H__ -#define __UTIL_H__ - -#include - - -json_t *json_decode(const char *s); - -char *bin2hex(const unsigned char *p, size_t len); -bool hex2bin(unsigned char *p, const char *hexstr, size_t len); - -struct thread_q *tq_new(void); -void tq_free(struct thread_q *tq); -bool tq_push(struct thread_q *tq, void *data); -void *tq_pop(struct thread_q *tq, const struct timespec *abstime); -void tq_freeze(struct thread_q *tq); -void tq_thaw(struct thread_q *tq); - - -#endif /* __UTIL_H__ */ diff --git a/xmrig.c b/xmrig.c deleted file mode 100644 index 7b14933b..00000000 --- a/xmrig.c +++ /dev/null @@ -1,677 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#ifdef WIN32 -# include -# include -#endif - -#include -#include -#include - -#include "compat.h" -#include "xmrig.h" -#include "algo/cryptonight/cryptonight.h" -#include "options.h" -#include "cpu.h" -#include "persistent_memory.h" -#include "stratum.h" -#include "stats.h" -#include "util.h" -#include "utils/summary.h" -#include "utils/applog.h" - -#define LP_SCANTIME 60 -#define JSON_BUF_LEN 345 - - -struct workio_cmd { - struct thr_info *thr; - struct work *work; -}; - - -struct thr_info *thr_info; -static int work_thr_id = -1; -static int timer_thr_id = -1; -static int stratum_thr_id = -1; -struct work_restart *work_restart = NULL; -static struct stratum_ctx *stratum_ctx = NULL; -static bool backup_active = false; -static bool g_want_donate = false; - - -static void workio_cmd_free(struct workio_cmd *wc); - - -/** - * @brief work_copy - * @param dest - * @param src - */ -static inline void work_copy(struct work *dest, const struct work *src) { - memcpy(dest, src, sizeof(struct work)); -} - - -/** - * @brief restart_threads - */ -static inline void restart_threads(void) { - for (int i = 0; i < opt_n_threads; i++) { - work_restart[i].restart = 1; - } -} - - -/** - * @brief gen_workify - * @param sctx - * @param work - */ -static inline void gen_workify(struct stratum_ctx *sctx) { - pthread_mutex_lock(&stratum_ctx->work_lock); - - if (stratum_ctx->work.job_id && (!stratum_ctx->g_work_time || strcmp(stratum_ctx->work.job_id, stratum_ctx->g_work.job_id))) { - memcpy(&sctx->g_work, &sctx->work, sizeof(struct work)); - time(&stratum_ctx->g_work_time); - - pthread_mutex_unlock(&stratum_ctx->work_lock); - - applog(LOG_DEBUG, "Stratum detected new block"); - restart_threads(); - - return; - } - - pthread_mutex_unlock(&stratum_ctx->work_lock); -} - - -/** - * @brief submit_upstream_work - * @param work - * @return - */ -static bool submit_upstream_work(struct work *work) { - char s[JSON_BUF_LEN]; - - /* pass if the previous hash is not the current previous hash */ - if (memcmp(work->blob + 1, stratum_ctx->g_work.blob + 1, 32)) { - return true; - } - - char *noncestr = bin2hex(((const unsigned char*) work->blob) + 39, 4); - char *hashhex = bin2hex((const unsigned char *) work->hash, 32); - - snprintf(s, JSON_BUF_LEN, - "{\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"},\"id\":1}", - stratum_ctx->id, work->job_id, noncestr, hashhex); - - free(hashhex); - free(noncestr); - - if (unlikely(!stratum_send_line(stratum_ctx, s))) { - return false; - } - - return true; -} - - - -/** - * @brief workio_cmd_free - * @param wc - */ -static void workio_cmd_free(struct workio_cmd *wc) { - if (!wc) { - return; - } - - free(wc->work); - - memset(wc, 0, sizeof(*wc)); /* poison */ - free(wc); -} - - -/** - * @brief workio_submit_work - * @param wc - * @param curl - * @return - */ -static bool workio_submit_work(struct workio_cmd *wc) { - while (!submit_upstream_work(wc->work)) { - sleep(opt_retry_pause); - } - - return true; -} - - -/** - * @brief workio_thread - * @param userdata - * @return - */ -static void *workio_thread(void *userdata) { - struct thr_info *mythr = userdata; - bool ok = true; - - while (ok) { - struct workio_cmd *wc; - - /* wait for workio_cmd sent to us, on our queue */ - wc = tq_pop(mythr->q, NULL ); - if (!wc) { - ok = false; - break; - } - - workio_submit_work(wc); - workio_cmd_free(wc); - } - - tq_freeze(mythr->q); - - return NULL ; -} - - -/** - * @brief submit_work - * @param thr - * @param work_in - * @return - */ -static bool submit_work(struct thr_info *thr, const struct work *work_in) { - struct workio_cmd *wc; - - /* fill out work request message */ - wc = calloc(1, sizeof(*wc)); - wc->work = malloc(sizeof(*work_in)); - - if (likely(wc->work)) { - wc->thr = thr; - work_copy(wc->work, work_in); - - if (likely(tq_push(thr_info[work_thr_id].q, wc))) { - return true; - } - } - - workio_cmd_free(wc); - return false; -} - - -static bool should_pause(int thr_id) { - bool ret = false; - - pthread_mutex_lock(&stratum_ctx->sock_lock); - - if (!stratum_ctx->ready) { - ret = true; - } - - pthread_mutex_unlock(&stratum_ctx->sock_lock); - - return ret; -} - - -/** - * @brief miner_thread - * @param userdata - * @return - */ -static void *miner_thread(void *userdata) { - struct thr_info *mythr = userdata; - const int thr_id = mythr->id; - struct work work = { { 0 } }; - uint32_t max_nonce; - uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - 0x20; - - struct cryptonight_ctx *persistentctx = (struct cryptonight_ctx *) create_persistent_ctx(thr_id); - - if (cpu_info.total_logical_cpus > 1 && opt_affinity != -1L) { - affine_to_cpu_mask(thr_id, (unsigned long) opt_affinity); - } - - uint32_t *nonceptr = NULL; - uint32_t hash[8] __attribute__((aligned(32))); - - while (1) { - if (should_pause(thr_id)) { - sleep(1); - continue; - } - - pthread_mutex_lock(&stratum_ctx->work_lock); - - if (memcmp(work.job_id, stratum_ctx->g_work.job_id, 64)) { - work_copy(&work, &stratum_ctx->g_work); - nonceptr = (uint32_t*) (((char*) work.blob) + 39); - - if (opt_nicehash) { - end_nonce = (*nonceptr & 0xff000000U) + (0xffffffU / opt_n_threads * (thr_id + 1) - 0x20); - *nonceptr = (*nonceptr & 0xff000000U) + (0xffffffU / opt_n_threads * thr_id); - } - else { - *nonceptr = 0xffffffffU / opt_n_threads * thr_id; - } - } - - pthread_mutex_unlock(&stratum_ctx->work_lock); - - work_restart[thr_id].restart = 0; - - if (*nonceptr + LP_SCANTIME > end_nonce) { - max_nonce = end_nonce; - } else { - max_nonce = *nonceptr + LP_SCANTIME; - } - - unsigned long hashes_done = 0; - - struct timeval tv_start; - gettimeofday(&tv_start, NULL); - - /* scan nonces for a proof-of-work hash */ - const int rc = scanhash_cryptonight(thr_id, hash, work.blob, work.blob_size, work.target, max_nonce, &hashes_done, persistentctx); - stats_add_hashes(thr_id, &tv_start, hashes_done); - - if (!rc) { - continue; - } - - memcpy(work.hash, hash, 32); - submit_work(mythr, &work); - ++(*nonceptr); - } - - tq_freeze(mythr->q); - return NULL; -} - - -/** - * @brief miner_thread_double - * @param userdata - * @return - */ -static void *miner_thread_double(void *userdata) { - struct thr_info *mythr = userdata; - const int thr_id = mythr->id; - struct work work = { { 0 } }; - uint32_t max_nonce; - uint32_t end_nonce = 0xffffffffU / opt_n_threads * (thr_id + 1) - 0x20; - - struct cryptonight_ctx *persistentctx = (struct cryptonight_ctx *) create_persistent_ctx(thr_id); - - if (cpu_info.total_logical_cpus > 1 && opt_affinity != -1L) { - affine_to_cpu_mask(thr_id, (unsigned long) opt_affinity); - } - - uint32_t *nonceptr0 = NULL; - uint32_t *nonceptr1 = NULL; - uint8_t double_hash[64]; - uint8_t double_blob[sizeof(work.blob) * 2]; - - while (1) { - if (should_pause(thr_id)) { - sleep(1); - continue; - } - - pthread_mutex_lock(&stratum_ctx->work_lock); - - if (memcmp(work.job_id, stratum_ctx->g_work.job_id, 64)) { - work_copy(&work, &stratum_ctx->g_work); - - memcpy(double_blob, work.blob, work.blob_size); - memcpy(double_blob + work.blob_size, work.blob, work.blob_size); - - nonceptr0 = (uint32_t*) (((char*) double_blob) + 39); - nonceptr1 = (uint32_t*) (((char*) double_blob) + 39 + work.blob_size); - - if (opt_nicehash) { - end_nonce = (*nonceptr0 & 0xff000000U) + (0xffffffU / (opt_n_threads * 2) * (thr_id + 1) - 0x20); - *nonceptr0 = (*nonceptr0 & 0xff000000U) + (0xffffffU / (opt_n_threads * 2) * thr_id); - *nonceptr1 = (*nonceptr1 & 0xff000000U) + (0xffffffU / (opt_n_threads * 2) * (thr_id + opt_n_threads)); - } - else { - *nonceptr0 = 0xffffffffU / (opt_n_threads * 2) * thr_id; - *nonceptr1 = 0xffffffffU / (opt_n_threads * 2) * (thr_id + opt_n_threads); - } - } - - pthread_mutex_unlock(&stratum_ctx->work_lock); - - work_restart[thr_id].restart = 0; - - if (*nonceptr0 + (LP_SCANTIME / 2) > end_nonce) { - max_nonce = end_nonce; - } else { - max_nonce = *nonceptr0 + (LP_SCANTIME / 2); - } - - unsigned long hashes_done = 0; - - struct timeval tv_start; - gettimeofday(&tv_start, NULL); - - /* scan nonces for a proof-of-work hash */ - const int rc = scanhash_cryptonight_double(thr_id, (uint32_t *) double_hash, double_blob, work.blob_size, work.target, max_nonce, &hashes_done, persistentctx); - stats_add_hashes(thr_id, &tv_start, hashes_done); - - if (!rc) { - continue; - } - - if (rc & 1) { - memcpy(work.hash, double_hash, 32); - memcpy(work.blob, double_blob, work.blob_size); - submit_work(mythr, &work); - } - - if (rc & 2) { - memcpy(work.hash, double_hash + 32, 32); - memcpy(work.blob, double_blob + work.blob_size, work.blob_size); - submit_work(mythr, &work); - } - - ++(*nonceptr0); - ++(*nonceptr1); - } - - tq_freeze(mythr->q); - return NULL; -} - - - -/** - * @brief stratum_thread - * @param userdata - * @return - */ -static void *timer_thread(void *userdata) { - const int max_user_time = 100 - opt_donate_level; - int user_time_remaning = max_user_time; - int donate_time_remaning = 0; - - - while (1) { - sleep(60); - - if (user_time_remaning > 0) { - if (--user_time_remaning == 0) { - g_want_donate = true; - - donate_time_remaning = opt_donate_level; - stratum_disconnect(stratum_ctx); - continue; - } - } - - if (donate_time_remaning > 0) { - if (--donate_time_remaning == 0) { - g_want_donate = false; - - user_time_remaning = max_user_time; - stratum_disconnect(stratum_ctx); - continue; - } - } - } -} - - -static void switch_stratum() { - static bool want_donate = false; - - if (g_want_donate && !want_donate) { - stratum_ctx->url = opt_algo == ALGO_CRYPTONIGHT ? "stratum+tcp://donate.xmrig.com:443" : "stratum+tcp://donate.xmrig.com:3333"; - applog(LOG_NOTICE, "Switching to dev pool"); - want_donate = true; - } - - if (!g_want_donate && want_donate) { - stratum_ctx->url = backup_active ? opt_backup_url : opt_url; - applog(LOG_NOTICE, "Switching to user pool: \"%s\"", stratum_ctx->url); - want_donate = false; - } -} - - - -/** - * @brief stratum_thread - * @param userdata - * @return - */ -static void *stratum_thread(void *userdata) { - char *s; - - stratum_ctx->url = opt_url; - stratum_ctx->ready = false; - - while (1) { - int failures = 0; - switch_stratum(); - - while (!stratum_ctx->curl) { - pthread_mutex_lock(&stratum_ctx->work_lock); - stratum_ctx->g_work_time = 0; - pthread_mutex_unlock(&stratum_ctx->work_lock); - - restart_threads(); - switch_stratum(); - - if (!stratum_connect(stratum_ctx, stratum_ctx->url) || !stratum_authorize(stratum_ctx, opt_user, opt_pass)) { - stratum_disconnect(stratum_ctx); - failures++; - - if (failures > opt_retries && opt_backup_url) { - failures = 0; - - backup_active = !backup_active; - stratum_ctx->url = backup_active ? opt_backup_url : opt_url; - sleep(opt_retry_pause); - - applog(LOG_WARNING, "Switch to: \"%s\"", stratum_ctx->url); - continue; - } - - applog(LOG_ERR, "...retry after %d seconds", opt_retry_pause); - sleep(opt_retry_pause); - } - } - - gen_workify(stratum_ctx); - - if (opt_keepalive && !stratum_socket_full(stratum_ctx, 90)) { - stratum_keepalived(stratum_ctx); - } - - if (!stratum_socket_full(stratum_ctx, 300)) { - applog(LOG_ERR, "Stratum connection timed out"); - s = NULL; - } else { - s = stratum_recv_line(stratum_ctx); - } - - if (!s) { - stratum_disconnect(stratum_ctx); - applog(LOG_ERR, "Stratum connection interrupted"); - continue; - } - - if (!stratum_handle_method(stratum_ctx, s)) { - stratum_handle_response(s); - } - - free(s); - } - - return NULL ; -} - - -/** - * @brief start work I/O thread - * @return - */ -static bool start_workio() { - work_thr_id = opt_n_threads; - - struct thr_info *thr = &thr_info[work_thr_id]; - thr->id = work_thr_id; - thr->q = tq_new(); - - if (unlikely(!thr->q || pthread_create(&thr->pth, NULL, workio_thread, thr))) { - return false; - } - - return true; -} - - -/** - * @brief start_stratum - * @return - */ -static bool start_stratum() { - stratum_thr_id = opt_n_threads + 1; - - stratum_ctx = persistent_calloc(1, sizeof(struct stratum_ctx)); - pthread_mutex_init(&stratum_ctx->work_lock, NULL); - pthread_mutex_init(&stratum_ctx->sock_lock, NULL); - - struct thr_info *thr = &thr_info[stratum_thr_id]; - thr->id = stratum_thr_id; - thr->q = tq_new(); - - if (unlikely(!thr->q || pthread_create(&thr->pth, NULL, stratum_thread, thr))) { - return false; - } - - tq_push(thr_info[stratum_thr_id].q, strdup(opt_url)); - return true; -} - - -/** - * @brief start_timer - * @return - */ -static bool start_timer() { - timer_thr_id = opt_n_threads + 2; - - if (opt_donate_level < 1) { - return true; - } - - struct thr_info *thr = &thr_info[timer_thr_id]; - thr->id = timer_thr_id; - thr->q = tq_new(); - - if (unlikely(!thr->q || pthread_create(&thr->pth, NULL, timer_thread, thr))) { - return false; - } - - return true; -} - - -/** - * @brief start_mining - * @return - */ -static bool start_mining() { - for (int i = 0; i < opt_n_threads; i++) { - struct thr_info *thr = &thr_info[i]; - - thr->id = i; - thr->q = tq_new(); - - if (unlikely(!thr->q || pthread_create(&thr->pth, NULL, opt_double_hash ? miner_thread_double : miner_thread, thr))) { - applog(LOG_ERR, "thread %d create failed", i); - return false; - } - } - - return true; -} - - -/** - * @brief main - * @param argc - * @param argv - * @return - */ -int main(int argc, char *argv[]) { - applog_init(); - cpu_init(); - parse_cmdline(argc, argv); - persistent_memory_allocate(); - print_summary(); - - stats_init(); - os_specific_init(); - - work_restart = persistent_calloc(opt_n_threads, sizeof(*work_restart)); - thr_info = persistent_calloc(opt_n_threads + 3, sizeof(struct thr_info)); - - if (!start_workio()) { - applog(LOG_ERR, "workio thread create failed"); - return 1; - } - - if (!start_stratum()) { - applog(LOG_ERR, "stratum thread create failed"); - return 1; - } - - start_timer(); - - if (!start_mining()) { - return 1; - } - - pthread_join(thr_info[work_thr_id].pth, NULL); - applog(LOG_INFO, "workio thread dead, exiting."); - persistent_memory_free(); - return 0; -} - diff --git a/xmrig.h b/xmrig.h deleted file mode 100644 index 08091367..00000000 --- a/xmrig.h +++ /dev/null @@ -1,57 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __XMRIG_H__ -#define __XMRIG_H__ - -#include -#include -#include -#include -#include - -#define unlikely(expr) (__builtin_expect(!!(expr), 0)) -#define likely(expr) (__builtin_expect(!!(expr), 1)) - - -struct thr_info { - int id; - pthread_t pth; - struct thread_q *q; -}; - - -struct work_restart { - volatile unsigned long restart; - char padding[128 - sizeof(unsigned long)]; -}; - - -struct work; - - -extern struct thr_info *thr_info; -extern struct work_restart *work_restart; -extern void os_specific_init(); - -#endif /* __XMRIG_H__ */ From 8c2951db2df884f7e91e377241db22f15f43d2b6 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 13 Jun 2017 13:20:15 +0300 Subject: [PATCH 37/92] Add signal handlers. --- CMakeLists.txt | 1 + src/App.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++------- src/App.h | 11 ++++++++++ src/App_win.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++ src/Cpu.cpp | 2 +- src/Options.h | 1 + 6 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 src/App_win.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9badb06d..e1dd51ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,7 @@ if (WIN32) res/app.rc src/3rdparty/winansi.cpp src/3rdparty/winansi.h + src/App_win.cpp src/Cpu_win.cpp src/Mem_win.cpp src/net/Network_win.cpp diff --git a/src/App.cpp b/src/App.cpp index b897be8a..06e512b6 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -30,7 +30,6 @@ #include "Cpu.h" #include "crypto/CryptoNight.h" #include "Mem.h" -#include "net/Client.h" #include "net/Network.h" #include "Options.h" #include "Summary.h" @@ -38,25 +37,28 @@ #include "workers/Workers.h" +App *App::m_self = nullptr; -App::App(int argc, char **argv) + + +App::App(int argc, char **argv) : + m_network(nullptr), + m_options(nullptr) { + m_self = this; + Console::init(); Cpu::init(); m_options = Options::parse(argc, argv); m_network = new Network(m_options); - + uv_signal_init(uv_default_loop(), &m_signal); } App::~App() { - LOG_DEBUG("~APP"); - - free(m_network); - free(m_options); } @@ -71,6 +73,12 @@ int App::exec() return 1; } + uv_signal_start(&m_signal, App::onSignal, SIGHUP); + uv_signal_start(&m_signal, App::onSignal, SIGTERM); + uv_signal_start(&m_signal, App::onSignal, SIGINT); + + background(); + Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); @@ -81,5 +89,38 @@ int App::exec() const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); uv_loop_close(uv_default_loop()); + free(m_network); + free(m_options); + return r; } + + +void App::close() +{ + uv_stop(uv_default_loop()); +} + + +void App::onSignal(uv_signal_t *handle, int signum) +{ + switch (signum) + { + case SIGHUP: + LOG_WARN("SIGHUP received, exiting"); + break; + + case SIGTERM: + LOG_WARN("SIGTERM received, exiting"); + break; + + case SIGINT: + LOG_WARN("SIGINT received, exiting"); + break; + + default: + break; + } + + m_self->close(); +} diff --git a/src/App.h b/src/App.h index b2d5e5f0..99eac432 100644 --- a/src/App.h +++ b/src/App.h @@ -25,6 +25,9 @@ #define __APP_H__ +#include + + class Network; class Options; @@ -38,8 +41,16 @@ public: int exec(); private: + void background(); + void close(); + + static void onSignal(uv_signal_t *handle, int signum); + + static App *m_self; + Network *m_network; Options *m_options; + uv_signal_t m_signal; }; diff --git a/src/App_win.cpp b/src/App_win.cpp new file mode 100644 index 00000000..895f3bdf --- /dev/null +++ b/src/App_win.cpp @@ -0,0 +1,52 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#include "App.h" +#include "Options.h" +#include "Cpu.h" + + +void App::background() +{ + if (m_options->affinity() != -1L) { + Cpu::setAffinity(-1, m_options->affinity()); + } + + if (!m_options->background()) { + return; + } + + HWND hcon = GetConsoleWindow(); + if (hcon) { + ShowWindow(hcon, SW_HIDE); + } else { + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + CloseHandle(h); + FreeConsole(); + } +} diff --git a/src/Cpu.cpp b/src/Cpu.cpp index 53d81e58..2f0a1195 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -91,7 +91,7 @@ void Cpu::initCommon() m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0; } -# ifdef __x86_64__ +# if defined(__x86_64__) || defined(_M_AMD64) m_flags |= X86_64; # endif diff --git a/src/Options.h b/src/Options.h index 4955a7f3..d8d6e4ae 100644 --- a/src/Options.h +++ b/src/Options.h @@ -51,6 +51,7 @@ public: static inline Options* i() { return m_self; } static Options *parse(int argc, char **argv); + inline bool background() const { return m_background; } inline bool colors() const { return m_colors; } inline bool doubleHash() const { return m_doubleHash; } inline bool isReady() const { return m_ready; } From 981e043ada1f75878519466ea3cf617a4a89429f Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 13 Jun 2017 19:58:31 +0300 Subject: [PATCH 38/92] Add DoubleWorker class. --- CMakeLists.txt | 4 +- src/App.cpp | 2 +- src/Mem.h | 2 + src/crypto/CryptoNight.cpp | 20 +++++--- src/crypto/CryptoNight.h | 1 + src/net/Job.h | 3 +- src/net/JobResult.h | 7 +++ src/workers/DoubleWorker.cpp | 97 ++++++++++++++++++++++++++++++++++++ src/workers/DoubleWorker.h | 55 ++++++++++++++++++++ src/workers/SingleWorker.cpp | 2 +- src/workers/Worker.cpp | 2 - src/workers/Workers.cpp | 15 ++++-- src/workers/Workers.h | 2 +- 13 files changed, 195 insertions(+), 17 deletions(-) create mode 100644 src/workers/DoubleWorker.cpp create mode 100644 src/workers/DoubleWorker.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e1dd51ca..d2fb5262 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ set(HEADERS src/Options.h src/Summary.h src/version.h + src/workers/DoubleWorker.h src/workers/Handle.h src/workers/SingleWorker.h src/workers/Telemetry.h @@ -52,6 +53,7 @@ set(SOURCES src/net/Url.cpp src/Options.cpp src/Summary.cpp + src/workers/DoubleWorker.cpp src/workers/Handle.cpp src/workers/SingleWorker.cpp src/workers/Telemetry.cpp @@ -113,7 +115,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) add_definitions(/D_GNU_SOURCE) - #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) diff --git a/src/App.cpp b/src/App.cpp index 06e512b6..a92883c1 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -82,7 +82,7 @@ int App::exec() Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); - Workers::start(m_options->threads(), m_options->affinity(), m_options->nicehash()); + Workers::start(m_options->affinity(), m_options->nicehash()); m_network->connect(); diff --git a/src/Mem.h b/src/Mem.h index 89635e33..4198d8a2 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -48,9 +48,11 @@ public: static void *calloc(size_t num, size_t size); static void release(); + static inline bool isDoubleHash() { return m_doubleHash; } static inline bool isHugepagesAvailable() { return m_flags & HugepagesAvailable; } static inline bool isHugepagesEnabled() { return m_flags & HugepagesEnabled; } static inline int flags() { return m_flags; } + static inline int threads() { return m_threads; } private: static bool m_doubleHash; diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index e19e66ca..a463c9f9 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -38,38 +38,38 @@ static void cryptonight_av1_aesni(const void *input, size_t size, void *output, } -static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { +static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, false>(input, size, output, ctx); } -static void cryptonight_av3_softaes(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { +static void cryptonight_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { cryptonight_hash<0x80000, MEMORY, 0x1FFFF0, true>(input, size, output, ctx); } -static void cryptonight_av4_softaes_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { +static void cryptonight_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { cryptonight_double_hash<0x80000, MEMORY, 0x1FFFF0, true>(input, size, output, ctx); } #ifndef XMRIG_NO_AEON -static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { +static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx); } -static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { +static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, false>(input, size, output, ctx); } -static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { +static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { cryptonight_hash<0x40000, MEMORY_LITE, 0xFFFF0, true>(input, size, output, ctx); } -static void cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx) { +static void cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx) { cryptonight_double_hash<0x40000, MEMORY_LITE, 0xFFFF0, true>(input, size, output, ctx); } @@ -119,6 +119,12 @@ bool CryptoNight::init(int algo, int variant) } +void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx) +{ + cryptonight_hash_ctx(input, size, output, ctx); +} + + bool CryptoNight::selfTest(int algo) { if (cryptonight_hash_ctx == nullptr) { return false; diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 2ed5dfb2..29412730 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -51,6 +51,7 @@ class CryptoNight public: static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx); static bool init(int algo, int variant); + static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx); private: static bool selfTest(int algo); diff --git a/src/net/Job.h b/src/net/Job.h index 9848f128..262465fc 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -50,8 +50,9 @@ public: inline void setPoolId(int poolId) { m_poolId = poolId; } static bool fromHex(const char* in, unsigned int len, unsigned char* out); - static void toHex(const unsigned char* in, unsigned int len, char* out); + static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast(blob + 39); } static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } + static void toHex(const unsigned char* in, unsigned int len, char* out); private: int m_poolId; diff --git a/src/net/JobResult.h b/src/net/JobResult.h index ba067cdc..55ebdbd2 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -31,6 +31,13 @@ class JobResult { public: + inline JobResult() : poolId(0), nonce(0) {} + inline JobResult(int poolId, const char *jobId, uint32_t nonce, const uint8_t *result) : poolId(poolId), nonce(nonce) + { + memcpy(this->jobId, jobId, sizeof(this->jobId)); + memcpy(this->result, result, sizeof(this->result)); + } + char jobId[64]; int poolId; uint32_t nonce; diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp new file mode 100644 index 00000000..f7a56dbf --- /dev/null +++ b/src/workers/DoubleWorker.cpp @@ -0,0 +1,97 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "crypto/CryptoNight.h" +#include "workers/DoubleWorker.h" +#include "workers/Workers.h" + + +DoubleWorker::DoubleWorker(Handle *handle) + : Worker(handle), + m_nonce1(0), + m_nonce2(0) +{ +} + + +void DoubleWorker::start() +{ + while (true) { + if (Workers::isPaused()) { + do { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + while (Workers::isPaused()); + + consumeJob(); + } + + while (!Workers::isOutdated(m_sequence)) { + if ((m_count & 0xF) == 0) { + storeStats(); + } + + m_count += 2; + *Job::nonce(m_blob) = ++m_nonce1; + *Job::nonce(m_blob + m_job.size()) = ++m_nonce2; + + CryptoNight::hash(m_blob, m_job.size(), m_hash, m_ctx); + + if (*reinterpret_cast(m_hash + 24) < m_job.target()) { + Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce1, m_hash)); + } + + if (*reinterpret_cast(m_hash + 32 + 24) < m_job.target()) { + Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce2, m_hash + 32)); + } + + std::this_thread::yield(); + } + + consumeJob(); + } +} + + + +void DoubleWorker::consumeJob() +{ + m_job = Workers::job(); + m_sequence = Workers::sequence(); + + memcpy(m_blob, m_job.blob(), m_job.size()); + memcpy(m_blob + m_job.size(), m_job.blob(), m_job.size()); + + if (m_nicehash) { + m_nonce1 = (*Job::nonce(m_blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id); + m_nonce2 = (*Job::nonce(m_blob + m_job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads)); + } + else { + m_nonce1 = 0xffffffffU / (m_threads * 2) * m_id; + m_nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads); + } +} diff --git a/src/workers/DoubleWorker.h b/src/workers/DoubleWorker.h new file mode 100644 index 00000000..d062dac0 --- /dev/null +++ b/src/workers/DoubleWorker.h @@ -0,0 +1,55 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DOUBLEWORKER_H__ +#define __DOUBLEWORKER_H__ + + +#include "align.h" +#include "net/Job.h" +#include "net/JobResult.h" +#include "workers/Worker.h" + + +class Handle; + + +class DoubleWorker : public Worker +{ +public: + DoubleWorker(Handle *handle); + + void start() override; + +private: + void consumeJob(); + + Job m_job; + uint32_t m_nonce1; + uint32_t m_nonce2; + uint8_t m_hash[64]; + uint8_t m_blob[84 * 2]; +}; + + +#endif /* __SINGLEWORKER_H__ */ diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 3969e883..9c56b7d8 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -60,7 +60,7 @@ void SingleWorker::start() Workers::submit(m_result); } -// sched_yield(); + std::this_thread::yield(); } consumeJob(); diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 5478bcf7..1cede65f 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -40,8 +40,6 @@ Worker::Worker(Handle *handle) : m_count(0), m_sequence(0) { - handle->setWorker(this); - if (Cpu::threads() > 1 && handle->affinity() != -1L) { Cpu::setAffinity(m_id, handle->affinity()); } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index b3673445..27453fdb 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -26,6 +26,8 @@ #include "Console.h" #include "interfaces/IJobResultListener.h" +#include "Mem.h" +#include "workers/DoubleWorker.h" #include "workers/Handle.h" #include "workers/SingleWorker.h" #include "workers/Telemetry.h" @@ -67,8 +69,9 @@ void Workers::setJob(const Job &job) } -void Workers::start(int threads, int64_t affinity, bool nicehash) +void Workers::start(int64_t affinity, bool nicehash) { + const int threads = Mem::threads(); m_telemetry = new Telemetry(threads); uv_mutex_init(&m_mutex); @@ -103,8 +106,14 @@ void Workers::submit(const JobResult &result) void Workers::onReady(void *arg) { auto handle = static_cast(arg); - IWorker *worker = new SingleWorker(handle); - worker->start(); + if (Mem::isDoubleHash()) { + handle->setWorker(new DoubleWorker(handle)); + } + else { + handle->setWorker(new SingleWorker(handle)); + } + + handle->worker()->start(); } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 5e398109..6cf17de4 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -44,7 +44,7 @@ class Workers public: static Job job(); static void setJob(const Job &job); - static void start(int threads, int64_t affinity, bool nicehash); + static void start(int64_t affinity, bool nicehash); static void submit(const JobResult &result); static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } From 7c8a9677a1f835ff04015d0eb59a6080e1e56613 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 13 Jun 2017 20:03:43 +0300 Subject: [PATCH 39/92] Fix crash. --- src/crypto/CryptoNight_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/CryptoNight_p.h b/src/crypto/CryptoNight_p.h index 8a5268f4..fa2fa93a 100644 --- a/src/crypto/CryptoNight_p.h +++ b/src/crypto/CryptoNight_p.h @@ -363,7 +363,7 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, keccak((const uint8_t *) input + size, size, ctx->state1, 200); const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEMORY; + const uint8_t* l1 = ctx->memory + MEM; uint64_t* h0 = reinterpret_cast(ctx->state0); uint64_t* h1 = reinterpret_cast(ctx->state1); From 8ebb659cd66a1da3d35186c9c49ab795597ecf73 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 14 Jun 2017 09:03:03 +0300 Subject: [PATCH 40/92] Fix AEON donate port. --- src/net/Network.cpp | 2 +- src/workers/DoubleWorker.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/net/Network.cpp b/src/net/Network.cpp index eef52cd1..448f1ebb 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -205,7 +205,7 @@ void Network::onTimer(uv_timer_t *handle) auto net = static_cast(handle->data); if (!net->m_donate) { - auto url = std::make_unique("donate.xmrig.com", 443); + auto url = std::make_unique("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443); net->m_pools[0]->connect(url.get()); uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index f7a56dbf..41b9aec7 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -77,7 +77,6 @@ void DoubleWorker::start() } - void DoubleWorker::consumeJob() { m_job = Workers::job(); From 5af169fd7b453c86cbfbba09099a641b4ac96e1d Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 14 Jun 2017 16:11:01 +0300 Subject: [PATCH 41/92] Fix linux build. --- cmake/FindUV.cmake | 2 +- src/App.cpp | 3 ++ src/App_unix.cpp | 66 ++++++++++++++++++++++++++++++++++++++++ src/Console.cpp | 4 +++ src/Cpu_unix.cpp | 35 +++++++++++++++++++++ src/Mem_unix.cpp | 56 ++++++++++++++++++++++++++++++++++ src/Options.cpp | 3 +- src/crypto/CryptoNight.h | 1 + src/net/JobResult.h | 1 + src/net/Network_unix.cpp | 50 ++++++++++++++++++++++++++++++ src/net/Network_win.cpp | 2 +- 11 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 src/App_unix.cpp create mode 100644 src/net/Network_unix.cpp diff --git a/cmake/FindUV.cmake b/cmake/FindUV.cmake index c8a95e7a..e3c22d28 100644 --- a/cmake/FindUV.cmake +++ b/cmake/FindUV.cmake @@ -1,5 +1,5 @@ find_path(UV_INCLUDE_DIR NAMES uv.h) -find_library(UV_LIBRARY NAMES libuv) +find_library(UV_LIBRARY NAMES uv libuv) set(UV_LIBRARIES ${UV_LIBRARY}) set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR}) diff --git a/src/App.cpp b/src/App.cpp index a92883c1..8f6ed148 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -22,6 +22,7 @@ */ +#include #include @@ -92,6 +93,8 @@ int App::exec() free(m_network); free(m_options); + Mem::release(); + return r; } diff --git a/src/App_unix.cpp b/src/App_unix.cpp new file mode 100644 index 00000000..d001acb2 --- /dev/null +++ b/src/App_unix.cpp @@ -0,0 +1,66 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include +#include + + +#include "App.h" +#include "Console.h" +#include "Cpu.h" +#include "Options.h" + + +void App::background() +{ + if (m_options->affinity() != -1L) { + Cpu::setAffinity(-1, m_options->affinity()); + } + + if (!m_options->background()) { + return; + } + + int i = fork(); + if (i < 0) { + exit(1); + } + + if (i > 0) { + exit(0); + } + + i = setsid(); + + if (i < 0) { + LOG_ERR("setsid() failed (errno = %d)", errno); + } + + i = chdir("/"); + if (i < 0) { + LOG_ERR("chdir() failed (errno = %d)", errno); + } +} diff --git a/src/Console.cpp b/src/Console.cpp index b3b7ed3e..5df744db 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -23,9 +23,13 @@ #include +#include +#include +#include #include + #ifdef WIN32 # include # include "3rdparty/winansi.h" diff --git a/src/Cpu_unix.cpp b/src/Cpu_unix.cpp index 8140cd5f..1b7c6b0a 100644 --- a/src/Cpu_unix.cpp +++ b/src/Cpu_unix.cpp @@ -22,3 +22,38 @@ */ +#include +#include +#include + + +#include "Cpu.h" + + +void Cpu::init() +{ +# ifdef XMRIG_NO_LIBCPUID + m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); +# endif + + initCommon(); +} + + +void Cpu::setAffinity(int id, unsigned long mask) +{ + cpu_set_t set; + CPU_ZERO(&set); + + for (int i = 0; i < m_totalThreads; i++) { + if (mask & (1UL << i)) { + CPU_SET(i, &set); + } + } + + if (id == -1) { + sched_setaffinity(0, sizeof(&set), &set); + } else { + pthread_setaffinity_np(pthread_self(), sizeof(&set), &set); + } +} diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index a0690e79..231b48fc 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -22,5 +22,61 @@ */ +#include +#include +#include + + #include "crypto/CryptoNight.h" #include "Mem.h" +#include "Options.h" +#include "Console.h" + + +bool Mem::allocate(int algo, int threads, bool doubleHash) +{ + m_algo = algo; + m_threads = threads; + m_doubleHash = doubleHash; + + const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; + const size_t size = MEMORY * (threads * ratio + 1); + + m_flags |= HugepagesAvailable; + + m_memory = static_cast(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0)); + + if (m_memory == MAP_FAILED) { + m_memory = static_cast(_mm_malloc(size, 16)); + return true; + } + + m_flags |= HugepagesEnabled; + + if (madvise(m_memory, size, MADV_RANDOM | MADV_WILLNEED) != 0) { + LOG_ERR("madvise failed"); + } + + if (mlock(m_memory, size) == 0) { + m_flags |= Lock; + } + + return true; +} + + +void Mem::release() +{ + const int size = MEMORY * (m_threads + 1); + + if (m_flags & HugepagesEnabled) { + if (m_flags & Lock) { + munlock(m_memory, size); + } + + munmap(m_memory, size); + } + else { + _mm_free(m_memory); + } +} diff --git a/src/Options.cpp b/src/Options.cpp index c38f417b..8a8a3174 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -22,8 +22,9 @@ */ -#include #include +#include +#include #ifdef _MSC_VER diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 29412730..64fc0fd1 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -25,6 +25,7 @@ #define __CRYPTONIGHT_H__ +#include #include diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 55ebdbd2..87e3a645 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -25,6 +25,7 @@ #define __JOBRESULT_H__ +#include #include diff --git a/src/net/Network_unix.cpp b/src/net/Network_unix.cpp new file mode 100644 index 00000000..546d1b8a --- /dev/null +++ b/src/net/Network_unix.cpp @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "net/Network.h" +#include "version.h" + + +char *Network::userAgent() +{ + const size_t max = 128; + + char *buf = static_cast(malloc(max)); + int length = snprintf(buf, max, "%s/%s (Linux ", APP_NAME, APP_VERSION); + +# if defined(__x86_64__) + length += snprintf(buf + length, max - length, "x86_64) libuv/%s", uv_version_string()); +# else + length += snprintf(buf + length, max - length, "i686) libuv/%s", uv_version_string()); +# endif + +# ifdef __GNUC__ + length += snprintf(buf + length, max - length, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# endif + + return buf; +} diff --git a/src/net/Network_win.cpp b/src/net/Network_win.cpp index 15b358b5..6ae5e322 100644 --- a/src/net/Network_win.cpp +++ b/src/net/Network_win.cpp @@ -64,7 +64,7 @@ char *Network::userAgent() # ifdef __GNUC__ length += snprintf(buf + length, max - length, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); -#elif _MSC_VER +# elif _MSC_VER length += snprintf(buf + length, max - length, " msvc/%d", MSVC_VERSION); # endif From 33d752bcaaa1452ce49ca62ae1de19cabaf4df5c Mon Sep 17 00:00:00 2001 From: xmrig Date: Wed, 14 Jun 2017 16:18:13 +0300 Subject: [PATCH 42/92] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fb3f44e2..241a1eea 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Since version 0.8.0. ## Build ### Ubuntu (Debian-based distros) ``` -sudo apt-get install git build-essential cmake libcurl4-openssl-dev +sudo apt-get install git build-essential cmake libuv1-dev git clone https://github.com/xmrig/xmrig.git cd xmrig mkdir build @@ -81,6 +81,16 @@ cd build cmake .. -DCMAKE_BUILD_TYPE=Release make ``` +#### gcc 7.1 +``` +sudo add-apt-repository ppa:jonathonf/gcc-7.1 +sudo apt-get update +apt-get install gcc-7 g++-7 +``` +When run cmake manually specify C and C++ compiler: +``` +cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 +``` ### Windows It's complicated, you need [MSYS2](http://www.msys2.org/), custom libcurl build, and of course CMake too. From babc48f76758f82ed46114dd0e85f2eb96363509 Mon Sep 17 00:00:00 2001 From: xmrig Date: Wed, 14 Jun 2017 16:42:00 +0300 Subject: [PATCH 43/92] Update README.md --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 241a1eea..1f22ed13 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,9 @@ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CX ``` ### Windows -It's complicated, you need [MSYS2](http://www.msys2.org/), custom libcurl build, and of course CMake too. +There two options Microsoft Visual Studio 2015+ or [MSYS2](http://www.msys2.org/) both required [libuv](https://github.com/libuv/libuv) build and cmake. +#### MSYS2 Necessary MSYS2 packages: ``` pacman -Sy @@ -103,13 +104,15 @@ pacman -S make pacman -S mingw-w64-x86_64-cmake pacman -S mingw-w64-x86_64-pkg-config ``` -Configure options for libcurl: +CMake build: ``` -./configure --disable-shared --enable-optimize --enable-threaded-resolver --disable-libcurl-option --disable-ares --disable-rt --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual --disable-ipv6 --disable-sspi --disable-crypto-auth --disable-ntlm-wb --disable-tls-srp --disable-unix-sockets --without-zlib --without-winssl --without-ssl --without-libssh2 --without-nghttp2 --disable-cookies --without-ca-bundle --without-librtmp +cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DUV_INCLUDE_DIR="c:\\libuv\include" -DUV_LIBRARY="c:\\libuv\.libs\libuv.a" +make ``` -CMake options: + +#### Microsoft Visual Studio ``` -cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCURL_INCLUDE_DIR="c:\\curl-7.53.1\include" -DCURL_LIBRARY="c:\\curl-7.53.1\lib\.libs" +`cmake .. -G "Visual Studio 14 2015 Win64" -T v140_xp -DCMAKE_BUILD_TYPE=Release -DUV_INCLUDE_DIR=c:\\libuv\include -DUV_LIBRARY=c:\\libuv\Release\lib\libuv.lib` ``` ### Optional features From e3689ccb1a2c52479ffea29eca5d7017d45f13f1 Mon Sep 17 00:00:00 2001 From: xmrig Date: Wed, 14 Jun 2017 16:49:47 +0300 Subject: [PATCH 44/92] Move build instructions to Wiki --- README.md | 51 +-------------------------------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/README.md b/README.md index 1f22ed13..70485e0a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of * [Download](#download) * [Usage](#usage) * [Algorithm variations](#algorithm-variations) -* [Build](#build) +* [Build](https://github.com/xmrig/xmrig/wiki/Build) * [Common Issues](#common-issues) * [Other information](#other-information) * [Donations](#donations) @@ -70,55 +70,6 @@ Since version 0.8.0. * `--av=3` Software AES implementation. * `--av=4` Lower power mode (double hash) of `3`. -## Build -### Ubuntu (Debian-based distros) -``` -sudo apt-get install git build-essential cmake libuv1-dev -git clone https://github.com/xmrig/xmrig.git -cd xmrig -mkdir build -cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -make -``` -#### gcc 7.1 -``` -sudo add-apt-repository ppa:jonathonf/gcc-7.1 -sudo apt-get update -apt-get install gcc-7 g++-7 -``` -When run cmake manually specify C and C++ compiler: -``` -cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 -``` - -### Windows -There two options Microsoft Visual Studio 2015+ or [MSYS2](http://www.msys2.org/) both required [libuv](https://github.com/libuv/libuv) build and cmake. - -#### MSYS2 -Necessary MSYS2 packages: -``` -pacman -Sy -pacman -S mingw-w64-x86_64-gcc -pacman -S make -pacman -S mingw-w64-x86_64-cmake -pacman -S mingw-w64-x86_64-pkg-config -``` -CMake build: -``` -cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DUV_INCLUDE_DIR="c:\\libuv\include" -DUV_LIBRARY="c:\\libuv\.libs\libuv.a" -make -``` - -#### Microsoft Visual Studio -``` -`cmake .. -G "Visual Studio 14 2015 Win64" -T v140_xp -DCMAKE_BUILD_TYPE=Release -DUV_INCLUDE_DIR=c:\\libuv\include -DUV_LIBRARY=c:\\libuv\Release\lib\libuv.lib` -``` - -### Optional features -`-DWITH_LIBCPUID=OFF` Disable libcpuid. Auto configuration of CPU after this will be very limited. -`-DWITH_AEON=OFF` Disable CryptoNight-Lite support. - ## Common Issues ### HUGE PAGES unavailable * Run XMRig as Administrator. From 599117abde895a67d677f496473bb19503d8a793 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 14 Jun 2017 19:13:02 +0300 Subject: [PATCH 45/92] Prepare for OS X. --- CMakeLists.txt | 24 ++++++++++++++++++++---- src/net/Network_mac.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/net/Network_mac.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d2fb5262..d846fd98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,8 +85,21 @@ if (WIN32) ) set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) +elseif (APPLE) + set(SOURCES_OS + src/App_unix.cpp + src/Cpu_unix.cpp + src/Mem_unix.cpp + src/net/Network_mac.cpp + ) else() - set(SOURCES_OS src/Cpu_unix.cpp src/Mem_unix.cpp) + set(SOURCES_OS + src/App_unix.cpp + src/Cpu_unix.cpp + src/Mem_unix.cpp + src/net/Network_unix.cpp + ) + set(EXTRA_LIBS pthread) endif() @@ -105,17 +118,17 @@ endif() # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html if (CMAKE_CXX_COMPILER_ID MATCHES GNU) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -fno-exceptions") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") add_definitions(/D_GNU_SOURCE) - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") + #set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2") elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) @@ -124,7 +137,10 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") endif() diff --git a/src/net/Network_mac.cpp b/src/net/Network_mac.cpp new file mode 100644 index 00000000..79b58c51 --- /dev/null +++ b/src/net/Network_mac.cpp @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "net/Network.h" +#include "version.h" + + +char *Network::userAgent() +{ + const size_t max = 128; + + char *buf = static_cast(malloc(max)); + snprintf(buf, max, "%s/%s", APP_NAME, APP_VERSION); + + return buf; +} From 1bf428f8da1836b9b10440be71114b78ffa80445 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 14 Jun 2017 20:37:59 +0300 Subject: [PATCH 46/92] Initial OS X support --- CMakeLists.txt | 4 ++-- src/Console.cpp | 1 - src/Mem_unix.cpp | 4 ++++ src/Options.cpp | 4 +++- src/Summary.cpp | 4 +++- src/net/Network.h | 2 +- src/workers/Workers.cpp | 6 ++++-- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d846fd98..126c9580 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,10 +138,10 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -fmerge-all-constants") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants") endif() diff --git a/src/Console.cpp b/src/Console.cpp index 5df744db..2ce56ee1 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -22,7 +22,6 @@ */ -#include #include #include #include diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 231b48fc..eb3f9af6 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -44,7 +44,11 @@ bool Mem::allocate(int algo, int threads, bool doubleHash) m_flags |= HugepagesAvailable; +# if defined(__APPLE__) + m_memory = static_cast(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0)); +# else m_memory = static_cast(mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0)); +# endif if (m_memory == MAP_FAILED) { m_memory = static_cast(_mm_malloc(size, 16)); diff --git a/src/Options.cpp b/src/Options.cpp index 8a8a3174..111543ec 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -396,7 +396,9 @@ void Options::showVersion() { printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ -# if defined(__GNUC__) +# if defined(__clang__) + " with clang " __clang_version__); +# elif defined(__GNUC__) " with GCC"); printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); # elif defined(_MSC_VER) diff --git a/src/Summary.cpp b/src/Summary.cpp index 8c7d3ea3..8db80893 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -37,7 +37,9 @@ static void print_versions() { char buf[16]; -# if defined(__GNUC__) +# if defined(__clang__) + snprintf(buf, 16, " clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__); +# elif defined(__GNUC__) snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); # elif defined(_MSC_VER) snprintf(buf, 16, " MSVC/%d", MSVC_VERSION); diff --git a/src/net/Network.h b/src/net/Network.h index d9192c9f..2859abc8 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -50,7 +50,7 @@ public: protected: void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; - void onJobResult(const JobResult &result); + void onJobResult(const JobResult &result) override; void onLoginCredentialsRequired(Client *client) override; void onLoginSuccess(Client *client) override; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 27453fdb..b512d282 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -54,7 +54,7 @@ Job Workers::job() Job job = m_job; uv_rwlock_rdunlock(&m_rwlock); - return std::move(job); + return job; } @@ -139,7 +139,9 @@ void Workers::onResult(uv_async_t *handle) void Workers::onTick(uv_timer_t *handle) { for (Handle *handle : m_workers) { - m_telemetry->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp()); + if (handle->worker()) { + m_telemetry->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp()); + } } if ((m_ticks++ & 0xF) == 0) { From 555eee8236d0476e7eed132cf3474f1ba1532175 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 14 Jun 2017 20:51:47 +0300 Subject: [PATCH 47/92] Add Cpu_mac.cpp --- CMakeLists.txt | 2 +- src/Cpu_mac.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/Cpu_mac.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 126c9580..92b075eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,7 @@ if (WIN32) elseif (APPLE) set(SOURCES_OS src/App_unix.cpp - src/Cpu_unix.cpp + src/Cpu_mac.cpp src/Mem_unix.cpp src/net/Network_mac.cpp ) diff --git a/src/Cpu_mac.cpp b/src/Cpu_mac.cpp new file mode 100644 index 00000000..1b7c6b0a --- /dev/null +++ b/src/Cpu_mac.cpp @@ -0,0 +1,59 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include + + +#include "Cpu.h" + + +void Cpu::init() +{ +# ifdef XMRIG_NO_LIBCPUID + m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); +# endif + + initCommon(); +} + + +void Cpu::setAffinity(int id, unsigned long mask) +{ + cpu_set_t set; + CPU_ZERO(&set); + + for (int i = 0; i < m_totalThreads; i++) { + if (mask & (1UL << i)) { + CPU_SET(i, &set); + } + } + + if (id == -1) { + sched_setaffinity(0, sizeof(&set), &set); + } else { + pthread_setaffinity_np(pthread_self(), sizeof(&set), &set); + } +} From faf14f5e5a030545ccc3e66f995551427d6c897b Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 14 Jun 2017 21:13:04 +0300 Subject: [PATCH 48/92] Fixes for OS X. --- src/Cpu_mac.cpp | 14 -------------- src/Cpu_unix.cpp | 4 ++++ src/net/Network_mac.cpp | 3 +-- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/Cpu_mac.cpp b/src/Cpu_mac.cpp index 1b7c6b0a..3b6c4400 100644 --- a/src/Cpu_mac.cpp +++ b/src/Cpu_mac.cpp @@ -42,18 +42,4 @@ void Cpu::init() void Cpu::setAffinity(int id, unsigned long mask) { - cpu_set_t set; - CPU_ZERO(&set); - - for (int i = 0; i < m_totalThreads; i++) { - if (mask & (1UL << i)) { - CPU_SET(i, &set); - } - } - - if (id == -1) { - sched_setaffinity(0, sizeof(&set), &set); - } else { - pthread_setaffinity_np(pthread_self(), sizeof(&set), &set); - } } diff --git a/src/Cpu_unix.cpp b/src/Cpu_unix.cpp index 1b7c6b0a..cddf54f1 100644 --- a/src/Cpu_unix.cpp +++ b/src/Cpu_unix.cpp @@ -42,6 +42,10 @@ void Cpu::init() void Cpu::setAffinity(int id, unsigned long mask) { + if (id == -1) { + return; + } + cpu_set_t set; CPU_ZERO(&set); diff --git a/src/net/Network_mac.cpp b/src/net/Network_mac.cpp index 79b58c51..c3c42a3e 100644 --- a/src/net/Network_mac.cpp +++ b/src/net/Network_mac.cpp @@ -24,7 +24,6 @@ #include - #include "net/Network.h" #include "version.h" @@ -34,7 +33,7 @@ char *Network::userAgent() const size_t max = 128; char *buf = static_cast(malloc(max)); - snprintf(buf, max, "%s/%s", APP_NAME, APP_VERSION); + snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__); return buf; } From 1587fb27d2311e0658bf48b8b926c4b3e1549188 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 14 Jun 2017 21:33:20 +0300 Subject: [PATCH 49/92] Fixes. --- CMakeLists.txt | 1 + src/Cpu_unix.cpp | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 92b075eb..9bce386c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ if (WIN32) src/net/Network_win.cpp ) + add_definitions(/DWIN32) set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv) elseif (APPLE) set(SOURCES_OS diff --git a/src/Cpu_unix.cpp b/src/Cpu_unix.cpp index cddf54f1..1b7c6b0a 100644 --- a/src/Cpu_unix.cpp +++ b/src/Cpu_unix.cpp @@ -42,10 +42,6 @@ void Cpu::init() void Cpu::setAffinity(int id, unsigned long mask) { - if (id == -1) { - return; - } - cpu_set_t set; CPU_ZERO(&set); From 70b0a39dc8383a189d78db27c69e30c0bf0be619 Mon Sep 17 00:00:00 2001 From: xmrig Date: Wed, 14 Jun 2017 22:18:29 +0300 Subject: [PATCH 50/92] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2005d74d..343f0731 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v1.0.0 +- Miner complete rewritten in C++ with libuv. +- Removed dependency on libcurl. + # v0.8.2 - Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). - Fixed gcc 7.1 support. From ccc2d775927334b15e6b69e3138f313210ea8665 Mon Sep 17 00:00:00 2001 From: xmrig Date: Thu, 15 Jun 2017 09:41:27 +0300 Subject: [PATCH 51/92] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 343f0731..400eff76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # v1.0.0 - Miner complete rewritten in C++ with libuv. +- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. +- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). - Removed dependency on libcurl. +- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. + +# v0.8.2 +- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). # v0.8.2 - Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). From d1bf9ddc3fd1a43b027d50ffab86cbb3d36d5188 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 15 Jun 2017 18:09:29 +0300 Subject: [PATCH 52/92] Add missing file. --- src/3rdparty/libcpuid/masm-x64.asm | 359 +++++++++++++++++++++++++++++ 1 file changed, 359 insertions(+) create mode 100644 src/3rdparty/libcpuid/masm-x64.asm diff --git a/src/3rdparty/libcpuid/masm-x64.asm b/src/3rdparty/libcpuid/masm-x64.asm new file mode 100644 index 00000000..51e98651 --- /dev/null +++ b/src/3rdparty/libcpuid/masm-x64.asm @@ -0,0 +1,359 @@ + +.code +; procedure exec_cpuid +; Signature: void exec_cpiud(uint32_t *regs) +exec_cpuid Proc + push rbx + push rcx + push rdx + push rdi + + mov rdi, rcx + + mov eax, [rdi] + mov ebx, [rdi+4] + mov ecx, [rdi+8] + mov edx, [rdi+12] + + cpuid + + mov [rdi], eax + mov [rdi+4], ebx + mov [rdi+8], ecx + mov [rdi+12], edx + pop rdi + pop rdx + pop rcx + pop rbx + ret +exec_cpuid endp + +; procedure cpu_rdtsc +; Signature: void cpu_rdtsc(uint64_t *result) +cpu_rdtsc Proc + push rdx + rdtsc + mov [rcx], eax + mov [rcx+4], edx + pop rdx + ret +cpu_rdtsc endp + +; procedure busy_sse_loop +; Signature: void busy_sse_loop(int cycles) +busy_sse_loop Proc + ; save xmm6 & xmm7 into the shadow area, as Visual C++ 2008 + ; expects that we don't touch them: + movups [rsp + 8], xmm6 + movups [rsp + 24], xmm7 + + xorps xmm0, xmm0 + xorps xmm1, xmm1 + xorps xmm2, xmm2 + xorps xmm3, xmm3 + xorps xmm4, xmm4 + xorps xmm5, xmm5 + xorps xmm6, xmm6 + xorps xmm7, xmm7 + ; -- + align 16 +bsLoop: + ; 0: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 1: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 2: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 3: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 4: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 5: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 6: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 7: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 8: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 9: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 10: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 11: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 12: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 13: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 14: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 15: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 16: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 17: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 18: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 19: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 20: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 21: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 22: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 23: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 24: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 25: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 26: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 27: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 28: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 29: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 30: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; 31: + addps xmm0, xmm1 + addps xmm1, xmm2 + addps xmm2, xmm3 + addps xmm3, xmm4 + addps xmm4, xmm5 + addps xmm5, xmm6 + addps xmm6, xmm7 + addps xmm7, xmm0 + ; ---------------------- + dec ecx + jnz bsLoop + + ; restore xmm6 & xmm7: + movups xmm6, [rsp + 8] + movups xmm7, [rsp + 24] + ret +busy_sse_loop endp + +END From fcb7b0fb3e1de6345855c38de4e8a7a0518bbf24 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 15 Jun 2017 21:00:25 +0300 Subject: [PATCH 53/92] Rename Telemetry class to Hashrate. --- CMakeLists.txt | 4 +-- src/Console.cpp | 2 +- src/workers/{Telemetry.cpp => Hashrate.cpp} | 26 +++++++++++++---- src/workers/{Telemetry.h => Hashrate.h} | 11 ++++---- src/workers/Workers.cpp | 31 ++++++--------------- src/workers/Workers.h | 4 +-- 6 files changed, 40 insertions(+), 38 deletions(-) rename src/workers/{Telemetry.cpp => Hashrate.cpp} (86%) rename src/workers/{Telemetry.h => Hashrate.h} (90%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9bce386c..d301b6ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,8 @@ set(HEADERS src/version.h src/workers/DoubleWorker.h src/workers/Handle.h + src/workers/Hashrate.h src/workers/SingleWorker.h - src/workers/Telemetry.h src/workers/Worker.h src/workers/Workers.h ) @@ -55,8 +55,8 @@ set(SOURCES src/Summary.cpp src/workers/DoubleWorker.cpp src/workers/Handle.cpp + src/workers/Hashrate.cpp src/workers/SingleWorker.cpp - src/workers/Telemetry.cpp src/workers/Worker.cpp src/workers/Workers.cpp src/xmrig.cpp diff --git a/src/Console.cpp b/src/Console.cpp index 2ce56ee1..558c1e8d 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -28,9 +28,9 @@ #include - #ifdef WIN32 # include +# include # include "3rdparty/winansi.h" #endif diff --git a/src/workers/Telemetry.cpp b/src/workers/Hashrate.cpp similarity index 86% rename from src/workers/Telemetry.cpp rename to src/workers/Hashrate.cpp index b1a36633..3a6cbda2 100644 --- a/src/workers/Telemetry.cpp +++ b/src/workers/Hashrate.cpp @@ -23,14 +23,14 @@ #include -#include +#include #include #include "Console.h" -#include "workers/Telemetry.h" +#include "workers/Hashrate.h" -Telemetry::Telemetry(int threads) : +Hashrate::Hashrate(int threads) : m_threads(threads) { m_counts = new uint64_t*[threads]; @@ -48,7 +48,23 @@ Telemetry::Telemetry(int threads) : } -double Telemetry::calc(size_t threadId, size_t ms) const +double Hashrate::calc(size_t ms) const +{ + double result = .0; + double data; + + for (int i = 0; i < m_threads; ++i) { + data = calc(i, ms); + if (std::isnormal(data)) { + result += data; + } + } + + return result; +} + + +double Hashrate::calc(size_t threadId, size_t ms) const { using namespace std::chrono; const uint64_t now = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); @@ -97,7 +113,7 @@ double Telemetry::calc(size_t threadId, size_t ms) const } -void Telemetry::add(size_t threadId, uint64_t count, uint64_t timestamp) +void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) { const size_t top = m_top[threadId]; m_counts[threadId][top] = count; diff --git a/src/workers/Telemetry.h b/src/workers/Hashrate.h similarity index 90% rename from src/workers/Telemetry.h rename to src/workers/Hashrate.h index 007ba536..b225e1ca 100644 --- a/src/workers/Telemetry.h +++ b/src/workers/Hashrate.h @@ -21,17 +21,18 @@ * along with this program. If not, see . */ -#ifndef __TELEMETRY_H__ -#define __TELEMETRY_H__ +#ifndef __HASHRATE_H__ +#define __HASHRATE_H__ #include -class Telemetry +class Hashrate { public: - Telemetry(int threads); + Hashrate(int threads); + double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; void add(size_t threadId, uint64_t count, uint64_t timestamp); @@ -46,4 +47,4 @@ private: }; -#endif /* __TELEMETRY_H__ */ +#endif /* __HASHRATE_H__ */ diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index b512d282..592bc17d 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -29,18 +29,18 @@ #include "Mem.h" #include "workers/DoubleWorker.h" #include "workers/Handle.h" +#include "workers/Hashrate.h" #include "workers/SingleWorker.h" -#include "workers/Telemetry.h" #include "workers/Workers.h" +Hashrate *Workers::m_hashrate = nullptr; IJobResultListener *Workers::m_listener = nullptr; Job Workers::m_job; std::atomic Workers::m_paused; std::atomic Workers::m_sequence; std::list Workers::m_queue; std::vector Workers::m_workers; -Telemetry *Workers::m_telemetry = nullptr; uint64_t Workers::m_ticks = 0; uv_async_t Workers::m_async; uv_mutex_t Workers::m_mutex; @@ -72,7 +72,7 @@ void Workers::setJob(const Job &job) void Workers::start(int64_t affinity, bool nicehash) { const int threads = Mem::threads(); - m_telemetry = new Telemetry(threads); + m_hashrate = new Hashrate(threads); uv_mutex_init(&m_mutex); uv_rwlock_init(&m_rwlock); @@ -139,29 +139,14 @@ void Workers::onResult(uv_async_t *handle) void Workers::onTick(uv_timer_t *handle) { for (Handle *handle : m_workers) { - if (handle->worker()) { - m_telemetry->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp()); + if (!handle->worker()) { + return; } + + m_hashrate->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp()); } if ((m_ticks++ & 0xF) == 0) { - double hps = 0.0; - double telem; - bool normal = true; - - for (Handle *handle : m_workers) { - telem = m_telemetry->calc(handle->threadId(), 2500); - if (!std::isnormal(telem)) { - normal = false; - break; - } - else { - hps += telem; - } - } - - if (normal) { - LOG_NOTICE("%03.1f H/s", hps); - } + LOG_NOTICE("%03.1f H/s", m_hashrate->calc(2500)); } } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 6cf17de4..0990fc45 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -35,8 +35,8 @@ class Handle; +class Hashrate; class IJobResultListener; -class Telemetry; class Workers @@ -58,13 +58,13 @@ private: static void onResult(uv_async_t *handle); static void onTick(uv_timer_t *handle); + static Hashrate *m_hashrate; static IJobResultListener *m_listener; static Job m_job; static std::atomic m_paused; static std::atomic m_sequence; static std::list m_queue; static std::vector m_workers; - static Telemetry *m_telemetry; static uint64_t m_ticks; static uv_async_t m_async; static uv_mutex_t m_mutex; From e759ddca4933be6b538bdbe9222b906b15b47ae4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 15 Jun 2017 22:30:56 +0300 Subject: [PATCH 54/92] Handle "Unauthenticated" error. --- src/net/Client.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index eb776da1..6fdcf331 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -32,6 +32,11 @@ #include "net/Url.h" +#ifdef _MSC_VER +# define strncasecmp(x,y,z) _strnicmp(x,y,z) +#endif + + Client::Client(int id, IClientListener *listener) : m_keepAlive(false), m_host(nullptr), @@ -317,9 +322,10 @@ void Client::parseNotification(const char *method, const json_t *params, const j void Client::parseResponse(int64_t id, const json_t *result, const json_t *error) { if (json_is_object(error)) { - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + const char *message = json_string_value(json_object_get(error, "message")); + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, message, json_integer_value(json_object_get(error, "code"))); - if (id == 1) { + if (id == 1 || (message && strncasecmp(message, "Unauthenticated", 15) == 0)) { close(); } From 4e4c54314bcb36cbb68f88ec515b597fd29a006f Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 16 Jun 2017 10:19:14 +0300 Subject: [PATCH 55/92] New hashtable report. --- src/net/Network.cpp | 12 ++++++++--- src/workers/Hashrate.cpp | 44 +++++++++++++++++++++++++++++++++++++--- src/workers/Hashrate.h | 5 +++++ src/workers/Workers.cpp | 3 ++- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 448f1ebb..20480eca 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -107,7 +107,13 @@ void Network::onJobReceived(Client *client, const Job &job) void Network::onJobResult(const JobResult &result) { - LOG_NOTICE("SHARE FOUND"); + if (m_options->colors()) { + LOG_NOTICE("\x1B[01;32mSHARE FOUND"); + } + else { + LOG_NOTICE("SHARE FOUND"); + } + m_pools[result.poolId]->submit(result); } @@ -156,8 +162,8 @@ void Network::addPool(const Url *url) void Network::setJob(Client *client, const Job &job) { - if (m_options->colors()){ - LOG_INFO("\x1B[01;33mnew job\x1B[0m from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff()); + if (m_options->colors()) { + LOG_INFO("\x1B[01;35mnew job\x1B[0m from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff()); } else { diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 3a6cbda2..53443c95 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -22,15 +22,28 @@ */ -#include -#include #include +#include +#include #include "Console.h" +#include "Options.h" #include "workers/Hashrate.h" +inline const char *format(double h, char* buf, size_t size) +{ + if (std::isnormal(h)) { + snprintf(buf, size, "%03.1f", h); + return buf; + } + + return "n/a"; +} + + Hashrate::Hashrate(int threads) : + m_highest(0.0), m_threads(threads) { m_counts = new uint64_t*[threads]; @@ -50,7 +63,7 @@ Hashrate::Hashrate(int threads) : double Hashrate::calc(size_t ms) const { - double result = .0; + double result = 0.0; double data; for (int i = 0; i < m_threads; ++i) { @@ -121,3 +134,28 @@ void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) m_top[threadId] = (top + 1) & kBucketMask; } + + +void Hashrate::print() +{ + char num1[8]; + char num2[8]; + char num3[8]; + char num4[8]; + + LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m highest: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s highest: %s H/s", + format(calc(2500), num1, sizeof(num1)), + format(calc(60000), num2, sizeof(num2)), + format(calc(900000), num3, sizeof(num3)), + format(m_highest, num4, sizeof(num4)) + ); +} + + +void Hashrate::updateHighest() +{ + double highest = calc(2500); + if (std::isnormal(highest) && highest > m_highest) { + m_highest = highest; + } +} diff --git a/src/workers/Hashrate.h b/src/workers/Hashrate.h index b225e1ca..c6f3cf27 100644 --- a/src/workers/Hashrate.h +++ b/src/workers/Hashrate.h @@ -35,11 +35,16 @@ public: double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; void add(size_t threadId, uint64_t count, uint64_t timestamp); + void print(); + void updateHighest(); + + inline double highest() const { return m_highest; } private: constexpr static size_t kBucketSize = 2 << 11; constexpr static size_t kBucketMask = kBucketSize - 1; + double m_highest; int m_threads; uint32_t* m_top; uint64_t** m_counts; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 592bc17d..de3f7a0e 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -147,6 +147,7 @@ void Workers::onTick(uv_timer_t *handle) } if ((m_ticks++ & 0xF) == 0) { - LOG_NOTICE("%03.1f H/s", m_hashrate->calc(2500)); + m_hashrate->updateHighest(); + m_hashrate->print(); } } From fed163568e71a386e9fbd37d9c13007cec844e44 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 16 Jun 2017 11:08:10 +0300 Subject: [PATCH 56/92] Add option "--print-time". --- src/Options.cpp | 13 +++++++++++++ src/Options.h | 2 ++ src/workers/Hashrate.cpp | 15 +++++++++++++++ src/workers/Hashrate.h | 4 ++++ src/workers/Workers.cpp | 3 +-- 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 111543ec..4da75923 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -72,6 +72,7 @@ Options:\n\ --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ --safe safe adjust threads and av settings for current CPU\n\ --nicehash enable nicehash support\n\ + --print-time=N print hashrate report every N seconds\n\ -h, --help display this help and exit\n\ -V, --version output version information and exit\n\ "; @@ -94,6 +95,7 @@ static struct option const options[] = { { "nicehash", 0, nullptr, 1006 }, { "no-color", 0, nullptr, 1002 }, { "pass", 1, nullptr, 'p' }, + { "print-time", 1, nullptr, 1007 }, { "retries", 1, nullptr, 'r' }, { "retry-pause", 1, nullptr, 'R' }, { "safe", 0, nullptr, 1005 }, @@ -144,6 +146,7 @@ Options::Options(int argc, char **argv) : m_algoVariant(0), m_donateLevel(kDonateLevel), m_maxCpuUsage(75), + m_printTime(60), m_retries(5), m_retryPause(5), m_threads(0), @@ -360,6 +363,16 @@ bool Options::parseArg(int key, char *arg) m_nicehash = true; break; + case 1007: /* --print-time */ + v = strtol(arg, nullptr, 10); + if (v < 0 || v > 1000) { + showUsage(1); + return false; + } + + m_printTime = v; + break; + default: showUsage(1); return false; diff --git a/src/Options.h b/src/Options.h index d8d6e4ae..c100f6d6 100644 --- a/src/Options.h +++ b/src/Options.h @@ -64,6 +64,7 @@ public: inline int algo() const { return m_algo; } inline int algoVariant() const { return m_algoVariant; } inline int donateLevel() const { return m_donateLevel; } + inline int printTime() const { return m_printTime; } inline int retries() const { return m_retries; } inline int retryPause() const { return m_retryPause; } inline int threads() const { return m_threads; } @@ -103,6 +104,7 @@ private: int m_algoVariant; int m_donateLevel; int m_maxCpuUsage; + int m_printTime; int m_retries; int m_retryPause; int m_threads; diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 53443c95..7f2f7ee1 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -58,6 +58,15 @@ Hashrate::Hashrate(int threads) : memset(m_counts[0], 0, sizeof(uint64_t) * kBucketSize); memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize); } + + const int printTime = Options::i()->printTime(); + + if (printTime > 0) { + uv_timer_init(uv_default_loop(), &m_timer); + m_timer.data = this; + + uv_timer_start(&m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000); + } } @@ -159,3 +168,9 @@ void Hashrate::updateHighest() m_highest = highest; } } + + +void Hashrate::onReport(uv_timer_t *handle) +{ + static_cast(handle->data)->print(); +} diff --git a/src/workers/Hashrate.h b/src/workers/Hashrate.h index c6f3cf27..9ba0b0bf 100644 --- a/src/workers/Hashrate.h +++ b/src/workers/Hashrate.h @@ -26,6 +26,7 @@ #include +#include class Hashrate @@ -41,6 +42,8 @@ public: inline double highest() const { return m_highest; } private: + static void onReport(uv_timer_t *handle); + constexpr static size_t kBucketSize = 2 << 11; constexpr static size_t kBucketMask = kBucketSize - 1; @@ -49,6 +52,7 @@ private: uint32_t* m_top; uint64_t** m_counts; uint64_t** m_timestamps; + uv_timer_t m_timer; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index de3f7a0e..433bdcd8 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -27,6 +27,7 @@ #include "Console.h" #include "interfaces/IJobResultListener.h" #include "Mem.h" +#include "Options.h" #include "workers/DoubleWorker.h" #include "workers/Handle.h" #include "workers/Hashrate.h" @@ -102,7 +103,6 @@ void Workers::submit(const JobResult &result) } - void Workers::onReady(void *arg) { auto handle = static_cast(arg); @@ -148,6 +148,5 @@ void Workers::onTick(uv_timer_t *handle) if ((m_ticks++ & 0xF) == 0) { m_hashrate->updateHighest(); - m_hashrate->print(); } } From b8089e637aa85d8ca42eb83a45710f2a39423171 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 16 Jun 2017 11:32:34 +0300 Subject: [PATCH 57/92] Print pool urls in summary. --- src/Summary.cpp | 38 +++++++++++++++++++++++--------------- src/version.h | 2 +- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 8db80893..8f917d44 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -28,6 +28,7 @@ #include "Console.h" #include "Cpu.h" #include "Mem.h" +#include "net/Url.h" #include "Options.h" #include "Summary.h" #include "version.h" @@ -99,22 +100,28 @@ static void print_threads() buf[0] = '\0'; } - if (Options::i()->colors()) { - Console::i()->text("\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s", - Options::i()->threads(), - Options::i()->algoName(), - Options::i()->algoVariant(), - Options::i()->donateLevel(), - Options::i()->nicehash() ? ", nicehash" : "", buf); - } - else { - Console::i()->text(" * THREADS: %d, %s, av=%d, donate=%d%%%s%s", - Options::i()->threads(), - Options::i()->algoName(), - Options::i()->algoVariant(), - Options::i()->donateLevel(), - Options::i()->nicehash() ? ", nicehash" : "", buf); + Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s%s", + Options::i()->threads(), + Options::i()->algoName(), + Options::i()->algoVariant(), + Options::i()->donateLevel(), + Options::i()->nicehash() ? ", nicehash" : "", buf); +} + + +static void print_pools() +{ + Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #1: \x1B[01;36m%s:%d" : " * POOL #1: %s:%d", + Options::i()->url()->host(), + Options::i()->url()->port()); + + if (!Options::i()->backupUrl()) { + return; } + + Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #2: \x1B[01;36m%s:%d" : " * POOL #2: %s:%d", + Options::i()->backupUrl()->host(), + Options::i()->backupUrl()->port()); } @@ -124,6 +131,7 @@ void Summary::print() print_memory(); print_cpu(); print_threads(); + print_pools(); } diff --git a/src/version.h b/src/version.h index 326b6567..8dc9a107 100644 --- a/src/version.h +++ b/src/version.h @@ -27,7 +27,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "1.0.0-dev" +#define APP_VERSION "1.0.0" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" From 6fd4d99fa126d52c9d4b7db27f2108faaee7a785 Mon Sep 17 00:00:00 2001 From: xmrig Date: Fri, 16 Jun 2017 14:36:24 +0300 Subject: [PATCH 58/92] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 70485e0a..8910c977 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ xmrig.exe -o xmr-eu.dwarfpool.com:8005 -u YOUR_WALLET -p x -k --max-cpu-usage=N maximum cpu usage for automatic threads mode (default 75) --safe safe adjust threads and av settings for current cpu --nicehash enable nicehash support + --print-time=N print hashrate report every N seconds -h, --help display this help and exit -V, --version output version information and exit ``` From 09e859d41ec80bb0560b7e0547ca77878c50aaf3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 16 Jun 2017 16:13:29 +0300 Subject: [PATCH 59/92] Fix for linux. --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d301b6ef..685aa5d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,7 +125,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + if (WIN32) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") + endif() add_definitions(/D_GNU_SOURCE) From 0d4b908bfe17b9ea6eb5442b297e7a9f32998b74 Mon Sep 17 00:00:00 2001 From: xmrig Date: Fri, 16 Jun 2017 16:26:25 +0300 Subject: [PATCH 60/92] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 400eff76..54b7bd43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ - Miner complete rewritten in C++ with libuv. - This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. - This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). +- Added new option `--print-time=N`, print hashrate report every N seconds. +- New hashrate reports, by default every 60 secons. - Removed dependency on libcurl. - To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. From bf56ee00bc2cdf4e9a5b32e390ade5403a95eb84 Mon Sep 17 00:00:00 2001 From: xmrig Date: Fri, 16 Jun 2017 16:43:16 +0300 Subject: [PATCH 61/92] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54b7bd43..f04f6228 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). - Added new option `--print-time=N`, print hashrate report every N seconds. - New hashrate reports, by default every 60 secons. +- Added Microsoft Visual C++ 2015 and 2017 support. - Removed dependency on libcurl. - To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. From ccc7fba2c461809c31c77cf828beaabfbe2b3dc0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 17 Jun 2017 15:23:25 +0300 Subject: [PATCH 62/92] Fix software AES. --- src/crypto/CryptoNight_p.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/crypto/CryptoNight_p.h b/src/crypto/CryptoNight_p.h index fa2fa93a..a58c4daa 100644 --- a/src/crypto/CryptoNight_p.h +++ b/src/crypto/CryptoNight_p.h @@ -327,7 +327,13 @@ inline void cryptonight_hash(const void *__restrict__ input, size_t size, void * for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx; cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); - cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); + + if (SOFT_AES) { + cx = soft_aesenc(cx, _mm_set_epi64x(ah0, al0)); + } + else { + cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); + } _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); idx0 = EXTRACT64(cx); @@ -385,8 +391,14 @@ inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, __m128i cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); __m128i cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); - cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); - cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); + if (SOFT_AES) { + cx0 = soft_aesenc(cx0, _mm_set_epi64x(ah0, al0)); + cx1 = soft_aesenc(cx1, _mm_set_epi64x(ah1, al1)); + } + else { + cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); + cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); + } _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); From 815f8cbb967f0eac6771fbd2080959906269fa76 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 17 Jun 2017 15:34:42 +0300 Subject: [PATCH 63/92] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f04f6228..fd070745 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# v1.0.1 +- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. + # v1.0.0 - Miner complete rewritten in C++ with libuv. - This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. From ed0972da85f5b9973535494fc1fcf1965942e369 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 17 Jun 2017 15:37:33 +0300 Subject: [PATCH 64/92] Update version. --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 8dc9a107..6bc3c855 100644 --- a/src/version.h +++ b/src/version.h @@ -27,14 +27,14 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "1.0.0" +#define APP_VERSION "1.0.1" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" #define APP_VER_MAJOR 1 #define APP_VER_MINOR 0 -#define APP_VER_BUILD 0 +#define APP_VER_BUILD 1 #define APP_VER_REV 0 #ifdef _MSC_VER From 9bfa49b7d0f937a0f25cc57b5915a74c90d31635 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 19 Jun 2017 10:58:28 +0300 Subject: [PATCH 65/92] Fix regression, option --no-color not fully disabled colored output. --- src/App.cpp | 15 ++++++++------- src/Console.cpp | 16 +++++++--------- src/Console.h | 7 ++++--- src/Options.cpp | 3 +-- src/version.h | 6 +++--- 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 8f6ed148..091fbb8a 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -48,10 +48,11 @@ App::App(int argc, char **argv) : { m_self = this; - Console::init(); + m_options = Options::parse(argc, argv); + + Console::init(m_options->colors(), m_options->background()); Cpu::init(); - m_options = Options::parse(argc, argv); m_network = new Network(m_options); uv_signal_init(uv_default_loop(), &m_signal); @@ -69,17 +70,17 @@ int App::exec() return 0; } - if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) { - LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName()); - return 1; - } - uv_signal_start(&m_signal, App::onSignal, SIGHUP); uv_signal_start(&m_signal, App::onSignal, SIGTERM); uv_signal_start(&m_signal, App::onSignal, SIGINT); background(); + if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) { + LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName()); + return 1; + } + Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); diff --git a/src/Console.cpp b/src/Console.cpp index 558c1e8d..8f160760 100644 --- a/src/Console.cpp +++ b/src/Console.cpp @@ -40,10 +40,10 @@ Console *Console::m_self = nullptr; -void Console::init() +void Console::init(bool colors, bool background) { if (!m_self) { - m_self = new Console(); + m_self = new Console(colors, background); } } @@ -97,7 +97,7 @@ void Console::message(Console::Level level, const char* fmt, ...) stime.tm_hour, stime.tm_min, stime.tm_sec, - color, + m_colors ? color : "", fmt, m_colors ? kCL_N : "" ); @@ -121,10 +121,7 @@ void Console::text(const char* fmt, ...) const int len = 64 + strlen(fmt) + 2; char *buf = static_cast(alloca(len)); - sprintf(buf, "%s%s\n", - fmt, - m_colors ? kCL_N : "" - ); + sprintf(buf, "%s%s\n", fmt, m_colors ? kCL_N : ""); uv_mutex_lock(&m_mutex); @@ -137,8 +134,9 @@ void Console::text(const char* fmt, ...) } -Console::Console() : - m_colors(true) +Console::Console(bool colors, bool background) : + m_background(background), + m_colors(colors) { uv_mutex_init(&m_mutex); } diff --git a/src/Console.h b/src/Console.h index 73e04706..6e74aa46 100644 --- a/src/Console.h +++ b/src/Console.h @@ -51,16 +51,17 @@ public: # endif static inline Console* i() { return m_self; } - static void init(); + static void init(bool colors, bool background); void message(Level level, const char* fmt, ...); void text(const char* fmt, ...); private: - Console(); + Console(bool colors, bool background); - static Console *m_self; + bool m_background; bool m_colors; + static Console *m_self; uv_mutex_t m_mutex; }; diff --git a/src/Options.cpp b/src/Options.cpp index 4da75923..6fccbe4c 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -34,7 +34,6 @@ #endif -#include "Console.h" #include "Cpu.h" #include "donate.h" #include "net/Url.h" @@ -173,7 +172,7 @@ Options::Options(int argc, char **argv) : } if (!m_url) { - LOG_ERR("No pool URL supplied. Exiting.", argv[0]); + fprintf(stderr, "No pool URL supplied. Exiting."); return; } diff --git a/src/version.h b/src/version.h index 6bc3c855..7382070b 100644 --- a/src/version.h +++ b/src/version.h @@ -27,14 +27,14 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "1.0.1" +#define APP_VERSION "1.1.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" #define APP_VER_MAJOR 1 -#define APP_VER_MINOR 0 -#define APP_VER_BUILD 1 +#define APP_VER_MINOR 1 +#define APP_VER_BUILD 0 #define APP_VER_REV 0 #ifdef _MSC_VER From a791bc113e077a14c24ea948cb1056692f32b9b1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 20 Jun 2017 00:55:55 +0300 Subject: [PATCH 66/92] Adjust console output. --- src/App.cpp | 2 +- src/net/Network.cpp | 6 +++--- src/workers/Hashrate.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 091fbb8a..4284bd69 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -48,10 +48,10 @@ App::App(int argc, char **argv) : { m_self = this; + Cpu::init(); m_options = Options::parse(argc, argv); Console::init(m_options->colors(), m_options->background()); - Cpu::init(); m_network = new Network(m_options); diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 20480eca..8a7ccc6b 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -136,7 +136,7 @@ void Network::onLoginSuccess(Client *client) return; } - LOG_NOTICE("use pool: \"%s:%d\"", client->host(), client->port()); + LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); m_pool = id; if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool @@ -163,11 +163,11 @@ void Network::addPool(const Url *url) void Network::setJob(Client *client, const Job &job) { if (m_options->colors()) { - LOG_INFO("\x1B[01;35mnew job\x1B[0m from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff()); + LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff: \x1B[01;37m%d", client->host(), client->port(), job.diff()); } else { - LOG_INFO("new job from \"%s:%d\", diff: %d", client->host(), client->port(), job.diff()); + LOG_INFO("new job from %s:%d diff: %d", client->host(), client->port(), job.diff()); } Workers::setJob(job); diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 7f2f7ee1..694485cc 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -152,7 +152,7 @@ void Hashrate::print() char num3[8]; char num4[8]; - LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m highest: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s highest: %s H/s", + LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s highest: %s H/s", format(calc(2500), num1, sizeof(num1)), format(calc(60000), num2, sizeof(num2)), format(calc(900000), num3, sizeof(num3)), From 77d9beaf896b0d29263782a02add80155e3e81dd Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 20 Jun 2017 13:04:38 +0300 Subject: [PATCH 67/92] Rename Console class to Log. --- CMakeLists.txt | 4 +-- src/App.cpp | 4 +-- src/Mem_win.cpp | 2 +- src/Summary.cpp | 54 ++++++++++++++++---------------- src/{Console.cpp => log/Log.cpp} | 14 ++++----- src/{Console.h => log/Log.h} | 28 ++++++++--------- src/net/Client.cpp | 2 +- src/net/Job.cpp | 3 +- src/net/Network.cpp | 2 +- src/workers/Hashrate.cpp | 2 +- src/workers/Worker.cpp | 1 - src/workers/Workers.cpp | 1 - 12 files changed, 57 insertions(+), 60 deletions(-) rename src/{Console.cpp => log/Log.cpp} (90%) rename src/{Console.h => log/Log.h} (69%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 685aa5d3..4f2c4372 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,11 +7,11 @@ option(WITH_AEON "CryptoNight-Lite support" ON) set(HEADERS src/3rdparty/align.h src/App.h - src/Console.h src/Cpu.h src/interfaces/IClientListener.h src/interfaces/IJobResultListener.h src/interfaces/IWorker.h + src/log/Log.h src/Mem.h src/net/Client.h src/net/Job.h @@ -45,7 +45,7 @@ set(HEADERS_CRYPTO set(SOURCES src/App.cpp - src/Console.cpp + src/log/Log.cpp src/Mem.cpp src/net/Client.cpp src/net/Job.cpp diff --git a/src/App.cpp b/src/App.cpp index 4284bd69..3586889b 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -27,7 +27,7 @@ #include "App.h" -#include "Console.h" +#include "log/Log.h" #include "Cpu.h" #include "crypto/CryptoNight.h" #include "Mem.h" @@ -51,7 +51,7 @@ App::App(int argc, char **argv) : Cpu::init(); m_options = Options::parse(argc, argv); - Console::init(m_options->colors(), m_options->background()); + Log::init(m_options->colors(), m_options->background()); m_network = new Network(m_options); diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index c5e606f7..f47b6ae4 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -33,7 +33,7 @@ # include #endif -#include "Console.h" +#include "log/Log.h" #include "crypto/CryptoNight.h" #include "Mem.h" #include "Options.h" diff --git a/src/Summary.cpp b/src/Summary.cpp index 8f917d44..a243d9de 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -25,8 +25,8 @@ #include -#include "Console.h" #include "Cpu.h" +#include "log/Log.h" #include "Mem.h" #include "net/Url.h" #include "Options.h" @@ -50,21 +50,21 @@ static void print_versions() if (Options::i()->colors()) { - Console::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf); + Log::i()->text("\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s", APP_VERSION, uv_version_string(), buf); } else { - Console::i()->text(" * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf); + Log::i()->text(" * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf); } } static void print_memory() { if (Options::i()->colors()) { - Console::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s", - Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable", - Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled"); + Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s", + Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable", + Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled"); } else { - Console::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled"); + Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled"); } } @@ -72,19 +72,19 @@ static void print_memory() { static void print_cpu() { if (Options::i()->colors()) { - Console::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI", - Cpu::brand(), - Cpu::sockets(), - Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-", - Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-"); + Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI", + Cpu::brand(), + Cpu::sockets(), + Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-", + Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-"); # ifndef XMRIG_NO_LIBCPUID - Console::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); + Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); # endif } else { - Console::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-"); + Log::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-"); # ifndef XMRIG_NO_LIBCPUID - Console::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); + Log::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); # endif } } @@ -100,28 +100,28 @@ static void print_threads() buf[0] = '\0'; } - Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s%s", - Options::i()->threads(), - Options::i()->algoName(), - Options::i()->algoVariant(), - Options::i()->donateLevel(), - Options::i()->nicehash() ? ", nicehash" : "", buf); + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s%s", + Options::i()->threads(), + Options::i()->algoName(), + Options::i()->algoVariant(), + Options::i()->donateLevel(), + Options::i()->nicehash() ? ", nicehash" : "", buf); } static void print_pools() { - Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #1: \x1B[01;36m%s:%d" : " * POOL #1: %s:%d", - Options::i()->url()->host(), - Options::i()->url()->port()); + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #1: \x1B[01;36m%s:%d" : " * POOL #1: %s:%d", + Options::i()->url()->host(), + Options::i()->url()->port()); if (!Options::i()->backupUrl()) { return; } - Console::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #2: \x1B[01;36m%s:%d" : " * POOL #2: %s:%d", - Options::i()->backupUrl()->host(), - Options::i()->backupUrl()->port()); + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #2: \x1B[01;36m%s:%d" : " * POOL #2: %s:%d", + Options::i()->backupUrl()->host(), + Options::i()->backupUrl()->port()); } diff --git a/src/Console.cpp b/src/log/Log.cpp similarity index 90% rename from src/Console.cpp rename to src/log/Log.cpp index 8f160760..d4037f70 100644 --- a/src/Console.cpp +++ b/src/log/Log.cpp @@ -34,21 +34,21 @@ # include "3rdparty/winansi.h" #endif -#include "Console.h" +#include "log/Log.h" -Console *Console::m_self = nullptr; +Log *Log::m_self = nullptr; -void Console::init(bool colors, bool background) +void Log::init(bool colors, bool background) { if (!m_self) { - m_self = new Console(colors, background); + m_self = new Log(colors, background); } } -void Console::message(Console::Level level, const char* fmt, ...) +void Log::message(Log::Level level, const char* fmt, ...) { time_t now = time(nullptr); tm stime; @@ -113,7 +113,7 @@ void Console::message(Console::Level level, const char* fmt, ...) } -void Console::text(const char* fmt, ...) +void Log::text(const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -134,7 +134,7 @@ void Console::text(const char* fmt, ...) } -Console::Console(bool colors, bool background) : +Log::Log(bool colors, bool background) : m_background(background), m_colors(colors) { diff --git a/src/Console.h b/src/log/Log.h similarity index 69% rename from src/Console.h rename to src/log/Log.h index 6e74aa46..7e1d0b04 100644 --- a/src/Console.h +++ b/src/log/Log.h @@ -21,14 +21,14 @@ * along with this program. If not, see . */ -#ifndef __CONSOLE_H__ -#define __CONSOLE_H__ +#ifndef __LOG_H__ +#define __LOG_H__ #include -class Console +class Log { public: enum Level { @@ -50,35 +50,35 @@ public: constexpr static const char* kCL_GRAY = "\x1B[90m"; # endif - static inline Console* i() { return m_self; } + static inline Log* i() { return m_self; } static void init(bool colors, bool background); void message(Level level, const char* fmt, ...); void text(const char* fmt, ...); private: - Console(bool colors, bool background); + Log(bool colors, bool background); bool m_background; bool m_colors; - static Console *m_self; + static Log *m_self; uv_mutex_t m_mutex; }; -#define LOG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) -#define LOG_WARN(x, ...) Console::i()->message(Console::WARNING, x, ##__VA_ARGS__) -#define LOG_NOTICE(x, ...) Console::i()->message(Console::NOTICE, x, ##__VA_ARGS__) -#define LOG_INFO(x, ...) Console::i()->message(Console::INFO, x, ##__VA_ARGS__) +#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) +#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) +#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__) +#define LOG_INFO(x, ...) Log::i()->message(Log::INFO, x, ##__VA_ARGS__) #ifdef APP_DEBUG -# define LOG_DEBUG(x, ...) Console::i()->message(Console::DEBUG, x, ##__VA_ARGS__) -# define LOG_DEBUG_ERR(x, ...) Console::i()->message(Console::ERR, x, ##__VA_ARGS__) -# define LOG_DEBUG_WARN(x, ...) Console::i()->message(Console::WARNING, x, ##__VA_ARGS__) +# define LOG_DEBUG(x, ...) Log::i()->message(Log::DEBUG, x, ##__VA_ARGS__) +# define LOG_DEBUG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) +# define LOG_DEBUG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) #else # define LOG_DEBUG(x, ...) # define LOG_DEBUG_ERR(x, ...) # define LOG_DEBUG_WARN(x, ...) #endif -#endif /* __CONSOLE_H__ */ +#endif /* __LOG_H__ */ diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 6fdcf331..8dd8051e 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -25,7 +25,7 @@ #include -#include "Console.h" +#include "log/Log.h" #include "interfaces/IClientListener.h" #include "net/Client.h" #include "net/JobResult.h" diff --git a/src/net/Job.cpp b/src/net/Job.cpp index 52123485..9934903f 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -23,11 +23,10 @@ #include -//#include +#include "log/Log.h" #include "net/Job.h" -#include "Console.h" static inline unsigned char hf_hex2bin(char c, bool &err) diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 8a7ccc6b..8de785bd 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -25,7 +25,7 @@ #include -#include "Console.h" +#include "log/Log.h" #include "net/Client.h" #include "net/Network.h" #include "net/Url.h" diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 694485cc..68139710 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -26,7 +26,7 @@ #include #include -#include "Console.h" +#include "log/Log.h" #include "Options.h" #include "workers/Hashrate.h" diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 1cede65f..96cd4182 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -23,7 +23,6 @@ #include -#include "Console.h" #include "Cpu.h" #include "Mem.h" diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 433bdcd8..f78d8e27 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -24,7 +24,6 @@ #include -#include "Console.h" #include "interfaces/IJobResultListener.h" #include "Mem.h" #include "Options.h" From 91ed7e36cd109714ed2c7bdace4986984a7ad34e Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 21 Jun 2017 21:40:15 +0300 Subject: [PATCH 68/92] Temporary disable TCP keepalive for Windows, fixes Windows XP support. --- src/net/Client.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 8dd8051e..e56531f1 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -261,7 +261,10 @@ void Client::connect(struct sockaddr *addr) uv_tcp_init(uv_default_loop(), m_socket); uv_tcp_nodelay(m_socket, 1); + +# ifndef WIN32 uv_tcp_keepalive(m_socket, 1, 60); +# endif uv_tcp_connect(req, m_socket, (const sockaddr*) addr, Client::onConnect); } From 4f512c41d43d286d082567e0838db6a9f2c5a3e4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 22 Jun 2017 02:30:26 +0300 Subject: [PATCH 69/92] Fix linux build --- src/App_unix.cpp | 2 +- src/Mem.h | 1 + src/Mem_unix.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/App_unix.cpp b/src/App_unix.cpp index d001acb2..66957208 100644 --- a/src/App_unix.cpp +++ b/src/App_unix.cpp @@ -29,8 +29,8 @@ #include "App.h" -#include "Console.h" #include "Cpu.h" +#include "log/Log.h" #include "Options.h" diff --git a/src/Mem.h b/src/Mem.h index 4198d8a2..58b91ac7 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -25,6 +25,7 @@ #define __MEM_H__ +#include #include diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index eb3f9af6..6de2bd40 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -28,9 +28,9 @@ #include "crypto/CryptoNight.h" +#include "log/Log.h" #include "Mem.h" #include "Options.h" -#include "Console.h" bool Mem::allocate(int algo, int threads, bool doubleHash) From 052290d0e96a0ed6d24a0e4cc4dbe6eec5da0b75 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 22 Jun 2017 14:41:34 +0300 Subject: [PATCH 70/92] Add ConsoleLog class and ILogBackend interface. --- CMakeLists.txt | 3 + src/App.cpp | 9 ++- src/interfaces/ILogBackend.h | 41 +++++++++++++ src/log/ConsoleLog.cpp | 112 +++++++++++++++++++++++++++++++++++ src/log/ConsoleLog.h | 43 ++++++++++++++ src/log/Log.cpp | 99 +++++-------------------------- src/log/Log.h | 16 +++-- 7 files changed, 232 insertions(+), 91 deletions(-) create mode 100644 src/interfaces/ILogBackend.h create mode 100644 src/log/ConsoleLog.cpp create mode 100644 src/log/ConsoleLog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f2c4372..57def78c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,9 @@ set(HEADERS src/Cpu.h src/interfaces/IClientListener.h src/interfaces/IJobResultListener.h + src/interfaces/ILogBackend.h src/interfaces/IWorker.h + src/log/ConsoleLog.h src/log/Log.h src/Mem.h src/net/Client.h @@ -45,6 +47,7 @@ set(HEADERS_CRYPTO set(SOURCES src/App.cpp + src/log/ConsoleLog.cpp src/log/Log.cpp src/Mem.cpp src/net/Client.cpp diff --git a/src/App.cpp b/src/App.cpp index 3586889b..76e57ca2 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -27,9 +27,10 @@ #include "App.h" -#include "log/Log.h" #include "Cpu.h" #include "crypto/CryptoNight.h" +#include "log/ConsoleLog.h" +#include "log/Log.h" #include "Mem.h" #include "net/Network.h" #include "Options.h" @@ -51,7 +52,11 @@ App::App(int argc, char **argv) : Cpu::init(); m_options = Options::parse(argc, argv); - Log::init(m_options->colors(), m_options->background()); + Log::init(); + + if (!m_options->background()) { + Log::add(new ConsoleLog(m_options->colors())); + } m_network = new Network(m_options); diff --git a/src/interfaces/ILogBackend.h b/src/interfaces/ILogBackend.h new file mode 100644 index 00000000..458b504c --- /dev/null +++ b/src/interfaces/ILogBackend.h @@ -0,0 +1,41 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ILOGBACKEND_H__ +#define __ILOGBACKEND_H__ + + +#include + + +class ILogBackend +{ +public: + virtual ~ILogBackend() {} + + virtual void message(int level, const char* fmt, va_list args) = 0; + virtual void text(const char* fmt, va_list args) = 0; +}; + + +#endif // __ILOGBACKEND_H__ diff --git a/src/log/ConsoleLog.cpp b/src/log/ConsoleLog.cpp new file mode 100644 index 00000000..d9e86318 --- /dev/null +++ b/src/log/ConsoleLog.cpp @@ -0,0 +1,112 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include +#include + + +#ifdef WIN32 +# include +# include +# include "3rdparty/winansi.h" +#endif + +#include "log/ConsoleLog.h" +#include "log/Log.h" + + +ConsoleLog::ConsoleLog(bool colors) : + m_colors(colors) +{ +} + + +void ConsoleLog::message(int level, const char* fmt, va_list args) +{ + time_t now = time(nullptr); + tm stime; + +# ifdef _WIN32 + localtime_s(&stime, &now); +# else + localtime_r(&now, &stime); +# endif + + const char* color = nullptr; + if (m_colors) { + switch (level) { + case Log::ERR: + color = Log::kCL_RED; + break; + + case Log::WARNING: + color = Log::kCL_YELLOW; + break; + + case Log::NOTICE: + color = Log::kCL_WHITE; + break; + + case Log::DEBUG: + color = Log::kCL_GRAY; + break; + + default: + color = ""; + break; + } + } + + const size_t len = 64 + strlen(fmt) + 2; + char *buf = static_cast(alloca(len)); + + sprintf(buf, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n", + stime.tm_year + 1900, + stime.tm_mon + 1, + stime.tm_mday, + stime.tm_hour, + stime.tm_min, + stime.tm_sec, + m_colors ? color : "", + fmt, + m_colors ? Log::kCL_N : "" + ); + + vfprintf(stdout, buf, args); + fflush(stdout); +} + + +void ConsoleLog::text(const char* fmt, va_list args) +{ + const int len = 64 + strlen(fmt) + 2; + char *buf = static_cast(alloca(len)); + + sprintf(buf, "%s%s\n", fmt, m_colors ? Log::kCL_N : ""); + + vfprintf(stdout, buf, args); + fflush(stdout); +} diff --git a/src/log/ConsoleLog.h b/src/log/ConsoleLog.h new file mode 100644 index 00000000..9b6777a5 --- /dev/null +++ b/src/log/ConsoleLog.h @@ -0,0 +1,43 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONSOLELOG_H__ +#define __CONSOLELOG_H__ + + +#include "interfaces/ILogBackend.h" + + +class ConsoleLog : public ILogBackend +{ +public: + ConsoleLog(bool colors); + + void message(int level, const char* fmt, va_list args) override; + void text(const char* fmt, va_list args) override; + +private: + bool m_colors; +}; + +#endif /* __CONSOLELOG_H__ */ diff --git a/src/log/Log.cpp b/src/log/Log.cpp index d4037f70..6d509ae7 100644 --- a/src/log/Log.cpp +++ b/src/log/Log.cpp @@ -34,109 +34,42 @@ # include "3rdparty/winansi.h" #endif +#include "interfaces/ILogBackend.h" #include "log/Log.h" Log *Log::m_self = nullptr; -void Log::init(bool colors, bool background) -{ - if (!m_self) { - m_self = new Log(colors, background); - } -} - - void Log::message(Log::Level level, const char* fmt, ...) { - time_t now = time(nullptr); - tm stime; + va_list args; + va_start(args, fmt); -# ifdef _WIN32 - localtime_s(&stime, &now); -# else - localtime_r(&now, &stime); -# endif - - va_list ap; - va_start(ap, fmt); - - const char* color = nullptr; - if (m_colors) { - switch (level) { - case ERR: - color = kCL_RED; - break; - - case WARNING: - color = kCL_YELLOW; - break; - - case NOTICE: - color = kCL_WHITE; - break; - - case DEBUG: - color = kCL_GRAY; - break; - - default: - color = ""; - break; - } + for (ILogBackend *backend : m_backends) { + backend->message(level, fmt, args); } - const size_t len = 64 + strlen(fmt) + 2; - char *buf = static_cast(alloca(len)); - - sprintf(buf, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n", - stime.tm_year + 1900, - stime.tm_mon + 1, - stime.tm_mday, - stime.tm_hour, - stime.tm_min, - stime.tm_sec, - m_colors ? color : "", - fmt, - m_colors ? kCL_N : "" - ); - - uv_mutex_lock(&m_mutex); - - vfprintf(stdout, buf, ap); - fflush(stdout); - - uv_mutex_unlock(&m_mutex); - - va_end(ap); + va_end(args); } void Log::text(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); + va_list args; + va_start(args, fmt); - const int len = 64 + strlen(fmt) + 2; - char *buf = static_cast(alloca(len)); + for (ILogBackend *backend : m_backends) { + backend->text(fmt, args); + } - sprintf(buf, "%s%s\n", fmt, m_colors ? kCL_N : ""); - - uv_mutex_lock(&m_mutex); - - vfprintf(stdout, buf, ap); - fflush(stdout); - - uv_mutex_unlock(&m_mutex); - - va_end(ap); + va_end(args); } -Log::Log(bool colors, bool background) : - m_background(background), - m_colors(colors) +Log::~Log() { - uv_mutex_init(&m_mutex); + for (auto backend : m_backends) { + delete backend; + } } diff --git a/src/log/Log.h b/src/log/Log.h index 7e1d0b04..16e94e0b 100644 --- a/src/log/Log.h +++ b/src/log/Log.h @@ -26,6 +26,10 @@ #include +#include + + +class ILogBackend; class Log @@ -50,19 +54,19 @@ public: constexpr static const char* kCL_GRAY = "\x1B[90m"; # endif - static inline Log* i() { return m_self; } - static void init(bool colors, bool background); + static inline Log* i() { return m_self; } + static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); } + static inline void init() { if (!m_self) { m_self = new Log();} } void message(Level level, const char* fmt, ...); void text(const char* fmt, ...); private: - Log(bool colors, bool background); + inline Log() {} + ~Log(); - bool m_background; - bool m_colors; static Log *m_self; - uv_mutex_t m_mutex; + std::vector m_backends; }; From 1bfbc97c7d64882c830890e8139f3fa7dec52b53 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 23 Jun 2017 01:38:47 +0300 Subject: [PATCH 71/92] Add FileLog class. --- CMakeLists.txt | 2 + src/log/FileLog.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++ src/log/FileLog.h | 50 +++++++++++++++++++++ src/log/SysLog.cpp | 40 +++++++++++++++++ src/log/SysLog.h | 40 +++++++++++++++++ 5 files changed, 235 insertions(+) create mode 100644 src/log/FileLog.cpp create mode 100644 src/log/FileLog.h create mode 100644 src/log/SysLog.cpp create mode 100644 src/log/SysLog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 57def78c..2c9d95f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ set(HEADERS src/interfaces/ILogBackend.h src/interfaces/IWorker.h src/log/ConsoleLog.h + src/log/FileLog.h src/log/Log.h src/Mem.h src/net/Client.h @@ -48,6 +49,7 @@ set(HEADERS_CRYPTO set(SOURCES src/App.cpp src/log/ConsoleLog.cpp + src/log/FileLog.cpp src/log/Log.cpp src/Mem.cpp src/net/Client.cpp diff --git a/src/log/FileLog.cpp b/src/log/FileLog.cpp new file mode 100644 index 00000000..b08cd203 --- /dev/null +++ b/src/log/FileLog.cpp @@ -0,0 +1,103 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include +#include + + +#ifdef WIN32 +# include +# include +# include "3rdparty/winansi.h" +#endif + + +#include "log/FileLog.h" + + +FileLog::FileLog(const char *fileName) +{ + uv_fs_t req; + m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND, 0644, nullptr); + uv_fs_req_cleanup(&req); +} + + +void FileLog::message(int level, const char* fmt, va_list args) +{ + if (m_file < 0) { + return; + } + + time_t now = time(nullptr); + tm stime; + +# ifdef _WIN32 + localtime_s(&stime, &now); +# else + localtime_r(&now, &stime); +# endif + + char *buf = static_cast(malloc(512)); + int size = snprintf(buf, 23, "[%d-%02d-%02d %02d:%02d:%02d] ", + stime.tm_year + 1900, + stime.tm_mon + 1, + stime.tm_mday, + stime.tm_hour, + stime.tm_min, + stime.tm_sec); + + size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size; + buf[size] = '\n'; + + write(buf, size + 1); +} + + +void FileLog::text(const char* fmt, va_list args) +{ + message(0, fmt, args); +} + + + +void FileLog::onWrite(uv_fs_t *req) +{ + free(req->data); + + uv_fs_req_cleanup(req); + free(req); +} + + +void FileLog::write(char *data, size_t size) +{ + uv_buf_t buf = uv_buf_init(data, size); + uv_fs_t *req = static_cast(malloc(sizeof(uv_fs_t))); + req->data = buf.base; + + uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, 0, FileLog::onWrite); +} diff --git a/src/log/FileLog.h b/src/log/FileLog.h new file mode 100644 index 00000000..2b3ca5d4 --- /dev/null +++ b/src/log/FileLog.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __FILELOG_H__ +#define __FILELOG_H__ + + +#include + + +#include "interfaces/ILogBackend.h" + + +class FileLog : public ILogBackend +{ +public: + FileLog(const char *fileName); + + void message(int level, const char* fmt, va_list args) override; + void text(const char* fmt, va_list args) override; + +private: + static void onWrite(uv_fs_t *req); + + void write(char *data, size_t size); + + int m_file; +}; + +#endif /* __FILELOG_H__ */ diff --git a/src/log/SysLog.cpp b/src/log/SysLog.cpp new file mode 100644 index 00000000..88d2e55a --- /dev/null +++ b/src/log/SysLog.cpp @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "log/SysLog.h" + + +SysLog::SysLog() +{ +} + + +void SysLog::message(int level, const char* fmt, va_list args) +{ +} + + +void SysLog::text(const char* fmt, va_list args) +{ +} diff --git a/src/log/SysLog.h b/src/log/SysLog.h new file mode 100644 index 00000000..5a27fe74 --- /dev/null +++ b/src/log/SysLog.h @@ -0,0 +1,40 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SYSLOG_BACKEND_H__ +#define __SYSLOG_BACKEND_H__ + + +#include "interfaces/ILogBackend.h" + + +class SysLog : public ILogBackend +{ +public: + SysLog(); + + void message(int level, const char* fmt, va_list args) override; + void text(const char* fmt, va_list args) override; +}; + +#endif /* __SYSLOG_BACKEND_H__ */ From c1b3802590534e203dbfc2b0a68488d774b2e283 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 23 Jun 2017 03:12:46 +0300 Subject: [PATCH 72/92] Add option "-l, --log-file=FILE" and stub for option "-S, --syslog". --- src/App.cpp | 5 +++++ src/Options.cpp | 23 ++++++++++++++++++++++- src/Options.h | 4 ++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/App.cpp b/src/App.cpp index 76e57ca2..934b98b3 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -30,6 +30,7 @@ #include "Cpu.h" #include "crypto/CryptoNight.h" #include "log/ConsoleLog.h" +#include "log/FileLog.h" #include "log/Log.h" #include "Mem.h" #include "net/Network.h" @@ -58,6 +59,10 @@ App::App(int argc, char **argv) : Log::add(new ConsoleLog(m_options->colors())); } + if (m_options->logFile()) { + Log::add(new FileLog(m_options->logFile())); + } + m_network = new Network(m_options); uv_signal_init(uv_default_loop(), &m_signal); diff --git a/src/Options.cpp b/src/Options.cpp index 6fccbe4c..5929d062 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -68,6 +68,12 @@ Options:\n\ --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ -B, --background run the miner in the background\n\ -c, --config=FILE load a JSON-format configuration file\n\ + -l, --log-file=FILE log all output to a file\n" +# ifdef HAVE_SYSLOG_H +"\ + -S, --syslog use system log for output messages\n" +# endif +"\ --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ --safe safe adjust threads and av settings for current CPU\n\ --nicehash enable nicehash support\n\ @@ -77,7 +83,7 @@ Options:\n\ "; -static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:"; +static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:l:S"; static struct option const options[] = { @@ -90,6 +96,7 @@ static struct option const options[] = { { "donate-level", 1, nullptr, 1003 }, { "help", 0, nullptr, 'h' }, { "keepalive", 0, nullptr ,'k' }, + { "log-file", 1, nullptr, 'l' }, { "max-cpu-usage", 1, nullptr, 1004 }, { "nicehash", 0, nullptr, 1006 }, { "no-color", 0, nullptr, 1002 }, @@ -98,6 +105,7 @@ static struct option const options[] = { { "retries", 1, nullptr, 'r' }, { "retry-pause", 1, nullptr, 'R' }, { "safe", 0, nullptr, 1005 }, + { "syslog", 0, nullptr, 'S' }, { "threads", 1, nullptr, 't' }, { "url", 1, nullptr, 'o' }, { "user", 1, nullptr, 'u' }, @@ -139,6 +147,8 @@ Options::Options(int argc, char **argv) : m_nicehash(false), m_ready(false), m_safe(false), + m_syslog(false), + m_logFile(nullptr), m_pass(nullptr), m_user(nullptr), m_algo(0), @@ -263,6 +273,12 @@ bool Options::parseArg(int key, char *arg) m_pass = strdup(arg); break; + case 'l': /* --log-file */ + free(m_logFile); + m_logFile = strdup(arg); + m_colors = false; + break; + case 'r': /* --retries */ v = strtol(arg, nullptr, 10); if (v < 1 || v > 1000) { @@ -324,6 +340,11 @@ bool Options::parseArg(int key, char *arg) m_colors = false; break; + case 'S': /* --syslog */ + m_syslog = true; + m_colors = false; + break; + case 'v': /* --av */ v = strtol(arg, nullptr, 10); if (v < 0 || v > 1000) { diff --git a/src/Options.h b/src/Options.h index c100f6d6..907819b7 100644 --- a/src/Options.h +++ b/src/Options.h @@ -57,6 +57,8 @@ public: inline bool isReady() const { return m_ready; } inline bool keepAlive() const { return m_keepAlive; } inline bool nicehash() const { return m_nicehash; } + inline bool syslog() const { return m_syslog; } + inline const char *logFile() const { return m_logFile; } inline const char *pass() const { return m_pass; } inline const char *user() const { return m_user; } inline const Url *backupUrl() const { return m_backupUrl; } @@ -98,6 +100,8 @@ private: bool m_nicehash; bool m_ready; bool m_safe; + bool m_syslog; + char *m_logFile; char *m_pass; char *m_user; int m_algo; From e97cd98f909b4fba0c47c028f704b86c60a55aff Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 23 Jun 2017 19:37:41 +0300 Subject: [PATCH 73/92] Fix file log for linux. --- src/log/FileLog.cpp | 2 +- src/log/Log.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/log/FileLog.cpp b/src/log/FileLog.cpp index b08cd203..a1e80159 100644 --- a/src/log/FileLog.cpp +++ b/src/log/FileLog.cpp @@ -41,7 +41,7 @@ FileLog::FileLog(const char *fileName) { uv_fs_t req; - m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND, 0644, nullptr); + m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr); uv_fs_req_cleanup(&req); } diff --git a/src/log/Log.cpp b/src/log/Log.cpp index 6d509ae7..541486eb 100644 --- a/src/log/Log.cpp +++ b/src/log/Log.cpp @@ -44,23 +44,27 @@ Log *Log::m_self = nullptr; void Log::message(Log::Level level, const char* fmt, ...) { va_list args; + va_list copy; va_start(args, fmt); for (ILogBackend *backend : m_backends) { - backend->message(level, fmt, args); + va_copy(copy, args); + backend->message(level, fmt, copy); + va_end(copy); } - - va_end(args); } void Log::text(const char* fmt, ...) { va_list args; + va_list copy; va_start(args, fmt); for (ILogBackend *backend : m_backends) { - backend->text(fmt, args); + va_copy(copy, args); + backend->text(fmt, copy); + va_end(copy); } va_end(args); From faf793b0aabfe77cbf2b697cd906691432d6a8c1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 25 Jun 2017 02:04:59 +0300 Subject: [PATCH 74/92] Add syslog support. --- CMakeLists.txt | 12 +++++++++++- src/App.cpp | 11 +++++++++++ src/log/SysLog.cpp | 11 +++++++++-- src/log/SysLog.h | 8 ++++---- src/workers/Hashrate.cpp | 2 +- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c9d95f8..4ddcd2e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,10 @@ project(xmrig) option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_AEON "CryptoNight-Lite support" ON) + +include (CheckIncludeFile) + + set(HEADERS src/3rdparty/align.h src/App.h @@ -166,6 +170,12 @@ else() set(SOURCES_CPUID src/Cpu_stub.cpp) endif() +CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H) +if (HAVE_SYSLOG_H) + add_definitions(/DHAVE_SYSLOG_H) + set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp) +endif() + include_directories(src) include_directories(src/3rdparty) include_directories(src/3rdparty/jansson) @@ -173,5 +183,5 @@ include_directories(${UV_INCLUDE_DIR}) add_subdirectory(src/3rdparty/jansson) -add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO}) +add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG}) target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB}) diff --git a/src/App.cpp b/src/App.cpp index 934b98b3..58f6c350 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -40,6 +40,11 @@ #include "workers/Workers.h" +#ifdef HAVE_SYSLOG_H +# include "log/SysLog.h" +#endif + + App *App::m_self = nullptr; @@ -63,6 +68,12 @@ App::App(int argc, char **argv) : Log::add(new FileLog(m_options->logFile())); } +# ifdef HAVE_SYSLOG_H + if (m_options->syslog()) { + Log::add(new SysLog()); + } +# endif + m_network = new Network(m_options); uv_signal_init(uv_default_loop(), &m_signal); diff --git a/src/log/SysLog.cpp b/src/log/SysLog.cpp index 88d2e55a..f9b16cca 100644 --- a/src/log/SysLog.cpp +++ b/src/log/SysLog.cpp @@ -22,19 +22,26 @@ */ +#include + + #include "log/SysLog.h" +#include "version.h" SysLog::SysLog() { + openlog(APP_ID, LOG_PID, LOG_USER); } -void SysLog::message(int level, const char* fmt, va_list args) +void SysLog::message(int level, const char *fmt, va_list args) { + vsyslog(level, fmt, args); } -void SysLog::text(const char* fmt, va_list args) +void SysLog::text(const char *fmt, va_list args) { + message(LOG_INFO, fmt, args); } diff --git a/src/log/SysLog.h b/src/log/SysLog.h index 5a27fe74..38de1a6a 100644 --- a/src/log/SysLog.h +++ b/src/log/SysLog.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __SYSLOG_BACKEND_H__ -#define __SYSLOG_BACKEND_H__ +#ifndef __SYSLOG_H__ +#define __SYSLOG_H__ #include "interfaces/ILogBackend.h" @@ -33,8 +33,8 @@ class SysLog : public ILogBackend public: SysLog(); - void message(int level, const char* fmt, va_list args) override; - void text(const char* fmt, va_list args) override; + void message(int level, const char *fmt, va_list args) override; + void text(const char *fmt, va_list args) override; }; #endif /* __SYSLOG_BACKEND_H__ */ diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 68139710..40b25977 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -152,7 +152,7 @@ void Hashrate::print() char num3[8]; char num4[8]; - LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s highest: %s H/s", + LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s", format(calc(2500), num1, sizeof(num1)), format(calc(60000), num2, sizeof(num2)), format(calc(900000), num3, sizeof(num3)), From 952017ae7a3164d76b12af3b1b121a11915d9216 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 26 Jun 2017 21:13:05 +0300 Subject: [PATCH 75/92] Initial multiple pools support [1/2]. --- src/Options.cpp | 73 ++++++++++++++---------------- src/Options.h | 44 +++++++++---------- src/Summary.cpp | 19 ++++---- src/net/Network.cpp | 6 +-- src/net/Url.cpp | 105 +++++++++++++++++++++++++++++++------------- src/net/Url.h | 26 ++++++++--- 6 files changed, 162 insertions(+), 111 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 5929d062..3c636cec 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -150,7 +150,6 @@ Options::Options(int argc, char **argv) : m_syslog(false), m_logFile(nullptr), m_pass(nullptr), - m_user(nullptr), m_algo(0), m_algoVariant(0), m_donateLevel(kDonateLevel), @@ -159,10 +158,10 @@ Options::Options(int argc, char **argv) : m_retries(5), m_retryPause(5), m_threads(0), - m_affinity(-1L), - m_backupUrl(nullptr), - m_url(nullptr) + m_affinity(-1L) { + m_pools.push_back(new Url()); + int key; while (1) { @@ -181,18 +180,18 @@ Options::Options(int argc, char **argv) : return; } - if (!m_url) { + if (!m_pools[0]->isValid()) { fprintf(stderr, "No pool URL supplied. Exiting."); return; } - if (!m_nicehash && m_url->isNicehash()) { - m_nicehash = true; - } +// if (!m_nicehash && m_url->isNicehash()) { +// m_nicehash = true; +// } - if (!m_user) { - m_user = strdup("x"); - } +// if (!m_user) { +// m_user = strdup("x"); +// } if (!m_pass) { m_pass = strdup("x"); @@ -219,10 +218,6 @@ Options::Options(int argc, char **argv) : Options::~Options() { - delete m_url; - delete m_backupUrl; - - free(m_user); free(m_pass); } @@ -232,7 +227,6 @@ bool Options::parseArg(int key, char *arg) char *p; int v; uint64_t ul; - Url *url; switch (key) { case 'a': /* --algo */ @@ -248,29 +242,26 @@ bool Options::parseArg(int key, char *arg) break; case 'o': /* --url */ - url = parseUrl(arg); - if (url) { - free(m_url); - m_url = url; + if (m_pools[0]->isValid()) { + Url *url = new Url(arg); + if (url->isValid()) { + m_pools.push_back(url); + } + else { + delete url; + } } - break; - - case 'b': /* --backup-url */ - url = parseUrl(arg); - if (url) { - free(m_backupUrl); - m_backupUrl = url; + else { + m_pools[0]->parse(arg); } break; case 'u': /* --user */ - free(m_user); - m_user = strdup(arg); + m_pools.back()->setUser(arg); break; case 'p': /* --pass */ - free(m_pass); - m_pass = strdup(arg); + m_pools.back()->setPassword(arg); break; case 'l': /* --log-file */ @@ -485,18 +476,18 @@ bool Options::setAlgo(const char *algo) bool Options::setUserpass(const char *userpass) { - const char *p = strchr(userpass, ':'); - if (!p) { - showUsage(1); - return false; - } +// const char *p = strchr(userpass, ':'); +// if (!p) { +// showUsage(1); +// return false; +// } - free(m_user); - free(m_pass); +//// free(m_user); +// free(m_pass); - m_user = static_cast(calloc(p - userpass + 1, 1)); - strncpy(m_user, userpass, p - userpass); - m_pass = strdup(p + 1); +//// m_user = static_cast(calloc(p - userpass + 1, 1)); +// strncpy(m_user, userpass, p - userpass); +// m_pass = strdup(p + 1); return true; } diff --git a/src/Options.h b/src/Options.h index 907819b7..e2e6c9f9 100644 --- a/src/Options.h +++ b/src/Options.h @@ -25,6 +25,7 @@ #define __OPTIONS_H__ +#include #include @@ -51,26 +52,24 @@ public: static inline Options* i() { return m_self; } static Options *parse(int argc, char **argv); - inline bool background() const { return m_background; } - inline bool colors() const { return m_colors; } - inline bool doubleHash() const { return m_doubleHash; } - inline bool isReady() const { return m_ready; } - inline bool keepAlive() const { return m_keepAlive; } - inline bool nicehash() const { return m_nicehash; } - inline bool syslog() const { return m_syslog; } - inline const char *logFile() const { return m_logFile; } - inline const char *pass() const { return m_pass; } - inline const char *user() const { return m_user; } - inline const Url *backupUrl() const { return m_backupUrl; } - inline const Url *url() const { return m_url; } - inline int algo() const { return m_algo; } - inline int algoVariant() const { return m_algoVariant; } - inline int donateLevel() const { return m_donateLevel; } - inline int printTime() const { return m_printTime; } - inline int retries() const { return m_retries; } - inline int retryPause() const { return m_retryPause; } - inline int threads() const { return m_threads; } - inline int64_t affinity() const { return m_affinity; } + inline bool background() const { return m_background; } + inline bool colors() const { return m_colors; } + inline bool doubleHash() const { return m_doubleHash; } + inline bool isReady() const { return m_ready; } + inline bool keepAlive() const { return m_keepAlive; } + inline bool nicehash() const { return m_nicehash; } + inline bool syslog() const { return m_syslog; } + inline const char *logFile() const { return m_logFile; } + inline const char *pass() const { return m_pass; } + inline const std::vector &pools() const { return m_pools; } + inline int algo() const { return m_algo; } + inline int algoVariant() const { return m_algoVariant; } + inline int donateLevel() const { return m_donateLevel; } + inline int printTime() const { return m_printTime; } + inline int retries() const { return m_retries; } + inline int retryPause() const { return m_retryPause; } + inline int threads() const { return m_threads; } + inline int64_t affinity() const { return m_affinity; } const char *algoName() const; @@ -103,7 +102,7 @@ private: bool m_syslog; char *m_logFile; char *m_pass; - char *m_user; +// char *m_user; int m_algo; int m_algoVariant; int m_donateLevel; @@ -113,8 +112,7 @@ private: int m_retryPause; int m_threads; int64_t m_affinity; - Url *m_backupUrl; - Url *m_url; + std::vector m_pools; }; #endif /* __OPTIONS_H__ */ diff --git a/src/Summary.cpp b/src/Summary.cpp index a243d9de..54630e8c 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -111,17 +111,20 @@ static void print_threads() static void print_pools() { - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #1: \x1B[01;36m%s:%d" : " * POOL #1: %s:%d", - Options::i()->url()->host(), - Options::i()->url()->port()); + const std::vector &pools = Options::i()->pools(); - if (!Options::i()->backupUrl()) { - return; + for (size_t i = 0; i < pools.size(); ++i) { + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d", + i + 1, + pools[i]->host(), + pools[i]->port()); } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #2: \x1B[01;36m%s:%d" : " * POOL #2: %s:%d", - Options::i()->backupUrl()->host(), - Options::i()->backupUrl()->port()); +# ifdef APP_DEBUG + for (size_t i = 0; i < pools.size(); ++i) { + Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash()); + } +# endif } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 8de785bd..903ed826 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -45,8 +45,8 @@ Network::Network(const Options *options) : m_agent = userAgent(); addPool(std::make_unique().get()); - addPool(m_options->url()); - addPool(m_options->backupUrl()); +// addPool(m_options->url()); +// addPool(m_options->backupUrl()); m_timer.data = this; uv_timer_init(uv_default_loop(), &m_timer); @@ -120,7 +120,7 @@ void Network::onJobResult(const JobResult &result) void Network::onLoginCredentialsRequired(Client *client) { - client->login(m_options->user(), m_options->pass(), m_agent); +// client->login(m_options->user(), m_options->pass(), m_agent); } diff --git a/src/net/Url.cpp b/src/net/Url.cpp index d8264c20..96376d05 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -35,8 +35,12 @@ Url::Url() : + m_keepAlive(false), + m_nicehash(false), m_host(nullptr), - m_port(3333) + m_password(nullptr), + m_user(nullptr), + m_port(kDefaultPort) { } @@ -53,40 +57,22 @@ Url::Url() : * @param url */ Url::Url(const char *url) : + m_keepAlive(false), + m_nicehash(false), m_host(nullptr), - m_port(3333) + m_password(nullptr), + m_user(nullptr), + m_port(kDefaultPort) { - const char *p = strstr(url, "://"); - const char *base = url; - - if (p) { - if (strncasecmp(url, "stratum+tcp://", 14)) { - return; - } - - base = url + 14; - } - - if (!strlen(base) || *base == '/') { - return; - } - - const char *port = strchr(base, ':'); - if (!port) { - m_host = strdup(base); - return; - } - - const size_t size = port++ - base + 1; - m_host = static_cast(malloc(size)); - memcpy(m_host, base, size - 1); - m_host[size - 1] = '\0'; - - m_port = strtol(port, nullptr, 10); + parse(url); } -Url::Url(const char *host, uint16_t port) : +Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash) : + m_keepAlive(false), + m_nicehash(false), + m_password(nullptr), + m_user(nullptr), m_port(port) { m_host = strdup(host); @@ -96,10 +82,67 @@ Url::Url(const char *host, uint16_t port) : Url::~Url() { free(m_host); + free(m_password); + free(m_user); } bool Url::isNicehash() const { - return isValid() && strstr(m_host, ".nicehash.com"); + return isValid() && (m_nicehash || strstr(m_host, ".nicehash.com")); +} + + +bool Url::parse(const char *url) +{ + const char *p = strstr(url, "://"); + const char *base = url; + + if (p) { + if (strncasecmp(url, "stratum+tcp://", 14)) { + return false; + } + + base = url + 14; + } + + if (!strlen(base) || *base == '/') { + return false; + } + + const char *port = strchr(base, ':'); + if (!port) { + m_host = strdup(base); + return false; + } + + const size_t size = port++ - base + 1; + m_host = static_cast(malloc(size)); + memcpy(m_host, base, size - 1); + m_host[size - 1] = '\0'; + + m_port = strtol(port, nullptr, 10); + return true; +} + + +void Url::setPassword(const char *password, bool force) +{ + if (m_password != nullptr && !force) { + return; + } + + free(m_password); + m_password = strdup(password); +} + + +void Url::setUser(const char *user, bool force) +{ + if (m_user != nullptr && !force) { + return; + } + + free(m_user); + m_user = strdup(user); } diff --git a/src/net/Url.h b/src/net/Url.h index 7d44501d..bac2a564 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -31,19 +31,35 @@ class Url { public: + constexpr static const char *kDefaultPassword = "x"; + constexpr static const char *kDefaultUser = "x"; + constexpr static uint16_t kDefaultPort = 3333; + Url(); Url(const char *url); - Url(const char *host, uint16_t port); + Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false ); ~Url(); - bool isNicehash() const; + inline bool isKeepAlive() const { return m_keepAlive; } + inline bool isValid() const { return m_host && m_port > 0; } + inline const char *host() const { return m_host; } + inline const char *password() const { return m_password ? m_password : kDefaultPassword; } + inline const char *user() const { return m_user ? m_user : kDefaultUser; } + inline uint16_t port() const { return m_port; } + inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline bool isValid() const { return m_host && m_port > 0; } - inline const char *host() const { return m_host; } - inline uint16_t port() const { return m_port; } + bool isNicehash() const; + bool parse(const char *url); + void setPassword(const char *password, bool force = true); + void setUser(const char *user, bool force = true); private: + bool m_keepAlive; + bool m_nicehash; char *m_host; + char *m_password; + char *m_user; uint16_t m_port; }; From f36b5eeaade8ce7b78615aa954782dc7e66d98c3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 26 Jun 2017 23:08:10 +0300 Subject: [PATCH 76/92] Fix --cpu-affinity overflow. --- src/Options.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 5929d062..9d6280e2 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -231,7 +231,6 @@ bool Options::parseArg(int key, char *arg) { char *p; int v; - uint64_t ul; Url *url; switch (key) { @@ -357,12 +356,7 @@ bool Options::parseArg(int key, char *arg) case 1020: /* --cpu-affinity */ p = strstr(arg, "0x"); - ul = p ? strtoul(p, NULL, 16) : atol(arg); - if (ul > (1UL << Cpu::threads()) -1) { - ul = -1; - } - - m_affinity = ul; + m_affinity = p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10); break; case 1002: /* --no-color */ From c0dcfc2a9737ec9df88102ed583a2042aa7c4136 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 27 Jun 2017 06:32:17 +0300 Subject: [PATCH 77/92] Initial multiple pools support [2/2]. --- src/App.cpp | 2 +- src/Options.cpp | 49 +++++++++------------------------------------ src/Options.h | 8 -------- src/Summary.cpp | 4 ++-- src/net/Network.cpp | 6 +++--- src/net/Url.cpp | 18 +++++++++++++++++ src/net/Url.h | 2 +- 7 files changed, 35 insertions(+), 54 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 58f6c350..4d3305ff 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -105,7 +105,7 @@ int App::exec() Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); - Workers::start(m_options->affinity(), m_options->nicehash()); + Workers::start(m_options->affinity(), false); m_network->connect(); diff --git a/src/Options.cpp b/src/Options.cpp index 3c636cec..6230f03c 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -143,13 +143,10 @@ Options::Options(int argc, char **argv) : m_background(false), m_colors(true), m_doubleHash(false), - m_keepAlive(false), - m_nicehash(false), m_ready(false), m_safe(false), m_syslog(false), m_logFile(nullptr), - m_pass(nullptr), m_algo(0), m_algoVariant(0), m_donateLevel(kDonateLevel), @@ -185,18 +182,6 @@ Options::Options(int argc, char **argv) : return; } -// if (!m_nicehash && m_url->isNicehash()) { -// m_nicehash = true; -// } - -// if (!m_user) { -// m_user = strdup("x"); -// } - - if (!m_pass) { - m_pass = strdup("x"); - } - m_algoVariant = getAlgoVariant(); if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) { m_doubleHash = true; @@ -218,7 +203,6 @@ Options::Options(int argc, char **argv) : Options::~Options() { - free(m_pass); } @@ -236,13 +220,14 @@ bool Options::parseArg(int key, char *arg) break; case 'O': /* --userpass */ - if (!setUserpass(arg)) { + if (!m_pools.back()->setUserpass(arg)) { return false; } + break; case 'o': /* --url */ - if (m_pools[0]->isValid()) { + if (m_pools.size() > 1 || m_pools[0]->isValid()) { Url *url = new Url(arg); if (url->isValid()) { m_pools.push_back(url); @@ -254,6 +239,11 @@ bool Options::parseArg(int key, char *arg) else { m_pools[0]->parse(arg); } + + if (!m_pools.back()->isValid()) { + return false; + } + break; case 'u': /* --user */ @@ -315,7 +305,7 @@ bool Options::parseArg(int key, char *arg) break; case 'k': /* --keepalive */ - m_keepAlive = true; + m_pools.back()->setKeepAlive(true); break; case 'V': /* --version */ @@ -371,7 +361,7 @@ bool Options::parseArg(int key, char *arg) break; case 1006: /* --nicehash */ - m_nicehash = true; + m_pools.back()->setNicehash(true); break; case 1007: /* --print-time */ @@ -474,25 +464,6 @@ bool Options::setAlgo(const char *algo) } -bool Options::setUserpass(const char *userpass) -{ -// const char *p = strchr(userpass, ':'); -// if (!p) { -// showUsage(1); -// return false; -// } - -//// free(m_user); -// free(m_pass); - -//// m_user = static_cast(calloc(p - userpass + 1, 1)); -// strncpy(m_user, userpass, p - userpass); -// m_pass = strdup(p + 1); - - return true; -} - - int Options::getAlgoVariant() const { # ifndef XMRIG_NO_AEON diff --git a/src/Options.h b/src/Options.h index e2e6c9f9..cefca538 100644 --- a/src/Options.h +++ b/src/Options.h @@ -56,11 +56,8 @@ public: inline bool colors() const { return m_colors; } inline bool doubleHash() const { return m_doubleHash; } inline bool isReady() const { return m_ready; } - inline bool keepAlive() const { return m_keepAlive; } - inline bool nicehash() const { return m_nicehash; } inline bool syslog() const { return m_syslog; } inline const char *logFile() const { return m_logFile; } - inline const char *pass() const { return m_pass; } inline const std::vector &pools() const { return m_pools; } inline int algo() const { return m_algo; } inline int algoVariant() const { return m_algoVariant; } @@ -85,7 +82,6 @@ private: void showVersion(void); bool setAlgo(const char *algo); - bool setUserpass(const char *userpass); int getAlgoVariant() const; # ifndef XMRIG_NO_AEON @@ -95,14 +91,10 @@ private: bool m_background; bool m_colors; bool m_doubleHash; - bool m_keepAlive; - bool m_nicehash; bool m_ready; bool m_safe; bool m_syslog; char *m_logFile; - char *m_pass; -// char *m_user; int m_algo; int m_algoVariant; int m_donateLevel; diff --git a/src/Summary.cpp b/src/Summary.cpp index 54630e8c..9eb195d3 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -100,12 +100,12 @@ static void print_threads() buf[0] = '\0'; } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s%s", + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s", Options::i()->threads(), Options::i()->algoName(), Options::i()->algoVariant(), Options::i()->donateLevel(), - Options::i()->nicehash() ? ", nicehash" : "", buf); + buf); } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 903ed826..eddfc3be 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -45,7 +45,7 @@ Network::Network(const Options *options) : m_agent = userAgent(); addPool(std::make_unique().get()); -// addPool(m_options->url()); + addPool(m_options->pools().front()); // addPool(m_options->backupUrl()); m_timer.data = this; @@ -120,7 +120,7 @@ void Network::onJobResult(const JobResult &result) void Network::onLoginCredentialsRequired(Client *client) { -// client->login(m_options->user(), m_options->pass(), m_agent); + client->login(m_options->pools().front()->password(), m_options->pools().front()->password(), m_agent); } @@ -154,7 +154,7 @@ void Network::addPool(const Url *url) Client *client = new Client(m_pools.size(), this); client->setUrl(url); client->setRetryPause(m_options->retryPause() * 1000); - client->setKeepAlive(m_options->keepAlive()); +// client->setKeepAlive(m_options->keepAlive()); m_pools.push_back(client); } diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 96376d05..3f8ca54e 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -126,6 +126,24 @@ bool Url::parse(const char *url) } +bool Url::setUserpass(const char *userpass) +{ + const char *p = strchr(userpass, ':'); + if (!p) { + return false; + } + + free(m_user); + free(m_password); + + m_user = static_cast(calloc(p - userpass + 1, 1)); + strncpy(m_user, userpass, p - userpass); + m_password = strdup(p + 1); + + return true; +} + + void Url::setPassword(const char *password, bool force) { if (m_password != nullptr && !force) { diff --git a/src/net/Url.h b/src/net/Url.h index bac2a564..639df7cd 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -51,9 +51,9 @@ public: bool isNicehash() const; bool parse(const char *url); + bool setUserpass(const char *userpass); void setPassword(const char *password, bool force = true); void setUser(const char *user, bool force = true); - private: bool m_keepAlive; bool m_nicehash; From 14c6f8699e6dbf4ed66adfa8e87f8a56e37f084f Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 27 Jun 2017 18:47:33 +0300 Subject: [PATCH 78/92] Fix --cpu-affinity overflow, again. --- src/Cpu.h | 5 ++++- src/Cpu_unix.cpp | 2 +- src/Cpu_win.cpp | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Cpu.h b/src/Cpu.h index 292c6c6c..7f1f7614 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -25,6 +25,9 @@ #define __CPU_H__ +#include + + class Cpu { public: @@ -36,7 +39,7 @@ public: static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage); static void init(); - static void setAffinity(int id, unsigned long mask); + static void setAffinity(int id, uint64_t mask); static inline bool hasAES() { return m_flags & AES; } static inline bool isX64() { return m_flags & X86_64; } diff --git a/src/Cpu_unix.cpp b/src/Cpu_unix.cpp index 1b7c6b0a..925e0c0a 100644 --- a/src/Cpu_unix.cpp +++ b/src/Cpu_unix.cpp @@ -40,7 +40,7 @@ void Cpu::init() } -void Cpu::setAffinity(int id, unsigned long mask) +void Cpu::setAffinity(int id, uint64_t mask) { cpu_set_t set; CPU_ZERO(&set); diff --git a/src/Cpu_win.cpp b/src/Cpu_win.cpp index fe4ea0ba..13113a17 100644 --- a/src/Cpu_win.cpp +++ b/src/Cpu_win.cpp @@ -41,7 +41,7 @@ void Cpu::init() } -void Cpu::setAffinity(int id, unsigned long mask) +void Cpu::setAffinity(int id, uint64_t mask) { if (id == -1) { SetProcessAffinityMask(GetCurrentProcess(), mask); From b2d26eb019b6e812838f6706fc45b7a10d1366b3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 28 Jun 2017 04:04:04 +0300 Subject: [PATCH 79/92] Use Url inside Client. Remove onLoginCredentialsRequired from IClientListener interface. --- src/interfaces/IClientListener.h | 1 - src/net/Client.cpp | 75 +++++++++++++++----------------- src/net/Client.h | 17 +++----- src/net/Network.cpp | 8 +--- src/net/Network.h | 1 - src/net/Url.cpp | 28 +++++++----- src/net/Url.h | 7 ++- 7 files changed, 66 insertions(+), 71 deletions(-) diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h index 57019035..7a5743d2 100644 --- a/src/interfaces/IClientListener.h +++ b/src/interfaces/IClientListener.h @@ -36,7 +36,6 @@ public: virtual void onClose(Client *client, int failures) = 0; virtual void onJobReceived(Client *client, const Job &job) = 0; - virtual void onLoginCredentialsRequired(Client *client) = 0; virtual void onLoginSuccess(Client *client) = 0; }; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index e56531f1..86928ed0 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -37,9 +37,8 @@ #endif -Client::Client(int id, IClientListener *listener) : - m_keepAlive(false), - m_host(nullptr), +Client::Client(int id, const char *agent, IClientListener *listener) : + m_agent(agent), m_listener(listener), m_id(id), m_retryPause(5000), @@ -47,7 +46,6 @@ Client::Client(int id, IClientListener *listener) : m_sequence(1), m_recvBufPos(0), m_state(UnconnectedState), - m_port(0), m_stream(nullptr), m_socket(nullptr) { @@ -72,13 +70,12 @@ Client::~Client() { free(m_recvBuf.base); free(m_socket); - free(m_host); } void Client::connect() { - resolve(m_host); + resolve(m_url.host()); } @@ -90,7 +87,7 @@ void Client::connect() void Client::connect(const Url *url) { setUrl(url); - resolve(m_host); + resolve(m_url.host()); } @@ -102,18 +99,6 @@ void Client::disconnect() } -void Client::login(const char *user, const char *pass, const char *agent) -{ - m_sequence = 1; - - const size_t size = 96 + strlen(user) + strlen(pass) + strlen(agent); - char *req = static_cast(malloc(size)); - snprintf(req, size, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_sequence, user, pass, agent); - - send(req); -} - - /** * @brief Send raw data to server. * @@ -121,9 +106,9 @@ void Client::login(const char *user, const char *pass, const char *agent) */ void Client::send(char *data) { - LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_host, m_port, strlen(data), data); + LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), strlen(data), data); if (state() != ConnectedState) { - LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_host, m_port, m_state); + LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state); return; } @@ -148,9 +133,7 @@ void Client::setUrl(const Url *url) return; } - free(m_host); - m_host = strdup(url->host()); - m_port = url->port(); + m_url = url; } @@ -199,7 +182,7 @@ bool Client::parseJob(const json_t *params, int *code) job.setPoolId(m_id); m_job = std::move(job); - LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_host, m_port, job.id(), job.diff()); + LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_url.host(), m_url.port(), job.id(), job.diff()); return true; } @@ -227,7 +210,7 @@ int Client::resolve(const char *host) const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); if (r) { - LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_port, uv_strerror(r)); + LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r)); return 1; } @@ -250,7 +233,7 @@ void Client::connect(struct sockaddr *addr) { setState(ConnectingState); - reinterpret_cast(addr)->sin_port = htons(m_port); + reinterpret_cast(addr)->sin_port = htons(m_url.port()); free(m_socket); uv_connect_t *req = (uv_connect_t*) malloc(sizeof(uv_connect_t)); @@ -270,19 +253,31 @@ void Client::connect(struct sockaddr *addr) } +void Client::login() +{ + m_sequence = 1; + + const size_t size = 96 + strlen(m_url.user()) + strlen(m_url.password()) + strlen(m_agent); + char *req = static_cast(malloc(size)); + snprintf(req, size, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"login\",\"params\":{\"login\":\"%s\",\"pass\":\"%s\",\"agent\":\"%s\"}}\n", m_sequence, m_url.user(), m_url.password(), m_agent); + + send(req); +} + + void Client::parse(char *line, size_t len) { startTimeout(); line[len - 1] = '\0'; - LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_host, m_port, len, line); + LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line); json_error_t err; json_t *val = json_loads(line, 0, &err); if (!val) { - LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_host, m_port, err.text); + LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), err.text); return; } @@ -301,7 +296,7 @@ void Client::parse(char *line, size_t len) void Client::parseNotification(const char *method, const json_t *params, const json_t *error) { if (json_is_object(error)) { - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); return; } @@ -318,7 +313,7 @@ void Client::parseNotification(const char *method, const json_t *params, const j return; } - LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_host, m_port, method); + LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method); } @@ -326,7 +321,7 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error { if (json_is_object(error)) { const char *message = json_string_value(json_object_get(error, "message")); - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_host, m_port, message, json_integer_value(json_object_get(error, "code"))); + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code"))); if (id == 1 || (message && strncasecmp(message, "Unauthenticated", 15) == 0)) { close(); @@ -342,7 +337,7 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error if (id == 1) { int code = -1; if (!parseLogin(result, &code)) { - LOG_ERR("[%s:%u] login error code: %d", m_host, m_port, code); + LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code); return close(); } @@ -366,7 +361,7 @@ void Client::ping() void Client::reconnect() { uv_timer_stop(&m_responseTimer); - if (m_keepAlive) { + if (m_url.isKeepAlive()) { uv_timer_stop(&m_keepAliveTimer); } @@ -383,7 +378,7 @@ void Client::reconnect() void Client::setState(SocketState state) { - LOG_DEBUG("[%s:%u] state: %d", m_host, m_port, state); + LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state); if (m_state == state) { return; @@ -396,7 +391,7 @@ void Client::setState(SocketState state) void Client::startTimeout() { uv_timer_stop(&m_responseTimer); - if (!m_keepAlive) { + if (!m_url.isKeepAlive()) { return; } @@ -431,7 +426,7 @@ void Client::onConnect(uv_connect_t *req, int status) { auto client = getClient(req->data); if (status < 0) { - LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); free(req); client->close(); return; @@ -444,7 +439,7 @@ void Client::onConnect(uv_connect_t *req, int status) uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead); free(req); - client->m_listener->onLoginCredentialsRequired(client); + client->login(); } @@ -453,7 +448,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) auto client = getClient(stream->data); if (nread < 0) { if (nread != UV_EOF) { - LOG_ERR("[%s:%u] read error: \"%s\"", client->m_host, client->m_port, uv_strerror(nread)); + LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(nread)); } return client->close();; @@ -492,7 +487,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) { auto client = getClient(req->data); if (status < 0) { - LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_host, client->m_port, uv_strerror(status)); + LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); return client->reconnect();; } diff --git a/src/net/Client.h b/src/net/Client.h index 75c5b283..2e5303fb 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -30,11 +30,11 @@ #include "net/Job.h" +#include "net/Url.h" class IClientListener; class JobResult; -class Url; class Client @@ -51,24 +51,21 @@ public: constexpr static int kResponseTimeout = 15 * 1000; constexpr static int kKeepAliveTimeout = 60 * 1000; - Client(int id, IClientListener *listener); + Client(int id, const char *agent, IClientListener *listener); ~Client(); void connect(); void connect(const Url *url); void disconnect(); - void login(const char *user, const char *pass, const char *agent); void send(char *data); void setUrl(const Url *url); void submit(const JobResult &result); - inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } - inline const char *host() const { return m_host; } + inline const char *host() const { return m_url.host(); } inline const Job &job() const { return m_job; } inline int id() const { return m_id; } inline SocketState state() const { return m_state; } - inline uint16_t port() const { return m_port; } - inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } + inline uint16_t port() const { return m_url.port(); } inline void setRetryPause(int ms) { m_retryPause = ms; } private: @@ -79,6 +76,7 @@ private: int resolve(const char *host); void close(); void connect(struct sockaddr *addr); + void login(); void parse(char *line, size_t len); void parseNotification(const char *method, const json_t *params, const json_t *error); void parseResponse(int64_t id, const json_t *result, const json_t *error); @@ -95,9 +93,8 @@ private: static Client *getClient(void *data); - bool m_keepAlive; - char *m_host; char m_rpcId[64]; + const char *m_agent; IClientListener *m_listener; int m_id; int m_retryPause; @@ -107,7 +104,7 @@ private: size_t m_recvBufPos; SocketState m_state; struct addrinfo m_hints; - uint16_t m_port; + Url m_url; uv_buf_t m_recvBuf; uv_getaddrinfo_t m_resolver; uv_stream_t *m_stream; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index eddfc3be..4b186bfd 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -118,12 +118,6 @@ void Network::onJobResult(const JobResult &result) } -void Network::onLoginCredentialsRequired(Client *client) -{ - client->login(m_options->pools().front()->password(), m_options->pools().front()->password(), m_agent); -} - - void Network::onLoginSuccess(Client *client) { const int id = client->id(); @@ -151,7 +145,7 @@ void Network::addPool(const Url *url) return; } - Client *client = new Client(m_pools.size(), this); + Client *client = new Client(m_pools.size(), m_agent, this); client->setUrl(url); client->setRetryPause(m_options->retryPause() * 1000); // client->setKeepAlive(m_options->keepAlive()); diff --git a/src/net/Network.h b/src/net/Network.h index 2859abc8..eb20035d 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -51,7 +51,6 @@ protected: void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; void onJobResult(const JobResult &result) override; - void onLoginCredentialsRequired(Client *client) override; void onLoginSuccess(Client *client) override; private: diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 3f8ca54e..1b6d8b0b 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -144,23 +144,31 @@ bool Url::setUserpass(const char *userpass) } -void Url::setPassword(const char *password, bool force) +void Url::setPassword(const char *password) { - if (m_password != nullptr && !force) { - return; - } - free(m_password); m_password = strdup(password); } -void Url::setUser(const char *user, bool force) +void Url::setUser(const char *user) { - if (m_user != nullptr && !force) { - return; - } - free(m_user); m_user = strdup(user); } + + +Url &Url::operator=(const Url *other) +{ + m_keepAlive = other->m_keepAlive; + m_nicehash = other->m_nicehash; + m_port = other->m_port; + + free(m_host); + m_host = strdup(other->m_host); + + setPassword(other->m_password); + setUser(other->m_user); + + return *this; +} diff --git a/src/net/Url.h b/src/net/Url.h index 639df7cd..43197195 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -52,8 +52,11 @@ public: bool isNicehash() const; bool parse(const char *url); bool setUserpass(const char *userpass); - void setPassword(const char *password, bool force = true); - void setUser(const char *user, bool force = true); + void setPassword(const char *password); + void setUser(const char *user); + + Url &operator=(const Url *other); + private: bool m_keepAlive; bool m_nicehash; From bd8776b7eef4659ab45543bb5072be2c38abcefd Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 28 Jun 2017 06:17:02 +0300 Subject: [PATCH 80/92] Add classes SinglePoolStrategy, DonateStrategy, IStrategy, IStrategyListener. --- CMakeLists.txt | 10 +- src/interfaces/IStrategy.h | 37 +++++ src/interfaces/IStrategyListener.h | 35 +++++ src/net/Client.h | 1 + src/net/Network.cpp | 169 ++++++++++------------ src/net/Network.h | 14 +- src/net/Url.cpp | 8 +- src/net/strategies/DonateStrategy.cpp | 73 ++++++++++ src/net/strategies/DonateStrategy.h | 61 ++++++++ src/net/strategies/SinglePoolStrategy.cpp | 59 ++++++++ src/net/strategies/SinglePoolStrategy.h | 55 +++++++ 11 files changed, 414 insertions(+), 108 deletions(-) create mode 100644 src/interfaces/IStrategy.h create mode 100644 src/interfaces/IStrategyListener.h create mode 100644 src/net/strategies/DonateStrategy.cpp create mode 100644 src/net/strategies/DonateStrategy.h create mode 100644 src/net/strategies/SinglePoolStrategy.cpp create mode 100644 src/net/strategies/SinglePoolStrategy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ddcd2e5..63d33455 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,8 @@ set(HEADERS src/interfaces/IClientListener.h src/interfaces/IJobResultListener.h src/interfaces/ILogBackend.h + src/interfaces/IStrategy.h + src/interfaces/IStrategyListener.h src/interfaces/IWorker.h src/log/ConsoleLog.h src/log/FileLog.h @@ -25,6 +27,8 @@ set(HEADERS src/net/JobResult.h src/net/Network.h src/net/Url.h + src/net/strategies/DonateStrategy.h + src/net/strategies/SinglePoolStrategy.h src/Options.h src/Summary.h src/version.h @@ -60,6 +64,8 @@ set(SOURCES src/net/Job.cpp src/net/Network.cpp src/net/Url.cpp + src/net/strategies/DonateStrategy.cpp + src/net/strategies/SinglePoolStrategy.cpp src/Options.cpp src/Summary.cpp src/workers/DoubleWorker.cpp @@ -114,7 +120,7 @@ else() endif() add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") @@ -128,7 +134,7 @@ endif() # https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html if (CMAKE_CXX_COMPILER_ID MATCHES GNU) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -Wno-strict-aliasing") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti") diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h new file mode 100644 index 00000000..6b3b9560 --- /dev/null +++ b/src/interfaces/IStrategy.h @@ -0,0 +1,37 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ISTRATEGY_H__ +#define __ISTRATEGY_H__ + + +class IStrategy +{ +public: + virtual ~IStrategy() {} + + virtual void connect() = 0; +}; + + +#endif // __ISTRATEGY_H__ diff --git a/src/interfaces/IStrategyListener.h b/src/interfaces/IStrategyListener.h new file mode 100644 index 00000000..dd33424e --- /dev/null +++ b/src/interfaces/IStrategyListener.h @@ -0,0 +1,35 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ISTRATEGYLISTENER_H__ +#define __ISTRATEGYLISTENER_H__ + + +class IStrategyListener +{ +public: + virtual ~IStrategyListener() {} +}; + + +#endif // __ISTRATEGYLISTENER_H__ diff --git a/src/net/Client.h b/src/net/Client.h index 2e5303fb..a4ff846d 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -60,6 +60,7 @@ public: void send(char *data); void setUrl(const Url *url); void submit(const JobResult &result); + inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline const char *host() const { return m_url.host(); } inline const Job &job() const { return m_job; } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 4b186bfd..b04c035e 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -28,36 +28,36 @@ #include "log/Log.h" #include "net/Client.h" #include "net/Network.h" +#include "net/strategies/DonateStrategy.h" +#include "net/strategies/SinglePoolStrategy.h" #include "net/Url.h" #include "Options.h" #include "workers/Workers.h" Network::Network(const Options *options) : - m_donate(false), + m_donateActive(false), m_options(options), - m_pool(0), - m_diff(0) + m_donate(nullptr) { Workers::setListener(this); - - m_pools.reserve(2); m_agent = userAgent(); - addPool(std::make_unique().get()); - addPool(m_options->pools().front()); -// addPool(m_options->backupUrl()); + const std::vector &pools = options->pools(); - m_timer.data = this; - uv_timer_init(uv_default_loop(), &m_timer); + m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this); + + if (m_options->donateLevel() > 0) { + m_donate = new DonateStrategy(m_agent, this); + } } Network::~Network() { - for (auto client : m_pools) { - delete client; - } +// for (auto client : m_pools) { +// delete client; +// } free(m_agent); } @@ -65,39 +65,35 @@ Network::~Network() void Network::connect() { - m_pools[1]->connect(); - - if (m_options->donateLevel()) { - uv_timer_start(&m_timer, Network::onTimer, (100 - m_options->donateLevel()) * 60 * 1000, 0); - } + m_strategy->connect(); } void Network::onClose(Client *client, int failures) { - const int id = client->id(); - if (id == 0) { - if (failures == -1) { - stopDonate(); - } +// const int id = client->id(); +// if (id == 0) { +// if (failures == -1) { +// stopDonate(); +// } - return; - } +// return; +// } - if (m_pool == id) { - m_pool = 0; - Workers::pause(); - } +// if (m_pool == id) { +// m_pool = 0; +// Workers::pause(); +// } - if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { - m_pools[2]->connect(); - } +// if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { +// m_pools[2]->connect(); +// } } void Network::onJobReceived(Client *client, const Job &job) { - if (m_donate && client->id() != 0) { + if (m_donateActive && client->id() != 0) { return; } @@ -107,50 +103,35 @@ void Network::onJobReceived(Client *client, const Job &job) void Network::onJobResult(const JobResult &result) { - if (m_options->colors()) { - LOG_NOTICE("\x1B[01;32mSHARE FOUND"); - } - else { - LOG_NOTICE("SHARE FOUND"); - } +// if (m_options->colors()) { +// LOG_NOTICE("\x1B[01;32mSHARE FOUND"); +// } +// else { +// LOG_NOTICE("SHARE FOUND"); +// } - m_pools[result.poolId]->submit(result); +// m_pools[result.poolId]->submit(result); } void Network::onLoginSuccess(Client *client) { - const int id = client->id(); - if (id == 0) { - return startDonate(); - } +// const int id = client->id(); +// if (id == 0) { +// return startDonate(); +// } - if (id == 2 && m_pool) { // primary pool is already active - m_pools[2]->disconnect(); - return; - } +// if (id == 2 && m_pool) { // primary pool is already active +// m_pools[2]->disconnect(); +// return; +// } - LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); - m_pool = id; +// LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); +// m_pool = id; - if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool - m_pools[2]->disconnect(); - } -} - - -void Network::addPool(const Url *url) -{ - if (!url) { - return; - } - - Client *client = new Client(m_pools.size(), m_agent, this); - client->setUrl(url); - client->setRetryPause(m_options->retryPause() * 1000); -// client->setKeepAlive(m_options->keepAlive()); - - m_pools.push_back(client); +// if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool +// m_pools[2]->disconnect(); +// } } @@ -170,48 +151,48 @@ void Network::setJob(Client *client, const Job &job) void Network::startDonate() { - if (m_donate) { + if (m_donateActive) { return; } LOG_NOTICE("dev donate started"); - m_donate = true; + m_donateActive = true; } void Network::stopDonate() { - if (!m_donate) { - return; - } +// if (!m_donateActive) { +// return; +// } - LOG_NOTICE("dev donate finished"); +// LOG_NOTICE("dev donate finished"); - m_donate = false; - if (!m_pool) { - return; - } +// m_donateActive = false; +// if (!m_pool) { +// return; +// } - Client *client = m_pools[m_pool]; - if (client->isReady()) { - setJob(client, client->job()); - } +// Client *client = m_pools[m_pool]; +// if (client->isReady()) { +// setJob(client, client->job()); +// } } -void Network::onTimer(uv_timer_t *handle) -{ - auto net = static_cast(handle->data); +//void Network::onTimer(uv_timer_t *handle) +//{ +// auto net = static_cast(handle->data); - if (!net->m_donate) { - auto url = std::make_unique("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443); - net->m_pools[0]->connect(url.get()); +// if (!net->m_donateActive) { +// auto url = std::make_unique("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443); +// net->m_pools[0]->connect(url.get()); - uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); - return; - } +// uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); +// return; +// } - net->m_pools[0]->disconnect(); - uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0); -} +// net->m_pools[0]->disconnect(); +// uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0); +//} diff --git a/src/net/Network.h b/src/net/Network.h index eb20035d..3fec005a 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -31,13 +31,15 @@ #include "interfaces/IClientListener.h" #include "interfaces/IJobResultListener.h" +#include "interfaces/IStrategyListener.h" +class IStrategy; class Options; class Url; -class Network : public IClientListener, public IJobResultListener +class Network : public IClientListener, public IJobResultListener, public IStrategyListener { public: Network(const Options *options); @@ -59,15 +61,11 @@ private: void startDonate(); void stopDonate(); - static void onTimer(uv_timer_t *handle); - - bool m_donate; + bool m_donateActive; char *m_agent; const Options *m_options; - int m_pool; - std::vector m_pools; - uint64_t m_diff; - uv_timer_t m_timer; + IStrategy *m_donate; + IStrategy *m_strategy; }; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 1b6d8b0b..06e44aaa 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -69,10 +69,10 @@ Url::Url(const char *url) : Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash) : - m_keepAlive(false), - m_nicehash(false), - m_password(nullptr), - m_user(nullptr), + m_keepAlive(keepAlive), + m_nicehash(nicehash), + m_password(password ? strdup(password) : nullptr), + m_user(user ? strdup(user) : nullptr), m_port(port) { m_host = strdup(host); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp new file mode 100644 index 00000000..5cbd319f --- /dev/null +++ b/src/net/strategies/DonateStrategy.cpp @@ -0,0 +1,73 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "net/Client.h" +#include "net/strategies/DonateStrategy.h" +#include "Options.h" + + +DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : + m_listener(listener) +{ + Url *url = new Url("donate.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, Options::i()->pools().front()->user()); + + m_client = new Client(-1, agent, this); + m_client->setUrl(url); + m_client->setRetryPause(Options::i()->retryPause() * 1000); + + delete url; + + m_timer.data = this; + uv_timer_init(uv_default_loop(), &m_timer); + + uv_timer_start(&m_timer, DonateStrategy::onTimer, (100 - Options::i()->donateLevel()) * 60 * 1000, 0); +} + + +void DonateStrategy::connect() +{ +} + + +void DonateStrategy::onClose(Client *client, int failures) +{ + +} + + +void DonateStrategy::onJobReceived(Client *client, const Job &job) +{ + +} + + +void DonateStrategy::onLoginSuccess(Client *client) +{ +} + + +void DonateStrategy::onTimer(uv_timer_t *handle) +{ + +} diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h new file mode 100644 index 00000000..c010f7ff --- /dev/null +++ b/src/net/strategies/DonateStrategy.h @@ -0,0 +1,61 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __DONATESTRATEGY_H__ +#define __DONATESTRATEGY_H__ + + +#include + + +#include "interfaces/IClientListener.h" +#include "interfaces/IStrategy.h" + + +class Client; +class IStrategyListener; +class Url; + + +class DonateStrategy : public IStrategy, public IClientListener +{ +public: + DonateStrategy(const char *agent, IStrategyListener *listener); + +public: + void connect() override; + +protected: + void onClose(Client *client, int failures) override; + void onJobReceived(Client *client, const Job &job) override; + void onLoginSuccess(Client *client) override; + +private: + static void onTimer(uv_timer_t *handle); + + Client *m_client; + IStrategyListener *m_listener; + uv_timer_t m_timer; +}; + +#endif /* __DONATESTRATEGY_H__ */ diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp new file mode 100644 index 00000000..677a3518 --- /dev/null +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -0,0 +1,59 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "net/Client.h" +#include "net/strategies/SinglePoolStrategy.h" +#include "Options.h" + + +SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) : + m_listener(listener) +{ + m_client = new Client(0, agent, this); + m_client->setUrl(url); + m_client->setRetryPause(Options::i()->retryPause() * 1000); +} + + +void SinglePoolStrategy::connect() +{ + m_client->connect(); +} + + +void SinglePoolStrategy::onClose(Client *client, int failures) +{ + +} + + +void SinglePoolStrategy::onJobReceived(Client *client, const Job &job) +{ + +} + + +void SinglePoolStrategy::onLoginSuccess(Client *client) +{ +} diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h new file mode 100644 index 00000000..ff289ae9 --- /dev/null +++ b/src/net/strategies/SinglePoolStrategy.h @@ -0,0 +1,55 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SINGLEPOOLSTRATEGY_H__ +#define __SINGLEPOOLSTRATEGY_H__ + + +#include "interfaces/IClientListener.h" +#include "interfaces/IStrategy.h" + + +class Client; +class IStrategyListener; +class Url; + + +class SinglePoolStrategy : public IStrategy, public IClientListener +{ +public: + SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener); + +public: + void connect() override; + +protected: + void onClose(Client *client, int failures) override; + void onJobReceived(Client *client, const Job &job) override; + void onLoginSuccess(Client *client) override; + +private: + Client *m_client; + IStrategyListener *m_listener; +}; + +#endif /* __SINGLEPOOLSTRATEGY_H__ */ From 25faeabd61871435011df9d6046ee1fe73953975 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 29 Jun 2017 01:48:23 +0300 Subject: [PATCH 81/92] Implemented SinglePoolStrategy. --- CMakeLists.txt | 2 +- src/interfaces/IStrategy.h | 7 +++- src/interfaces/IStrategyListener.h | 9 +++++ src/net/Network.cpp | 45 ++++++++++++++++------- src/net/Network.h | 8 ++-- src/net/strategies/DonateStrategy.cpp | 18 ++++++++- src/net/strategies/DonateStrategy.h | 3 ++ src/net/strategies/SinglePoolStrategy.cpp | 23 +++++++++++- src/net/strategies/SinglePoolStrategy.h | 3 ++ src/workers/Workers.h | 2 +- 10 files changed, 98 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 63d33455..cecd78e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,7 +120,7 @@ else() endif() add_definitions(/DUNICODE) -add_definitions(/DAPP_DEBUG) +#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h index 6b3b9560..eddf300b 100644 --- a/src/interfaces/IStrategy.h +++ b/src/interfaces/IStrategy.h @@ -25,12 +25,17 @@ #define __ISTRATEGY_H__ +class JobResult; + + class IStrategy { public: virtual ~IStrategy() {} - virtual void connect() = 0; + virtual bool isActive() const = 0; + virtual void connect() = 0; + virtual void submit(const JobResult &result) = 0; }; diff --git a/src/interfaces/IStrategyListener.h b/src/interfaces/IStrategyListener.h index dd33424e..5fbc78c5 100644 --- a/src/interfaces/IStrategyListener.h +++ b/src/interfaces/IStrategyListener.h @@ -25,10 +25,19 @@ #define __ISTRATEGYLISTENER_H__ +class Client; +class IStrategy; +class Job; + + class IStrategyListener { public: virtual ~IStrategyListener() {} + + virtual void onActive(Client *client) = 0; + virtual void onJob(Client *client, const Job &job) = 0; + virtual void onPause(IStrategy *strategy) = 0; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index b04c035e..36443104 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -69,8 +69,19 @@ void Network::connect() } -void Network::onClose(Client *client, int failures) +void Network::onActive(Client *client) { + if (client->id() == -1) { + LOG_NOTICE("dev donate started"); + return; + } + + LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); +} + + +//void Network::onClose(Client *client, int failures) +//{ // const int id = client->id(); // if (id == 0) { // if (failures == -1) { @@ -88,12 +99,12 @@ void Network::onClose(Client *client, int failures) // if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { // m_pools[2]->connect(); // } -} +//} -void Network::onJobReceived(Client *client, const Job &job) +void Network::onJob(Client *client, const Job &job) { - if (m_donateActive && client->id() != 0) { + if (m_donate && m_donate->isActive() && client->id() != -1) { return; } @@ -103,19 +114,18 @@ void Network::onJobReceived(Client *client, const Job &job) void Network::onJobResult(const JobResult &result) { -// if (m_options->colors()) { -// LOG_NOTICE("\x1B[01;32mSHARE FOUND"); -// } -// else { -// LOG_NOTICE("SHARE FOUND"); -// } + LOG_NOTICE(m_options->colors() ? "\x1B[01;32mSHARE FOUND" : "SHARE FOUND"); -// m_pools[result.poolId]->submit(result); + if (result.poolId == -1 && m_donate) { + return m_donate->submit(result); + } + + m_strategy->submit(result); } -void Network::onLoginSuccess(Client *client) -{ +//void Network::onLoginSuccess(Client *client) +//{ // const int id = client->id(); // if (id == 0) { // return startDonate(); @@ -132,6 +142,15 @@ void Network::onLoginSuccess(Client *client) // if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool // m_pools[2]->disconnect(); // } +//} + + +void Network::onPause(IStrategy *strategy) +{ + if ((m_donate && !m_donate->isActive()) || !m_strategy->isActive()) { + LOG_ERR("no active pools, pause mining"); + Workers::pause(); + } } diff --git a/src/net/Network.h b/src/net/Network.h index 3fec005a..4eb86cc3 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -39,7 +39,7 @@ class Options; class Url; -class Network : public IClientListener, public IJobResultListener, public IStrategyListener +class Network : public IJobResultListener, public IStrategyListener { public: Network(const Options *options); @@ -50,10 +50,10 @@ public: static char *userAgent(); protected: - void onClose(Client *client, int failures) override; - void onJobReceived(Client *client, const Job &job) override; + void onActive(Client *client) override; + void onJob(Client *client, const Job &job) override; void onJobResult(const JobResult &result) override; - void onLoginSuccess(Client *client) override; + void onPause(IStrategy *strategy) override; private: void addPool(const Url *url); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 5cbd319f..9b7fb12b 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,12 +22,14 @@ */ +#include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/DonateStrategy.h" #include "Options.h" DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : + m_active(false), m_listener(listener) { Url *url = new Url("donate.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, Options::i()->pools().front()->user()); @@ -45,11 +47,23 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : } +bool DonateStrategy::isActive() const +{ + return m_active; +} + + void DonateStrategy::connect() { } +void DonateStrategy::submit(const JobResult &result) +{ + m_client->submit(result); +} + + void DonateStrategy::onClose(Client *client, int failures) { @@ -58,12 +72,14 @@ void DonateStrategy::onClose(Client *client, int failures) void DonateStrategy::onJobReceived(Client *client, const Job &job) { - + m_listener->onJob(client, job); } void DonateStrategy::onLoginSuccess(Client *client) { + m_active = true; + m_listener->onActive(client); } diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index c010f7ff..128757ca 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -43,7 +43,9 @@ public: DonateStrategy(const char *agent, IStrategyListener *listener); public: + bool isActive() const override; void connect() override; + void submit(const JobResult &result) override; protected: void onClose(Client *client, int failures) override; @@ -53,6 +55,7 @@ protected: private: static void onTimer(uv_timer_t *handle); + bool m_active; Client *m_client; IStrategyListener *m_listener; uv_timer_t m_timer; diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index 677a3518..c7d2a8d0 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -22,12 +22,14 @@ */ +#include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/SinglePoolStrategy.h" #include "Options.h" SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) : + m_active(false), m_listener(listener) { m_client = new Client(0, agent, this); @@ -36,24 +38,43 @@ SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrat } +bool SinglePoolStrategy::isActive() const +{ + return m_active; +} + + void SinglePoolStrategy::connect() { m_client->connect(); } +void SinglePoolStrategy::submit(const JobResult &result) +{ + m_client->submit(result); +} + + void SinglePoolStrategy::onClose(Client *client, int failures) { + if (!isActive()) { + return; + } + m_active = false; + m_listener->onPause(this); } void SinglePoolStrategy::onJobReceived(Client *client, const Job &job) { - + m_listener->onJob(client, job); } void SinglePoolStrategy::onLoginSuccess(Client *client) { + m_active = true; + m_listener->onActive(client); } diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h index ff289ae9..fb8eca60 100644 --- a/src/net/strategies/SinglePoolStrategy.h +++ b/src/net/strategies/SinglePoolStrategy.h @@ -40,7 +40,9 @@ public: SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener); public: + bool isActive() const override; void connect() override; + void submit(const JobResult &result) override; protected: void onClose(Client *client, int failures) override; @@ -48,6 +50,7 @@ protected: void onLoginSuccess(Client *client) override; private: + bool m_active; Client *m_client; IStrategyListener *m_listener; }; diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 0990fc45..ffeddb00 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -50,7 +50,7 @@ public: static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } - static inline void pause() { m_paused = 1; } + static inline void pause() { m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } private: From 7e17f77c1158fca71cd9ee007fcaf7157fd7d330 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 30 Jun 2017 03:20:50 +0300 Subject: [PATCH 82/92] Implemented DonateStrategy. --- src/interfaces/IStrategy.h | 1 + src/net/Client.cpp | 32 ++++++++++++++---- src/net/Client.h | 2 ++ src/net/Network.cpp | 21 ++++-------- src/net/strategies/DonateStrategy.cpp | 40 ++++++++++++++++++----- src/net/strategies/DonateStrategy.h | 9 ++++- src/net/strategies/SinglePoolStrategy.cpp | 16 +++++---- src/net/strategies/SinglePoolStrategy.h | 4 ++- 8 files changed, 88 insertions(+), 37 deletions(-) diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h index eddf300b..78f3f623 100644 --- a/src/interfaces/IStrategy.h +++ b/src/interfaces/IStrategy.h @@ -35,6 +35,7 @@ public: virtual bool isActive() const = 0; virtual void connect() = 0; + virtual void resume() = 0; virtual void submit(const JobResult &result) = 0; }; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 86928ed0..e9fcb0a7 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -38,6 +38,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : + m_quiet(false), m_agent(agent), m_listener(listener), m_id(id), @@ -93,6 +94,7 @@ void Client::connect(const Url *url) void Client::disconnect() { + uv_timer_stop(&m_retriesTimer); m_failures = -1; close(); @@ -207,10 +209,13 @@ int Client::resolve(const char *host) setState(HostLookupState); m_recvBufPos = 0; + m_failures = 0; const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); if (r) { - LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r)); + if (!m_quiet) { + LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r)); + } return 1; } @@ -277,7 +282,9 @@ void Client::parse(char *line, size_t len) json_t *val = json_loads(line, 0, &err); if (!val) { - LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), err.text); + if (!m_quiet) { + LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), err.text); + } return; } @@ -296,7 +303,9 @@ void Client::parse(char *line, size_t len) void Client::parseNotification(const char *method, const json_t *params, const json_t *error) { if (json_is_object(error)) { - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + if (!m_quiet) { + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), json_string_value(json_object_get(error, "message")), json_integer_value(json_object_get(error, "code"))); + } return; } @@ -321,7 +330,10 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error { if (json_is_object(error)) { const char *message = json_string_value(json_object_get(error, "message")); - LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code"))); + + if (!m_quiet) { + LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code"))); + } if (id == 1 || (message && strncasecmp(message, "Unauthenticated", 15) == 0)) { close(); @@ -337,7 +349,10 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error if (id == 1) { int code = -1; if (!parseLogin(result, &code)) { - LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code); + if (!m_quiet) { + LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code); + } + return close(); } @@ -426,7 +441,10 @@ void Client::onConnect(uv_connect_t *req, int status) { auto client = getClient(req->data); if (status < 0) { - LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); + if (!client->m_quiet) { + LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); + } + free(req); client->close(); return; @@ -447,7 +465,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { auto client = getClient(stream->data); if (nread < 0) { - if (nread != UV_EOF) { + if (nread != UV_EOF && !client->m_quiet) { LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(nread)); } diff --git a/src/net/Client.h b/src/net/Client.h index a4ff846d..65fdc42a 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -67,6 +67,7 @@ public: inline int id() const { return m_id; } inline SocketState state() const { return m_state; } inline uint16_t port() const { return m_url.port(); } + inline void setQuiet(bool quiet) { m_quiet = quiet; } inline void setRetryPause(int ms) { m_retryPause = ms; } private: @@ -94,6 +95,7 @@ private: static Client *getClient(void *data); + bool m_quiet; char m_rpcId[64]; const char *m_agent; IClientListener *m_listener; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 36443104..8e064e9a 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -147,9 +147,14 @@ void Network::onJobResult(const JobResult &result) void Network::onPause(IStrategy *strategy) { - if ((m_donate && !m_donate->isActive()) || !m_strategy->isActive()) { + if (m_donate && m_donate == strategy) { + LOG_NOTICE("dev donate finished"); + m_strategy->resume(); + } + + if (!m_strategy->isActive()) { LOG_ERR("no active pools, pause mining"); - Workers::pause(); + return Workers::pause(); } } @@ -168,18 +173,6 @@ void Network::setJob(Client *client, const Job &job) } -void Network::startDonate() -{ - if (m_donateActive) { - return; - } - - LOG_NOTICE("dev donate started"); - - m_donateActive = true; -} - - void Network::stopDonate() { // if (!m_donateActive) { diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 9b7fb12b..a3c595ed 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -30,6 +30,8 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : m_active(false), + m_donateTime(Options::i()->donateLevel() * 60 * 1000), + m_idleTime((100 - Options::i()->donateLevel()) * 60 * 1000), m_listener(listener) { Url *url = new Url("donate.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443, Options::i()->pools().front()->user()); @@ -37,24 +39,20 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : m_client = new Client(-1, agent, this); m_client->setUrl(url); m_client->setRetryPause(Options::i()->retryPause() * 1000); + m_client->setQuiet(true); delete url; m_timer.data = this; uv_timer_init(uv_default_loop(), &m_timer); - uv_timer_start(&m_timer, DonateStrategy::onTimer, (100 - Options::i()->donateLevel()) * 60 * 1000, 0); -} - - -bool DonateStrategy::isActive() const -{ - return m_active; + idle(); } void DonateStrategy::connect() { + m_client->connect(); } @@ -66,7 +64,6 @@ void DonateStrategy::submit(const JobResult &result) void DonateStrategy::onClose(Client *client, int failures) { - } @@ -78,12 +75,39 @@ void DonateStrategy::onJobReceived(Client *client, const Job &job) void DonateStrategy::onLoginSuccess(Client *client) { + if (!isActive()) { + uv_timer_start(&m_timer, DonateStrategy::onTimer, m_donateTime, 0); + } + m_active = true; m_listener->onActive(client); } +void DonateStrategy::idle() +{ + uv_timer_start(&m_timer, DonateStrategy::onTimer, m_idleTime, 0); +} + + +void DonateStrategy::stop() +{ + m_client->disconnect(); + + m_active = false; + m_listener->onPause(this); + + idle(); +} + + void DonateStrategy::onTimer(uv_timer_t *handle) { + auto strategy = static_cast(handle->data); + if (!strategy->isActive()) { + return strategy->connect(); + } + + strategy->stop(); } diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 128757ca..33cdf536 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -43,7 +43,9 @@ public: DonateStrategy(const char *agent, IStrategyListener *listener); public: - bool isActive() const override; + inline bool isActive() const override { return m_active; } + inline void resume() override {} + void connect() override; void submit(const JobResult &result) override; @@ -53,10 +55,15 @@ protected: void onLoginSuccess(Client *client) override; private: + void idle(); + void stop(); + static void onTimer(uv_timer_t *handle); bool m_active; Client *m_client; + const int m_donateTime; + const int m_idleTime; IStrategyListener *m_listener; uv_timer_t m_timer; }; diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index c7d2a8d0..c1d1a08f 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -38,18 +38,22 @@ SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrat } -bool SinglePoolStrategy::isActive() const -{ - return m_active; -} - - void SinglePoolStrategy::connect() { m_client->connect(); } +void SinglePoolStrategy::resume() +{ + if (!isActive()) { + return; + } + + m_listener->onJob(m_client, m_client->job()); +} + + void SinglePoolStrategy::submit(const JobResult &result) { m_client->submit(result); diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h index fb8eca60..b5939859 100644 --- a/src/net/strategies/SinglePoolStrategy.h +++ b/src/net/strategies/SinglePoolStrategy.h @@ -40,8 +40,10 @@ public: SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener); public: - bool isActive() const override; + inline bool isActive() const override { return m_active; } + void connect() override; + void resume() override; void submit(const JobResult &result) override; protected: From 7536663caf9770a55c37448a82f364dbf66e470a Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 30 Jun 2017 13:23:13 +0300 Subject: [PATCH 83/92] Remove option --backup-url. --- src/Options.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Options.cpp b/src/Options.cpp index 6230f03c..4f9a291c 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -54,7 +54,6 @@ Usage: " APP_ID " [OPTIONS]\n\ Options:\n\ -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ -o, --url=URL URL of mining server\n\ - -b, --backup-url=URL URL of backup mining server\n\ -O, --userpass=U:P username:password pair for mining server\n\ -u, --user=USERNAME username for mining server\n\ -p, --pass=PASSWORD password for mining server\n\ @@ -83,14 +82,13 @@ Options:\n\ "; -static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vb:l:S"; +static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vl:S"; static struct option const options[] = { { "algo", 1, nullptr, 'a' }, { "av", 1, nullptr, 'v' }, { "background", 0, nullptr, 'B' }, - { "backup-url", 1, nullptr, 'b' }, { "config", 1, nullptr, 'c' }, { "cpu-affinity", 1, nullptr, 1020 }, { "donate-level", 1, nullptr, 1003 }, From 970b5d1964e9e4e01c3e4ab15dba5f625a4abf1b Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 1 Jul 2017 20:53:42 +0300 Subject: [PATCH 84/92] Add FailoverStrategy. --- CMakeLists.txt | 4 +- src/Summary.cpp | 3 +- src/net/Client.cpp | 7 +- src/net/Network.cpp | 92 ++---------------- src/net/strategies/FailoverStrategy.cpp | 121 ++++++++++++++++++++++++ src/net/strategies/FailoverStrategy.h | 66 +++++++++++++ 6 files changed, 205 insertions(+), 88 deletions(-) create mode 100644 src/net/strategies/FailoverStrategy.cpp create mode 100644 src/net/strategies/FailoverStrategy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cecd78e1..3026905e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ set(HEADERS src/net/Network.h src/net/Url.h src/net/strategies/DonateStrategy.h + src/net/strategies/FailoverStrategy.h src/net/strategies/SinglePoolStrategy.h src/Options.h src/Summary.h @@ -65,6 +66,7 @@ set(SOURCES src/net/Network.cpp src/net/Url.cpp src/net/strategies/DonateStrategy.cpp + src/net/strategies/FailoverStrategy.cpp src/net/strategies/SinglePoolStrategy.cpp src/Options.cpp src/Summary.cpp @@ -120,7 +122,7 @@ else() endif() add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/Summary.cpp b/src/Summary.cpp index 9eb195d3..08326458 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -100,10 +100,11 @@ static void print_threads() buf[0] = '\0'; } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, donate=%d%%%s" : " * THREADS: %d, %s, av=%d, donate=%d%%%s", + Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", Options::i()->threads(), Options::i()->algoName(), Options::i()->algoVariant(), + Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "", Options::i()->donateLevel(), buf); } diff --git a/src/net/Client.cpp b/src/net/Client.cpp index e9fcb0a7..3b9eecbd 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -209,7 +209,10 @@ int Client::resolve(const char *host) setState(HostLookupState); m_recvBufPos = 0; - m_failures = 0; + + if (m_failures == -1) { + m_failures = 0; + } const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints); if (r) { @@ -375,6 +378,8 @@ void Client::ping() void Client::reconnect() { + setState(ConnectingState); + uv_timer_stop(&m_responseTimer); if (m_url.isKeepAlive()) { uv_timer_stop(&m_keepAliveTimer); diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 8e064e9a..abd7ed11 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -29,6 +29,7 @@ #include "net/Client.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" +#include "net/strategies/FailoverStrategy.h" #include "net/strategies/SinglePoolStrategy.h" #include "net/Url.h" #include "Options.h" @@ -45,7 +46,12 @@ Network::Network(const Options *options) : const std::vector &pools = options->pools(); - m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this); + if (pools.size() > 1) { + m_strategy = new FailoverStrategy(pools, m_agent, this); + } + else { + m_strategy = new SinglePoolStrategy(pools.front(), m_agent, this); + } if (m_options->donateLevel() > 0) { m_donate = new DonateStrategy(m_agent, this); @@ -55,10 +61,6 @@ Network::Network(const Options *options) : Network::~Network() { -// for (auto client : m_pools) { -// delete client; -// } - free(m_agent); } @@ -80,28 +82,6 @@ void Network::onActive(Client *client) } -//void Network::onClose(Client *client, int failures) -//{ -// const int id = client->id(); -// if (id == 0) { -// if (failures == -1) { -// stopDonate(); -// } - -// return; -// } - -// if (m_pool == id) { -// m_pool = 0; -// Workers::pause(); -// } - -// if (id == 1 && m_pools.size() > 2 && failures == m_options->retries()) { -// m_pools[2]->connect(); -// } -//} - - void Network::onJob(Client *client, const Job &job) { if (m_donate && m_donate->isActive() && client->id() != -1) { @@ -124,27 +104,6 @@ void Network::onJobResult(const JobResult &result) } -//void Network::onLoginSuccess(Client *client) -//{ -// const int id = client->id(); -// if (id == 0) { -// return startDonate(); -// } - -// if (id == 2 && m_pool) { // primary pool is already active -// m_pools[2]->disconnect(); -// return; -// } - -// LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); -// m_pool = id; - -// if (m_pool == 1 && m_pools.size() > 2) { // try disconnect from backup pool -// m_pools[2]->disconnect(); -// } -//} - - void Network::onPause(IStrategy *strategy) { if (m_donate && m_donate == strategy) { @@ -171,40 +130,3 @@ void Network::setJob(Client *client, const Job &job) Workers::setJob(job); } - - -void Network::stopDonate() -{ -// if (!m_donateActive) { -// return; -// } - -// LOG_NOTICE("dev donate finished"); - -// m_donateActive = false; -// if (!m_pool) { -// return; -// } - -// Client *client = m_pools[m_pool]; -// if (client->isReady()) { -// setJob(client, client->job()); -// } -} - - -//void Network::onTimer(uv_timer_t *handle) -//{ -// auto net = static_cast(handle->data); - -// if (!net->m_donateActive) { -// auto url = std::make_unique("donate.xmrig.com", net->m_options->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 443); -// net->m_pools[0]->connect(url.get()); - -// uv_timer_start(&net->m_timer, Network::onTimer, net->m_options->donateLevel() * 60 * 1000, 0); -// return; -// } - -// net->m_pools[0]->disconnect(); -// uv_timer_start(&net->m_timer, Network::onTimer, (100 - net->m_options->donateLevel()) * 60 * 1000, 0); -//} diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp new file mode 100644 index 00000000..07eabcde --- /dev/null +++ b/src/net/strategies/FailoverStrategy.cpp @@ -0,0 +1,121 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "interfaces/IStrategyListener.h" +#include "net/Client.h" +#include "net/strategies/FailoverStrategy.h" +#include "Options.h" + + +FailoverStrategy::FailoverStrategy(const std::vector &urls, const char *agent, IStrategyListener *listener) : + m_active(-1), + m_index(0), + m_listener(listener) +{ + for (const Url *url : urls) { + add(url, agent); + } +} + + +void FailoverStrategy::connect() +{ + m_pools[m_index]->connect(); +} + + +void FailoverStrategy::resume() +{ + if (!isActive()) { + return; + } + + m_listener->onJob( m_pools[m_active], m_pools[m_active]->job()); +} + + +void FailoverStrategy::submit(const JobResult &result) +{ + m_pools[m_active]->submit(result); +} + + +void FailoverStrategy::onClose(Client *client, int failures) +{ + if (failures == -1) { + return; + } + + if (m_active == client->id()) { + m_active = -1; + m_listener->onPause(this); + } + + if (m_index == 0 && failures < Options::i()->retries()) { + return; + } + + if (m_index == client->id() && (m_pools.size() - m_index) > 1) { + m_pools[++m_index]->connect(); + } +} + + +void FailoverStrategy::onJobReceived(Client *client, const Job &job) +{ + if (m_active == client->id()) { + m_listener->onJob(client, job); + } +} + + +void FailoverStrategy::onLoginSuccess(Client *client) +{ + int active = m_active; + + if (client->id() == 0 || !isActive()) { + active = client->id(); + } + + for (size_t i = 1; i < m_pools.size(); ++i) { + if (active != static_cast(i)) { + m_pools[i]->disconnect(); + } + } + + if (active >= 0 && active != m_active) { + m_index = m_active = active; + m_listener->onActive(client); + } +} + + +void FailoverStrategy::add(const Url *url, const char *agent) +{ + Client *client = new Client(m_pools.size(), agent, this); + client->setUrl(url); + client->setRetryPause(Options::i()->retryPause() * 1000); + + m_pools.push_back(client); +} diff --git a/src/net/strategies/FailoverStrategy.h b/src/net/strategies/FailoverStrategy.h new file mode 100644 index 00000000..456ddc66 --- /dev/null +++ b/src/net/strategies/FailoverStrategy.h @@ -0,0 +1,66 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __FAILOVERSTRATEGY_H__ +#define __FAILOVERSTRATEGY_H__ + + +#include + + +#include "interfaces/IClientListener.h" +#include "interfaces/IStrategy.h" + + +class Client; +class IStrategyListener; +class Url; + + +class FailoverStrategy : public IStrategy, public IClientListener +{ +public: + FailoverStrategy(const std::vector &urls, const char *agent, IStrategyListener *listener); + +public: + inline bool isActive() const override { return m_active >= 0; } + + void connect() override; + void resume() override; + void submit(const JobResult &result) override; + +protected: + void onClose(Client *client, int failures) override; + void onJobReceived(Client *client, const Job &job) override; + void onLoginSuccess(Client *client) override; + +private: + void add(const Url *url, const char *agent); + + int m_active; + int m_index; + IStrategyListener *m_listener; + std::vector m_pools; +}; + +#endif /* __FAILOVERSTRATEGY_H__ */ From 152b65b67ce6d452f5129245bf8c97dd3663a188 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 1 Jul 2017 21:11:41 +0300 Subject: [PATCH 85/92] Increase response timeout to 20 seconds. --- src/net/Client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net/Client.h b/src/net/Client.h index 65fdc42a..29571830 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -48,7 +48,7 @@ public: ClosingState }; - constexpr static int kResponseTimeout = 15 * 1000; + constexpr static int kResponseTimeout = 20 * 1000; constexpr static int kKeepAliveTimeout = 60 * 1000; Client(int id, const char *agent, IClientListener *listener); From 263634f585ff5df468493adc5519c3498e4a3306 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 1 Jul 2017 22:14:44 +0300 Subject: [PATCH 86/92] Increase major version because --backup-url option removed and added ability to specify multiple pool urls. --- src/version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/version.h b/src/version.h index 7382070b..1c9575ae 100644 --- a/src/version.h +++ b/src/version.h @@ -27,13 +27,13 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "1.1.0-dev" +#define APP_VERSION "2.0.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" -#define APP_VER_MAJOR 1 -#define APP_VER_MINOR 1 +#define APP_VER_MAJOR 2 +#define APP_VER_MINOR 0 #define APP_VER_BUILD 0 #define APP_VER_REV 0 From 8ec58a83941fd6aa197304e165af18c25af599fd Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 1 Jul 2017 22:37:27 +0300 Subject: [PATCH 87/92] Fix nicehash support, please note --nicehash option now specified per pool. --- src/App.cpp | 2 +- src/net/Client.cpp | 3 +-- src/net/Job.cpp | 3 ++- src/net/Job.h | 22 ++++++++++++---------- src/workers/DoubleWorker.cpp | 2 +- src/workers/Handle.cpp | 3 +-- src/workers/Handle.h | 4 +--- src/workers/SingleWorker.cpp | 2 +- src/workers/Worker.cpp | 1 - src/workers/Worker.h | 1 - src/workers/Workers.cpp | 4 ++-- src/workers/Workers.h | 2 +- 12 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 4d3305ff..9d970d12 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -105,7 +105,7 @@ int App::exec() Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash()); Summary::print(); - Workers::start(m_options->affinity(), false); + Workers::start(m_options->affinity()); m_network->connect(); diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 3b9eecbd..ffd72114 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -165,7 +165,7 @@ bool Client::parseJob(const json_t *params, int *code) return false; } - Job job; + Job job(m_id, m_url.isNicehash()); if (!job.setId(json_string_value(json_object_get(params, "job_id")))) { *code = 3; return false; @@ -181,7 +181,6 @@ bool Client::parseJob(const json_t *params, int *code) return false; } - job.setPoolId(m_id); m_job = std::move(job); LOG_DEBUG("[%s:%u] job: \"%s\", diff: %lld", m_url.host(), m_url.port(), job.id(), job.diff()); diff --git a/src/net/Job.cpp b/src/net/Job.cpp index 9934903f..cda6c9ae 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -56,7 +56,8 @@ static inline char hf_bin2hex(unsigned char c) } -Job::Job(int poolId) : +Job::Job(int poolId, bool nicehash) : + m_nicehash(nicehash), m_poolId(poolId), m_size(0), m_diff(0), diff --git a/src/net/Job.h b/src/net/Job.h index 262465fc..d8a9e203 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -34,20 +34,21 @@ class Job { public: - Job(int poolId = -2); + Job(int poolId = -2, bool nicehash = false); bool setBlob(const char *blob); bool setId(const char *id); bool setTarget(const char *target); - inline bool isValid() const { return m_size > 0 && m_diff > 0; } - inline const char *id() const { return m_id; } - inline const uint8_t *blob() const { return m_blob; } - inline int poolId() const { return m_poolId; } - inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } - inline uint32_t diff() const { return m_diff; } - inline uint32_t size() const { return m_size; } - inline uint64_t target() const { return m_target; } - inline void setPoolId(int poolId) { m_poolId = poolId; } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return m_size > 0 && m_diff > 0; } + inline const char *id() const { return m_id; } + inline const uint8_t *blob() const { return m_blob; } + inline int poolId() const { return m_poolId; } + inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } + inline uint32_t diff() const { return m_diff; } + inline uint32_t size() const { return m_size; } + inline uint64_t target() const { return m_target; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } static bool fromHex(const char* in, unsigned int len, unsigned char* out); static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast(blob + 39); } @@ -55,6 +56,7 @@ public: static void toHex(const unsigned char* in, unsigned int len, char* out); private: + bool m_nicehash; int m_poolId; VAR_ALIGN(16, char m_id[64]); VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 41b9aec7..90fbf2b3 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -85,7 +85,7 @@ void DoubleWorker::consumeJob() memcpy(m_blob, m_job.blob(), m_job.size()); memcpy(m_blob + m_job.size(), m_job.blob(), m_job.size()); - if (m_nicehash) { + if (m_job.isNicehash()) { m_nonce1 = (*Job::nonce(m_blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id); m_nonce2 = (*Job::nonce(m_blob + m_job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads)); } diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index c97d10b1..9cebd097 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,8 +25,7 @@ #include "workers/Handle.h" -Handle::Handle(int threadId, int threads, int64_t affinity, bool nicehash) : - m_nicehash(nicehash), +Handle::Handle(int threadId, int threads, int64_t affinity) : m_threadId(threadId), m_threads(threads), m_affinity(affinity), diff --git a/src/workers/Handle.h b/src/workers/Handle.h index 96a512e3..6ec3d240 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -35,10 +35,9 @@ class IWorker; class Handle { public: - Handle(int threadId, int threads, int64_t affinity, bool nicehash); + Handle(int threadId, int threads, int64_t affinity); void start(void (*callback) (void *)); - inline bool nicehash() const { return m_nicehash; } inline int threadId() const { return m_threadId; } inline int threads() const { return m_threads; } inline int64_t affinity() const { return m_affinity; } @@ -46,7 +45,6 @@ public: inline void setWorker(IWorker *worker) { m_worker = worker; } private: - bool m_nicehash; int m_threadId; int m_threads; int64_t m_affinity; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 9c56b7d8..477694eb 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -77,7 +77,7 @@ void SingleWorker::consumeJob() memcpy(m_result.jobId, m_job.id(), sizeof(m_result.jobId)); m_result.poolId = m_job.poolId(); - if (m_nicehash) { + if (m_job.isNicehash()) { m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id); } else { diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 96cd4182..583c1d45 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -31,7 +31,6 @@ Worker::Worker(Handle *handle) : - m_nicehash(handle->nicehash()), m_id(handle->threadId()), m_threads(handle->threads()), m_hashCount(0), diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 84f3ccf8..11c4a198 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -48,7 +48,6 @@ public: protected: void storeStats(); - bool m_nicehash; cryptonight_ctx *m_ctx; int m_id; int m_threads; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index f78d8e27..1ee6262e 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -69,7 +69,7 @@ void Workers::setJob(const Job &job) } -void Workers::start(int64_t affinity, bool nicehash) +void Workers::start(int64_t affinity) { const int threads = Mem::threads(); m_hashrate = new Hashrate(threads); @@ -85,7 +85,7 @@ void Workers::start(int64_t affinity, bool nicehash) uv_timer_start(&m_timer, Workers::onTick, 500, 500); for (int i = 0; i < threads; ++i) { - Handle *handle = new Handle(i, threads, affinity, nicehash); + Handle *handle = new Handle(i, threads, affinity); m_workers.push_back(handle); handle->start(Workers::onReady); } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index ffeddb00..8bc07c1d 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -44,7 +44,7 @@ class Workers public: static Job job(); static void setJob(const Job &job); - static void start(int64_t affinity, bool nicehash); + static void start(int64_t affinity); static void submit(const JobResult &result); static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } From 71522214aeb4ce811413256a2e3fea4900e119a5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 2 Jul 2017 01:36:33 +0300 Subject: [PATCH 88/92] Show resolved pool ip. --- CMakeLists.txt | 2 +- src/net/Client.cpp | 3 +++ src/net/Client.h | 2 ++ src/net/Network.cpp | 6 +++--- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3026905e..6cc2f555 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,7 +122,7 @@ else() endif() add_definitions(/DUNICODE) -add_definitions(/DAPP_DEBUG) +#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/net/Client.cpp b/src/net/Client.cpp index ffd72114..f709245a 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -50,6 +50,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_stream(nullptr), m_socket(nullptr) { + memset(m_ip, 0, sizeof(m_ip)); m_resolver.data = m_responseTimer.data = m_retriesTimer.data = m_keepAliveTimer.data = this; m_hints.ai_family = PF_INET; @@ -513,6 +514,8 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) return client->reconnect();; } + uv_ip4_name(reinterpret_cast(res->ai_addr), client->m_ip, 16); + client->connect(res->ai_addr); uv_freeaddrinfo(res); } diff --git a/src/net/Client.h b/src/net/Client.h index 29571830..d8bb785a 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -63,6 +63,7 @@ public: inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline const char *host() const { return m_url.host(); } + inline const char *ip() const { return m_ip; } inline const Job &job() const { return m_job; } inline int id() const { return m_id; } inline SocketState state() const { return m_state; } @@ -96,6 +97,7 @@ private: static Client *getClient(void *data); bool m_quiet; + char m_ip[17]; char m_rpcId[64]; const char *m_agent; IClientListener *m_listener; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index abd7ed11..5b204734 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -78,7 +78,7 @@ void Network::onActive(Client *client) return; } - LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool: \x1B[01;36m%s:%d" : "use pool: %s:%d", client->host(), client->port()); + LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip()); } @@ -121,11 +121,11 @@ void Network::onPause(IStrategy *strategy) void Network::setJob(Client *client, const Job &job) { if (m_options->colors()) { - LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff: \x1B[01;37m%d", client->host(), client->port(), job.diff()); + LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff()); } else { - LOG_INFO("new job from %s:%d diff: %d", client->host(), client->port(), job.diff()); + LOG_INFO("new job from %s:%d diff %d", client->host(), client->port(), job.diff()); } Workers::setJob(job); From 074db6bb72abad4184f950faea5237d127b500dc Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 2 Jul 2017 05:33:10 +0300 Subject: [PATCH 89/92] Add nice messages for accepted and rejected shares with diff and latency. --- CMakeLists.txt | 1 + src/interfaces/IClientListener.h | 10 +++-- src/interfaces/IStrategyListener.h | 10 +++-- src/net/Client.cpp | 16 +++++++- src/net/Client.h | 3 ++ src/net/JobResult.h | 5 ++- src/net/Network.cpp | 21 ++++++++-- src/net/Network.h | 3 ++ src/net/SubmitResult.h | 47 +++++++++++++++++++++++ src/net/strategies/DonateStrategy.cpp | 6 +++ src/net/strategies/DonateStrategy.h | 1 + src/net/strategies/FailoverStrategy.cpp | 6 +++ src/net/strategies/FailoverStrategy.h | 1 + src/net/strategies/SinglePoolStrategy.cpp | 6 +++ src/net/strategies/SinglePoolStrategy.h | 1 + src/workers/DoubleWorker.cpp | 4 +- src/workers/SingleWorker.cpp | 1 + 17 files changed, 128 insertions(+), 14 deletions(-) create mode 100644 src/net/SubmitResult.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cc2f555..8c19c125 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,7 @@ set(HEADERS src/net/Job.h src/net/JobResult.h src/net/Network.h + src/net/SubmitResult.h src/net/Url.h src/net/strategies/DonateStrategy.h src/net/strategies/FailoverStrategy.h diff --git a/src/interfaces/IClientListener.h b/src/interfaces/IClientListener.h index 7a5743d2..8911e043 100644 --- a/src/interfaces/IClientListener.h +++ b/src/interfaces/IClientListener.h @@ -25,6 +25,9 @@ #define __ICLIENTLISTENER_H__ +#include + + class Client; class Job; @@ -34,9 +37,10 @@ class IClientListener public: virtual ~IClientListener() {} - virtual void onClose(Client *client, int failures) = 0; - virtual void onJobReceived(Client *client, const Job &job) = 0; - virtual void onLoginSuccess(Client *client) = 0; + virtual void onClose(Client *client, int failures) = 0; + virtual void onJobReceived(Client *client, const Job &job) = 0; + virtual void onLoginSuccess(Client *client) = 0; + virtual void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) = 0; }; diff --git a/src/interfaces/IStrategyListener.h b/src/interfaces/IStrategyListener.h index 5fbc78c5..9fff223d 100644 --- a/src/interfaces/IStrategyListener.h +++ b/src/interfaces/IStrategyListener.h @@ -25,6 +25,9 @@ #define __ISTRATEGYLISTENER_H__ +#include + + class Client; class IStrategy; class Job; @@ -35,9 +38,10 @@ class IStrategyListener public: virtual ~IStrategyListener() {} - virtual void onActive(Client *client) = 0; - virtual void onJob(Client *client, const Job &job) = 0; - virtual void onPause(IStrategy *strategy) = 0; + virtual void onActive(Client *client) = 0; + virtual void onJob(Client *client, const Job &job) = 0; + virtual void onPause(IStrategy *strategy) = 0; + virtual void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) = 0; }; diff --git a/src/net/Client.cpp b/src/net/Client.cpp index f709245a..4a9f379d 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -22,6 +22,7 @@ */ +#include #include @@ -155,6 +156,7 @@ void Client::submit(const JobResult &result) snprintf(req, 345, "{\"id\":%llu,\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n", m_sequence, m_rpcId, result.jobId, nonce, data); + m_results[m_sequence] = SubmitResult(result.diff); send(req); } @@ -264,6 +266,7 @@ void Client::connect(struct sockaddr *addr) void Client::login() { m_sequence = 1; + m_results.clear(); const size_t size = 96 + strlen(m_url.user()) + strlen(m_url.password()) + strlen(m_agent); char *req = static_cast(malloc(size)); @@ -334,7 +337,12 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error if (json_is_object(error)) { const char *message = json_string_value(json_object_get(error, "message")); - if (!m_quiet) { + auto it = m_results.find(id); + if (it != m_results.end()) { + m_listener->onResultAccepted(this, it->second.diff, it->second.elapsed(), message); + m_results.erase(it); + } + else if (!m_quiet) { LOG_ERR("[%s:%u] error: \"%s\", code: %lld", m_url.host(), m_url.port(), message, json_integer_value(json_object_get(error, "code"))); } @@ -364,6 +372,12 @@ void Client::parseResponse(int64_t id, const json_t *result, const json_t *error m_listener->onJobReceived(this, m_job); return; } + + auto it = m_results.find(id); + if (it != m_results.end()) { + m_listener->onResultAccepted(this, it->second.diff, it->second.elapsed(), nullptr); + m_results.erase(it); + } } diff --git a/src/net/Client.h b/src/net/Client.h index d8bb785a..a9777435 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -26,10 +26,12 @@ #include +#include #include #include "net/Job.h" +#include "net/SubmitResult.h" #include "net/Url.h" @@ -108,6 +110,7 @@ private: Job m_job; size_t m_recvBufPos; SocketState m_state; + std::map m_results; struct addrinfo m_hints; Url m_url; uv_buf_t m_recvBuf; diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 87e3a645..0279b8be 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -32,8 +32,8 @@ class JobResult { public: - inline JobResult() : poolId(0), nonce(0) {} - inline JobResult(int poolId, const char *jobId, uint32_t nonce, const uint8_t *result) : poolId(poolId), nonce(nonce) + inline JobResult() : poolId(0), diff(0), nonce(0) {} + inline JobResult(int poolId, const char *jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) : poolId(poolId), diff(diff), nonce(nonce) { memcpy(this->jobId, jobId, sizeof(this->jobId)); memcpy(this->result, result, sizeof(this->result)); @@ -41,6 +41,7 @@ public: char jobId[64]; int poolId; + uint32_t diff; uint32_t nonce; uint8_t result[32]; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 5b204734..0fcac1be 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -39,7 +39,9 @@ Network::Network(const Options *options) : m_donateActive(false), m_options(options), - m_donate(nullptr) + m_donate(nullptr), + m_accepted(0), + m_rejected(0) { Workers::setListener(this); m_agent = userAgent(); @@ -94,8 +96,6 @@ void Network::onJob(Client *client, const Job &job) void Network::onJobResult(const JobResult &result) { - LOG_NOTICE(m_options->colors() ? "\x1B[01;32mSHARE FOUND" : "SHARE FOUND"); - if (result.poolId == -1 && m_donate) { return m_donate->submit(result); } @@ -118,6 +118,21 @@ void Network::onPause(IStrategy *strategy) } +void Network::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) +{ + if (error) { + m_rejected++; + + LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%lld/%lld) diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%llu ms)" : "accepted (%lld/%lld) diff %u \"%s\" (%llu ms)", m_accepted, m_rejected, diff, error, ms); + } + else { + m_accepted++; + + LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%lld/%lld) diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%llu ms)" : "accepted (%lld/%lld) diff %u (%llu ms)", m_accepted, m_rejected, diff, ms); + } +} + + void Network::setJob(Client *client, const Job &job) { if (m_options->colors()) { diff --git a/src/net/Network.h b/src/net/Network.h index 4eb86cc3..6cf6260d 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -54,6 +54,7 @@ protected: void onJob(Client *client, const Job &job) override; void onJobResult(const JobResult &result) override; void onPause(IStrategy *strategy) override; + void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; private: void addPool(const Url *url); @@ -66,6 +67,8 @@ private: const Options *m_options; IStrategy *m_donate; IStrategy *m_strategy; + uint64_t m_accepted; + uint64_t m_rejected; }; diff --git a/src/net/SubmitResult.h b/src/net/SubmitResult.h new file mode 100644 index 00000000..eb49bd02 --- /dev/null +++ b/src/net/SubmitResult.h @@ -0,0 +1,47 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __SUBMITRESULT_H__ +#define __SUBMITRESULT_H__ + + +#include + + +class SubmitResult +{ +public: + inline SubmitResult() : diff(0), start(0) {} + inline SubmitResult(uint32_t diff) : + diff(diff) + { + start = uv_hrtime(); + } + + inline uint64_t elapsed() const { return (uv_hrtime() - start) / 1000000; } + + uint32_t diff; + uint64_t start; +}; + +#endif /* __SUBMITRESULT_H__ */ diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index a3c595ed..fb7b6a67 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -84,6 +84,12 @@ void DonateStrategy::onLoginSuccess(Client *client) } +void DonateStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) +{ + m_listener->onResultAccepted(client, diff, ms, error); +} + + void DonateStrategy::idle() { uv_timer_start(&m_timer, DonateStrategy::onTimer, m_idleTime, 0); diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 33cdf536..b2c889bc 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -53,6 +53,7 @@ protected: void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; void onLoginSuccess(Client *client) override; + void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; private: void idle(); diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp index 07eabcde..7f2aa2a8 100644 --- a/src/net/strategies/FailoverStrategy.cpp +++ b/src/net/strategies/FailoverStrategy.cpp @@ -111,6 +111,12 @@ void FailoverStrategy::onLoginSuccess(Client *client) } +void FailoverStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) +{ + m_listener->onResultAccepted(client, diff, ms, error); +} + + void FailoverStrategy::add(const Url *url, const char *agent) { Client *client = new Client(m_pools.size(), agent, this); diff --git a/src/net/strategies/FailoverStrategy.h b/src/net/strategies/FailoverStrategy.h index 456ddc66..86545d81 100644 --- a/src/net/strategies/FailoverStrategy.h +++ b/src/net/strategies/FailoverStrategy.h @@ -53,6 +53,7 @@ protected: void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; void onLoginSuccess(Client *client) override; + void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; private: void add(const Url *url, const char *agent); diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index c1d1a08f..87d21077 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -82,3 +82,9 @@ void SinglePoolStrategy::onLoginSuccess(Client *client) m_active = true; m_listener->onActive(client); } + + +void SinglePoolStrategy::onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) +{ + m_listener->onResultAccepted(client, diff, ms, error); +} diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h index b5939859..dbf96aa1 100644 --- a/src/net/strategies/SinglePoolStrategy.h +++ b/src/net/strategies/SinglePoolStrategy.h @@ -50,6 +50,7 @@ protected: void onClose(Client *client, int failures) override; void onJobReceived(Client *client, const Job &job) override; void onLoginSuccess(Client *client) override; + void onResultAccepted(Client *client, uint32_t diff, uint64_t ms, const char *error) override; private: bool m_active; diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 90fbf2b3..86dbd13d 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -62,11 +62,11 @@ void DoubleWorker::start() CryptoNight::hash(m_blob, m_job.size(), m_hash, m_ctx); if (*reinterpret_cast(m_hash + 24) < m_job.target()) { - Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce1, m_hash)); + Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce1, m_hash, m_job.diff())); } if (*reinterpret_cast(m_hash + 32 + 24) < m_job.target()) { - Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce2, m_hash + 32)); + Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce2, m_hash + 32, m_job.diff())); } std::this_thread::yield(); diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 477694eb..68ff21b7 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -76,6 +76,7 @@ void SingleWorker::consumeJob() memcpy(m_result.jobId, m_job.id(), sizeof(m_result.jobId)); m_result.poolId = m_job.poolId(); + m_result.diff = m_job.diff(); if (m_job.isNicehash()) { m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id); From dbc6f26c9173053fd552a0d1d67001484bcaa922 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sun, 2 Jul 2017 07:34:02 +0300 Subject: [PATCH 90/92] Update CHANGELOG.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd070745..4b488dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v2.0.0 + - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` + - #15 Added option `-l, --log-file=FILE` to write log to file. + - #15 Added option `-S, --syslog` to use syslog for logging, Linux only. + - #18 Added nice messages for accepted/rejected shares with diff and network latency. + - #20 Fixed `--cpu-affinity` for more than 32 threads. + - Fixed Windows XP support. + - Fixed regression, option `--no-color` was not fully disable colored output. + - Show resolved pool IP address in miner output. + # v1.0.1 - Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. From 8e42fb9138416fe0dc72fe1831698c38827ad22a Mon Sep 17 00:00:00 2001 From: xmrig Date: Sun, 2 Jul 2017 07:36:24 +0300 Subject: [PATCH 91/92] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b488dca..3b45c559 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ # v2.0.0 - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` - - #15 Added option `-l, --log-file=FILE` to write log to file. - - #15 Added option `-S, --syslog` to use syslog for logging, Linux only. - - #18 Added nice messages for accepted/rejected shares with diff and network latency. - - #20 Fixed `--cpu-affinity` for more than 32 threads. + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. + - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. + - [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. - Fixed Windows XP support. - Fixed regression, option `--no-color` was not fully disable colored output. - Show resolved pool IP address in miner output. From 7937c814ff3f3eb9ad70c46e23e80f42db393a24 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 2 Jul 2017 21:49:56 +0300 Subject: [PATCH 92/92] v2.0.0 rc --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 1c9575ae..91be4b1f 100644 --- a/src/version.h +++ b/src/version.h @@ -27,7 +27,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "2.0.0-dev" +#define APP_VERSION "2.0.0" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com"