diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ef9573d..c5849269 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+# v2.8.0
+- **[#753](https://github.com/xmrig/xmrig/issues/753) Added new algorithm [CryptoNight variant 2](https://github.com/xmrig/xmrig/issues/753) for Monero fork, thanks [@SChernykh](https://github.com/SChernykh).**
+ - Added global and per thread option `"asm"` and and command line equivalent.
+- **[#758](https://github.com/xmrig/xmrig/issues/758) Added SSL/TLS support for secure connections to pools.**
+ - Added per pool options `"tls"` and `"tls-fingerprint"` and command line equivalents.
+- [#767](https://github.com/xmrig/xmrig/issues/767) Added config autosave feature, same with GPU miners.
+- [#245](https://github.com/xmrig/xmrig-proxy/issues/245) Fixed API ID collision when run multiple miners on same machine.
+- [#757](https://github.com/xmrig/xmrig/issues/757) Fixed send buffer overflow.
+
# v2.6.4
- [#700](https://github.com/xmrig/xmrig/issues/700) `cryptonight-lite/ipbc` replaced to `cryptonight-heavy/tube` for **Bittube (TUBE)**.
- Added `cryptonight/rto` (cryptonight variant 1 with IPBC/TUBE mod) variant for **Arto (RTO)** coin.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e263808e..1becac5c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,11 +1,14 @@
cmake_minimum_required(VERSION 2.8)
project(xmrig)
-option(WITH_LIBCPUID "Use Libcpuid" ON)
-option(WITH_AEON "CryptoNight-Lite support" ON)
-option(WITH_SUMO "CryptoNight-Heavy support" ON)
-option(WITH_HTTPD "HTTP REST API" ON)
-option(BUILD_STATIC "Build static binary" OFF)
+option(WITH_LIBCPUID "Use Libcpuid" ON)
+option(WITH_AEON "CryptoNight-Lite support" ON)
+option(WITH_SUMO "CryptoNight-Heavy support" ON)
+option(WITH_HTTPD "HTTP REST API" ON)
+option(WITH_DEBUG_LOG "Enable debug log output" OFF)
+option(WITH_TLS "Enable OpenSSL support" ON)
+option(WITH_ASM "Enable ASM PoW implementations" ON)
+option(BUILD_STATIC "Build static binary" OFF)
include (CheckIncludeFile)
include (cmake/cpu.cmake)
@@ -18,6 +21,7 @@ set(HEADERS
src/common/config/ConfigLoader.h
src/common/config/ConfigWatcher.h
src/common/Console.h
+ src/common/cpu/Cpu.h
src/common/crypto/Algorithm.h
src/common/crypto/keccak.h
src/common/interfaces/IClientListener.h
@@ -25,10 +29,12 @@ set(HEADERS
src/common/interfaces/IConfigCreator.h
src/common/interfaces/IConsoleListener.h
src/common/interfaces/IControllerListener.h
+ src/common/interfaces/ICpuInfo.h
src/common/interfaces/ILogBackend.h
src/common/interfaces/IStrategy.h
src/common/interfaces/IStrategyListener.h
src/common/interfaces/IWatcherListener.h
+ src/common/log/BasicLog.h
src/common/log/ConsoleLog.h
src/common/log/FileLog.h
src/common/log/Log.h
@@ -46,7 +52,6 @@ set(HEADERS
src/common/xmrig.h
src/core/ConfigLoader_platform.h
src/core/Controller.h
- src/Cpu.h
src/interfaces/IJobResultListener.h
src/interfaces/IThread.h
src/interfaces/IWorker.h
@@ -94,6 +99,7 @@ set(SOURCES
src/common/Console.cpp
src/common/crypto/Algorithm.cpp
src/common/crypto/keccak.cpp
+ src/common/log/BasicLog.cpp
src/common/log/ConsoleLog.cpp
src/common/log/FileLog.cpp
src/common/log/Log.cpp
@@ -131,7 +137,6 @@ if (WIN32)
res/app.rc
src/App_win.cpp
src/common/Platform_win.cpp
- src/Cpu_win.cpp
src/Mem_win.cpp
)
@@ -141,18 +146,16 @@ elseif (APPLE)
set(SOURCES_OS
src/App_unix.cpp
src/common/Platform_mac.cpp
- src/Cpu_mac.cpp
src/Mem_unix.cpp
)
else()
set(SOURCES_OS
src/App_unix.cpp
src/common/Platform_unix.cpp
- src/Cpu_unix.cpp
src/Mem_unix.cpp
)
- set(EXTRA_LIBS pthread rt)
+ set(EXTRA_LIBS pthread rt dl)
endif()
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
@@ -168,7 +171,6 @@ endif()
add_definitions(/D__STDC_FORMAT_MACROS)
add_definitions(/DUNICODE)
-#add_definitions(/DAPP_DEBUG)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
@@ -181,17 +183,21 @@ if (WITH_LIBCPUID)
include_directories(src/3rdparty/libcpuid)
set(CPUID_LIB cpuid)
- set(SOURCES_CPUID src/Cpu.cpp)
+ set(SOURCES_CPUID src/core/cpu/AdvancedCpuInfo.h src/core/cpu/AdvancedCpuInfo.cpp src/core/cpu/Cpu.cpp)
else()
add_definitions(/DXMRIG_NO_LIBCPUID)
+ set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp)
if (XMRIG_ARM)
- set(SOURCES_CPUID src/Cpu_arm.cpp)
+ set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp)
else()
- set(SOURCES_CPUID src/Cpu_stub.cpp)
+ set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp)
endif()
endif()
+include(cmake/OpenSSL.cmake)
+include(cmake/asm.cmake)
+
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_SYSLOG_H)
@@ -231,6 +237,7 @@ if (WITH_HTTPD)
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
endif()
else()
+ set(HTTPD_SOURCES "")
set(MHD_LIBRARY "")
add_definitions(/DXMRIG_NO_HTTPD)
add_definitions(/DXMRIG_NO_API)
@@ -244,5 +251,9 @@ if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS " -static")
endif()
-add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES})
-target_link_libraries(${PROJECT_NAME} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
+if (WITH_DEBUG_LOG)
+ add_definitions(/DAPP_DEBUG)
+endif()
+
+add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES})
+target_link_libraries(${PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
diff --git a/README.md b/README.md
index 6054b9f8..77b8f394 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# XMRig
-:warning: **If you mine Monero, Aeon, Sumokoin, Turtlecoin, Stellite, GRAFT, Haven Protocol, IPBC, [PLEASE READ](https://github.com/xmrig/xmrig/issues/482)!** :warning:
+:warning: **[Monero will change PoW algorithm on October 18](https://github.com/xmrig/xmrig/issues/753), all miners and proxy should be updated to v2.8+** :warning:
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
@@ -87,11 +87,22 @@ Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or shar
Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options.
## Algorithm variations
-Since version 0.8.0.
-* `--av=1` For CPUs with hardware AES.
-* `--av=2` Lower power mode (double hash) of `1`.
-* `--av=3` Software AES implementation.
-* `--av=4` Lower power mode (double hash) of `3`.
+
+- `av` option used for automatic and simple threads mode (when you specify only threads count).
+- For [advanced threads mode](https://github.com/xmrig/xmrig/issues/563) each thread configured individually and `av` option not used.
+
+| av | Hashes per round | Hardware AES |
+|----|------------------|--------------|
+| 1 | 1 (Single) | yes |
+| 2 | 2 (Double) | yes |
+| 3 | 1 (Single) | no |
+| 4 | 2 (Double) | no |
+| 5 | 3 (Triple) | yes |
+| 6 | 4 (Quard) | yes |
+| 7 | 5 (Penta) | yes |
+| 8 | 3 (Triple) | no |
+| 9 | 4 (Quard) | no |
+| 10 | 5 (Penta) | no |
## Common Issues
### HUGE PAGES unavailable
@@ -100,8 +111,7 @@ Since version 0.8.0.
## Other information
* No HTTP support, only stratum protocol support.
-* No TLS support.
-* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
+* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via option `donate-level`.
### CPU mining performance
diff --git a/cmake/OpenSSL.cmake b/cmake/OpenSSL.cmake
new file mode 100644
index 00000000..ed287e7e
--- /dev/null
+++ b/cmake/OpenSSL.cmake
@@ -0,0 +1,23 @@
+if (WITH_TLS)
+ set(OPENSSL_ROOT_DIR ${XMRIG_DEPS})
+
+ if (WIN32)
+ set(OPENSSL_USE_STATIC_LIBS TRUE)
+ set(OPENSSL_MSVC_STATIC_RT TRUE)
+
+ set(EXTRA_LIBS ${EXTRA_LIBS} Crypt32)
+ endif()
+
+ find_package(OpenSSL)
+
+ if (OPENSSL_FOUND)
+ set(TLS_SOURCES src/common/net/Tls.h src/common/net/Tls.cpp)
+ include_directories(${OPENSSL_INCLUDE_DIR})
+ else()
+ message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
+ endif()
+else()
+ set(TLS_SOURCES "")
+ set(OPENSSL_LIBRARIES "")
+ add_definitions(/DXMRIG_NO_TLS)
+endif()
diff --git a/cmake/asm.cmake b/cmake/asm.cmake
new file mode 100644
index 00000000..cb50f0d9
--- /dev/null
+++ b/cmake/asm.cmake
@@ -0,0 +1,27 @@
+if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(XMRIG_ASM_LIBRARY "xmrig-asm")
+
+ if (CMAKE_C_COMPILER_ID MATCHES MSVC)
+ enable_language(ASM_MASM)
+ set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop.asm")
+ set_property(SOURCE ${XMRIG_ASM_FILE} PROPERTY ASM_MASM)
+ else()
+ enable_language(ASM)
+
+ if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU)
+ set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop_win.S")
+ else()
+ set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop.S")
+ endif()
+
+ set_property(SOURCE ${XMRIG_ASM_FILE} PROPERTY C)
+ endif()
+
+ add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILE})
+ set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp)
+ set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
+else()
+ set(XMRIG_ASM_SOURCES "")
+ set(XMRIG_ASM_LIBRARY "")
+ add_definitions(/DXMRIG_NO_ASM)
+endif()
diff --git a/cmake/flags.cmake b/cmake/flags.cmake
index 498f2165..8bc14804 100644
--- a/cmake/flags.cmake
+++ b/cmake/flags.cmake
@@ -15,7 +15,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-class-memaccess")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
if (XMRIG_ARMv8)
diff --git a/src/3rdparty/libcpuid/asm-bits.c b/src/3rdparty/libcpuid/asm-bits.c
index b8e32284..bfabd404 100644
--- a/src/3rdparty/libcpuid/asm-bits.c
+++ b/src/3rdparty/libcpuid/asm-bits.c
@@ -1,825 +1,836 @@
-/*
- * Copyright 2008 Veselin Georgiev,
- * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
- *
- * 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 AUTHOR ``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 AUTHOR 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.
- */
-
-#include "libcpuid.h"
-#include "asm-bits.h"
-
-int cpuid_exists_by_eflags(void)
-{
-#if defined(PLATFORM_X64)
- return 1; /* CPUID is always present on the x86_64 */
-#elif defined(PLATFORM_X86)
-# if defined(COMPILER_GCC)
- int result;
- __asm __volatile(
- " pushfl\n"
- " pop %%eax\n"
- " mov %%eax, %%ecx\n"
- " xor $0x200000, %%eax\n"
- " push %%eax\n"
- " popfl\n"
- " pushfl\n"
- " pop %%eax\n"
- " xor %%ecx, %%eax\n"
- " mov %%eax, %0\n"
- " push %%ecx\n"
- " popfl\n"
- : "=m"(result)
- : :"eax", "ecx", "memory");
- return (result != 0);
-# elif defined(COMPILER_MICROSOFT)
- int result;
- __asm {
- pushfd
- pop eax
- mov ecx, eax
- xor eax, 0x200000
- push eax
- popfd
- pushfd
- pop eax
- xor eax, ecx
- mov result, eax
- push ecx
- popfd
- };
- return (result != 0);
-# else
- return 0;
-# endif /* COMPILER_MICROSOFT */
-#else
- return 0;
-#endif /* PLATFORM_X86 */
-}
-
-#ifdef INLINE_ASM_SUPPORTED
-/*
- * with MSVC/AMD64, the exec_cpuid() and cpu_rdtsc() functions
- * are implemented in separate .asm files. Otherwise, use inline assembly
- */
-void exec_cpuid(uint32_t *regs)
-{
-#ifdef COMPILER_GCC
-# ifdef PLATFORM_X64
- __asm __volatile(
- " mov %0, %%rdi\n"
-
- " push %%rbx\n"
- " push %%rcx\n"
- " push %%rdx\n"
-
- " mov (%%rdi), %%eax\n"
- " mov 4(%%rdi), %%ebx\n"
- " mov 8(%%rdi), %%ecx\n"
- " mov 12(%%rdi), %%edx\n"
-
- " cpuid\n"
-
- " movl %%eax, (%%rdi)\n"
- " movl %%ebx, 4(%%rdi)\n"
- " movl %%ecx, 8(%%rdi)\n"
- " movl %%edx, 12(%%rdi)\n"
- " pop %%rdx\n"
- " pop %%rcx\n"
- " pop %%rbx\n"
- :
- :"m"(regs)
- :"memory", "eax", "rdi"
- );
-# else
- __asm __volatile(
- " mov %0, %%edi\n"
-
- " push %%ebx\n"
- " push %%ecx\n"
- " push %%edx\n"
-
- " mov (%%edi), %%eax\n"
- " mov 4(%%edi), %%ebx\n"
- " mov 8(%%edi), %%ecx\n"
- " mov 12(%%edi), %%edx\n"
-
- " cpuid\n"
-
- " mov %%eax, (%%edi)\n"
- " mov %%ebx, 4(%%edi)\n"
- " mov %%ecx, 8(%%edi)\n"
- " mov %%edx, 12(%%edi)\n"
- " pop %%edx\n"
- " pop %%ecx\n"
- " pop %%ebx\n"
- :
- :"m"(regs)
- :"memory", "eax", "edi"
- );
-# endif /* COMPILER_GCC */
-#else
-# ifdef COMPILER_MICROSOFT
- __asm {
- push ebx
- push ecx
- push edx
- push edi
- mov edi, regs
-
- mov eax, [edi]
- mov ebx, [edi+4]
- mov ecx, [edi+8]
- mov edx, [edi+12]
-
- cpuid
-
- mov [edi], eax
- mov [edi+4], ebx
- mov [edi+8], ecx
- mov [edi+12], edx
-
- pop edi
- pop edx
- pop ecx
- pop ebx
- }
-# else
-# error "Unsupported compiler"
-# endif /* COMPILER_MICROSOFT */
-#endif
-}
-#endif /* INLINE_ASSEMBLY_SUPPORTED */
-
-#ifdef INLINE_ASM_SUPPORTED
-void cpu_rdtsc(uint64_t* result)
-{
- uint32_t low_part, hi_part;
-#ifdef COMPILER_GCC
- __asm __volatile (
- " rdtsc\n"
- " mov %%eax, %0\n"
- " mov %%edx, %1\n"
- :"=m"(low_part), "=m"(hi_part)::"memory", "eax", "edx"
- );
-#else
-# ifdef COMPILER_MICROSOFT
- __asm {
- rdtsc
- mov low_part, eax
- mov hi_part, edx
- };
-# else
-# error "Unsupported compiler"
-# endif /* COMPILER_MICROSOFT */
-#endif /* COMPILER_GCC */
- *result = (uint64_t)low_part + (((uint64_t) hi_part) << 32);
-}
-#endif /* INLINE_ASM_SUPPORTED */
-
-#ifdef INLINE_ASM_SUPPORTED
-void busy_sse_loop(int cycles)
-{
-#ifdef COMPILER_GCC
-#ifndef __APPLE__
-# define XALIGN ".balign 16\n"
-#else
-# define XALIGN ".align 4\n"
-#endif
- __asm __volatile (
- " xorps %%xmm0, %%xmm0\n"
- " xorps %%xmm1, %%xmm1\n"
- " xorps %%xmm2, %%xmm2\n"
- " xorps %%xmm3, %%xmm3\n"
- " xorps %%xmm4, %%xmm4\n"
- " xorps %%xmm5, %%xmm5\n"
- " xorps %%xmm6, %%xmm6\n"
- " xorps %%xmm7, %%xmm7\n"
- XALIGN
- /* ".bsLoop:\n" */
- "1:\n"
- // 0:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 1:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 2:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 3:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 4:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 5:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 6:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 7:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 8:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- // 9:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //10:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //11:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //12:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //13:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //14:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //15:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //16:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //17:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //18:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //19:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //20:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //21:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //22:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //23:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //24:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //25:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //26:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //27:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //28:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //29:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //30:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
- //31:
- " addps %%xmm1, %%xmm0\n"
- " addps %%xmm2, %%xmm1\n"
- " addps %%xmm3, %%xmm2\n"
- " addps %%xmm4, %%xmm3\n"
- " addps %%xmm5, %%xmm4\n"
- " addps %%xmm6, %%xmm5\n"
- " addps %%xmm7, %%xmm6\n"
- " addps %%xmm0, %%xmm7\n"
-
- " dec %%eax\n"
- /* "jnz .bsLoop\n" */
- " jnz 1b\n"
- ::"a"(cycles)
- );
-#else
-# ifdef COMPILER_MICROSOFT
- __asm {
- mov eax, cycles
- 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 eax
- jnz bsLoop
- }
-# else
-# error "Unsupported compiler"
-# endif /* COMPILER_MICROSOFT */
-#endif /* COMPILER_GCC */
-}
-#endif /* INLINE_ASSEMBLY_SUPPORTED */
+/*
+ * Copyright 2008 Veselin Georgiev,
+ * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
+ *
+ * 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 AUTHOR ``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 AUTHOR 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.
+ */
+
+#include "libcpuid.h"
+#include "asm-bits.h"
+
+int cpuid_exists_by_eflags(void)
+{
+#if defined(PLATFORM_X64)
+ return 1; /* CPUID is always present on the x86_64 */
+#elif defined(PLATFORM_X86)
+# if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
+ int result;
+ __asm __volatile(
+ " pushfl\n"
+ " pop %%eax\n"
+ " mov %%eax, %%ecx\n"
+ " xor $0x200000, %%eax\n"
+ " push %%eax\n"
+ " popfl\n"
+ " pushfl\n"
+ " pop %%eax\n"
+ " xor %%ecx, %%eax\n"
+ " mov %%eax, %0\n"
+ " push %%ecx\n"
+ " popfl\n"
+ : "=m"(result)
+ : :"eax", "ecx", "memory");
+ return (result != 0);
+# elif defined(COMPILER_MICROSOFT)
+ int result;
+ __asm {
+ pushfd
+ pop eax
+ mov ecx, eax
+ xor eax, 0x200000
+ push eax
+ popfd
+ pushfd
+ pop eax
+ xor eax, ecx
+ mov result, eax
+ push ecx
+ popfd
+ };
+ return (result != 0);
+# else
+ return 0;
+# endif /* COMPILER_MICROSOFT */
+#elif defined(PLATFORM_ARM)
+ return 0;
+#else
+ return 0;
+#endif /* PLATFORM_X86 */
+}
+
+#ifdef INLINE_ASM_SUPPORTED
+/*
+ * with MSVC/AMD64, the exec_cpuid() and cpu_rdtsc() functions
+ * are implemented in separate .asm files. Otherwise, use inline assembly
+ */
+void exec_cpuid(uint32_t *regs)
+{
+# if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
+# ifdef PLATFORM_X64
+ __asm __volatile(
+ " mov %0, %%rdi\n"
+
+ " push %%rbx\n"
+ " push %%rcx\n"
+ " push %%rdx\n"
+
+ " mov (%%rdi), %%eax\n"
+ " mov 4(%%rdi), %%ebx\n"
+ " mov 8(%%rdi), %%ecx\n"
+ " mov 12(%%rdi), %%edx\n"
+
+ " cpuid\n"
+
+ " movl %%eax, (%%rdi)\n"
+ " movl %%ebx, 4(%%rdi)\n"
+ " movl %%ecx, 8(%%rdi)\n"
+ " movl %%edx, 12(%%rdi)\n"
+ " pop %%rdx\n"
+ " pop %%rcx\n"
+ " pop %%rbx\n"
+ :
+ :"m"(regs)
+ :"memory", "eax", "rdi"
+ );
+# elif defined(PLATFORM_X86)
+ __asm __volatile(
+ " mov %0, %%edi\n"
+
+ " push %%ebx\n"
+ " push %%ecx\n"
+ " push %%edx\n"
+
+ " mov (%%edi), %%eax\n"
+ " mov 4(%%edi), %%ebx\n"
+ " mov 8(%%edi), %%ecx\n"
+ " mov 12(%%edi), %%edx\n"
+
+ " cpuid\n"
+
+ " mov %%eax, (%%edi)\n"
+ " mov %%ebx, 4(%%edi)\n"
+ " mov %%ecx, 8(%%edi)\n"
+ " mov %%edx, 12(%%edi)\n"
+ " pop %%edx\n"
+ " pop %%ecx\n"
+ " pop %%ebx\n"
+ :
+ :"m"(regs)
+ :"memory", "eax", "edi"
+ );
+# elif defined(PLATFORM_ARM)
+# endif /* COMPILER_GCC */
+#else
+# ifdef COMPILER_MICROSOFT
+ __asm {
+ push ebx
+ push ecx
+ push edx
+ push edi
+ mov edi, regs
+
+ mov eax, [edi]
+ mov ebx, [edi+4]
+ mov ecx, [edi+8]
+ mov edx, [edi+12]
+
+ cpuid
+
+ mov [edi], eax
+ mov [edi+4], ebx
+ mov [edi+8], ecx
+ mov [edi+12], edx
+
+ pop edi
+ pop edx
+ pop ecx
+ pop ebx
+ }
+# else
+# error "Unsupported compiler"
+# endif /* COMPILER_MICROSOFT */
+#endif
+}
+#endif /* INLINE_ASSEMBLY_SUPPORTED */
+
+#ifdef INLINE_ASM_SUPPORTED
+void cpu_rdtsc(uint64_t* result)
+{
+ uint32_t low_part, hi_part;
+#if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
+#ifdef PLATFORM_ARM
+ low_part = 0;
+ hi_part = 0;
+#else
+ __asm __volatile (
+ " rdtsc\n"
+ " mov %%eax, %0\n"
+ " mov %%edx, %1\n"
+ :"=m"(low_part), "=m"(hi_part)::"memory", "eax", "edx"
+ );
+#endif
+#else
+# ifdef COMPILER_MICROSOFT
+ __asm {
+ rdtsc
+ mov low_part, eax
+ mov hi_part, edx
+ };
+# else
+# error "Unsupported compiler"
+# endif /* COMPILER_MICROSOFT */
+#endif /* COMPILER_GCC */
+ *result = (uint64_t)low_part + (((uint64_t) hi_part) << 32);
+}
+#endif /* INLINE_ASM_SUPPORTED */
+
+#ifdef INLINE_ASM_SUPPORTED
+void busy_sse_loop(int cycles)
+{
+# if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
+#ifndef __APPLE__
+# define XALIGN ".balign 16\n"
+#else
+# define XALIGN ".align 4\n"
+#endif
+#ifdef PLATFORM_ARM
+#else
+ __asm __volatile (
+ " xorps %%xmm0, %%xmm0\n"
+ " xorps %%xmm1, %%xmm1\n"
+ " xorps %%xmm2, %%xmm2\n"
+ " xorps %%xmm3, %%xmm3\n"
+ " xorps %%xmm4, %%xmm4\n"
+ " xorps %%xmm5, %%xmm5\n"
+ " xorps %%xmm6, %%xmm6\n"
+ " xorps %%xmm7, %%xmm7\n"
+ XALIGN
+ /* ".bsLoop:\n" */
+ "1:\n"
+ // 0:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 1:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 2:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 3:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 4:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 5:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 6:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 7:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 8:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ // 9:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //10:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //11:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //12:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //13:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //14:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //15:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //16:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //17:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //18:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //19:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //20:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //21:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //22:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //23:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //24:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //25:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //26:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //27:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //28:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //29:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //30:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+ //31:
+ " addps %%xmm1, %%xmm0\n"
+ " addps %%xmm2, %%xmm1\n"
+ " addps %%xmm3, %%xmm2\n"
+ " addps %%xmm4, %%xmm3\n"
+ " addps %%xmm5, %%xmm4\n"
+ " addps %%xmm6, %%xmm5\n"
+ " addps %%xmm7, %%xmm6\n"
+ " addps %%xmm0, %%xmm7\n"
+
+ " dec %%eax\n"
+ /* "jnz .bsLoop\n" */
+ " jnz 1b\n"
+ ::"a"(cycles)
+ );
+#endif
+#else
+# ifdef COMPILER_MICROSOFT
+ __asm {
+ mov eax, cycles
+ 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 eax
+ jnz bsLoop
+ }
+# else
+# error "Unsupported compiler"
+# endif /* COMPILER_MICROSOFT */
+#endif /* COMPILER_GCC */
+}
+#endif /* INLINE_ASSEMBLY_SUPPORTED */
\ No newline at end of file
diff --git a/src/3rdparty/libcpuid/asm-bits.h b/src/3rdparty/libcpuid/asm-bits.h
index 3a03e11c..9049e2fe 100644
--- a/src/3rdparty/libcpuid/asm-bits.h
+++ b/src/3rdparty/libcpuid/asm-bits.h
@@ -1,53 +1,71 @@
-/*
- * Copyright 2008 Veselin Georgiev,
- * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
- *
- * 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 AUTHOR ``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 AUTHOR 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.
- */
-#ifndef __ASM_BITS_H__
-#define __ASM_BITS_H__
-#include "libcpuid.h"
-
-/* Determine Compiler: */
-#if defined(_MSC_VER)
-# define COMPILER_MICROSOFT
-#elif defined(__GNUC__)
-# define COMPILER_GCC
-#endif
-
-/* Determine Platform */
-#if defined(__x86_64__) || defined(_M_AMD64)
-# define PLATFORM_X64
-#elif defined(__i386__) || defined(_M_IX86)
-# define PLATFORM_X86
-#endif
-
-/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */
-#if (defined(COMPILER_GCC) && defined(PLATFORM_X64)) || defined(PLATFORM_X86)
-# define INLINE_ASM_SUPPORTED
-#endif
-
-int cpuid_exists_by_eflags(void);
-void exec_cpuid(uint32_t *regs);
-void busy_sse_loop(int cycles);
-
-#endif /* __ASM_BITS_H__ */
+/*
+ * Copyright 2008 Veselin Georgiev,
+ * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
+ *
+ * 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 AUTHOR ``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 AUTHOR 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.
+ */
+#ifndef __ASM_BITS_H__
+#define __ASM_BITS_H__
+#include "libcpuid.h"
+
+/* Determine Compiler: */
+#if defined(_MSC_VER)
+#if !defined(COMPILER_MICROSOFT)
+# define COMPILER_MICROSOFT
+#endif
+#elif defined(__GNUC__)
+#if !defined(COMPILER_GCC)
+# define COMPILER_GCC
+#endif
+#elif defined(__clang__)
+#if !defined(COMPILER_CLANG)
+# define COMPILER_CLANG
+#endif
+#endif
+
+/* Determine Platform */
+#if defined(__x86_64__) || defined(_M_AMD64)
+#if !defined(PLATFORM_X64)
+# define PLATFORM_X64
+#endif
+#elif defined(__i386__) || defined(_M_IX86)
+#if !defined(PLATFORM_X86)
+# define PLATFORM_X86
+#endif
+#elif defined(__ARMEL__)
+#if !defined(PLATFORM_ARM)
+# define PLATFORM_ARM
+#endif
+#endif
+
+/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */
+#if (((defined(COMPILER_GCC) || defined(COMPILER_CLANG))) && \
+ (defined(PLATFORM_X64) || defined(PLATFORM_X86) || defined(PLATFORM_ARM))) || \
+ (defined(COMPILER_MICROSOFT) && defined(PLATFORM_X86))
+# define INLINE_ASM_SUPPORTED
+#endif
+
+int cpuid_exists_by_eflags(void);
+void exec_cpuid(uint32_t *regs);
+void busy_sse_loop(int cycles);
+
+#endif /* __ASM_BITS_H__ */
diff --git a/src/3rdparty/libcpuid/cpuid_main.c b/src/3rdparty/libcpuid/cpuid_main.c
index f22c7dd6..61cb638d 100644
--- a/src/3rdparty/libcpuid/cpuid_main.c
+++ b/src/3rdparty/libcpuid/cpuid_main.c
@@ -221,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);
diff --git a/src/3rdparty/libcpuid/libcpuid.h b/src/3rdparty/libcpuid/libcpuid.h
index c44990c3..847e5a4a 100644
--- a/src/3rdparty/libcpuid/libcpuid.h
+++ b/src/3rdparty/libcpuid/libcpuid.h
@@ -60,7 +60,7 @@
*/
/** @mainpage A simple libcpuid introduction
- *
+ *
* LibCPUID provides CPU identification and access to the CPUID and RDTSC
* instructions on the x86.
*
@@ -82,6 +82,7 @@
*/
/** @defgroup libcpuid LibCPUID
+ * @brief LibCPUID provides CPU identification
@{ */
/* Include some integer type specifications: */
@@ -535,23 +536,23 @@ typedef enum {
* @brief Describes common library error codes
*/
typedef enum {
- ERR_OK = 0, /*!< "No error" */
- ERR_NO_CPUID = -1, /*!< "CPUID instruction is not supported" */
- ERR_NO_RDTSC = -2, /*!< "RDTSC instruction is not supported" */
- ERR_NO_MEM = -3, /*!< "Memory allocation failed" */
- ERR_OPEN = -4, /*!< "File open operation failed" */
- ERR_BADFMT = -5, /*!< "Bad file format" */
- ERR_NOT_IMP = -6, /*!< "Not implemented" */
- ERR_CPU_UNKN = -7, /*!< "Unsupported processor" */
- ERR_NO_RDMSR = -8, /*!< "RDMSR instruction is not supported" */
- ERR_NO_DRIVER= -9, /*!< "RDMSR driver error (generic)" */
- ERR_NO_PERMS = -10, /*!< "No permissions to install RDMSR driver" */
- ERR_EXTRACT = -11, /*!< "Cannot extract RDMSR driver (read only media?)" */
- ERR_HANDLE = -12, /*!< "Bad handle" */
- ERR_INVMSR = -13, /*!< "Invalid MSR" */
- ERR_INVCNB = -14, /*!< "Invalid core number" */
- ERR_HANDLE_R = -15, /*!< "Error on handle read" */
- ERR_INVRANGE = -16, /*!< "Invalid given range" */
+ ERR_OK = 0, /*!< No error */
+ ERR_NO_CPUID = -1, /*!< CPUID instruction is not supported */
+ ERR_NO_RDTSC = -2, /*!< RDTSC instruction is not supported */
+ ERR_NO_MEM = -3, /*!< Memory allocation failed */
+ ERR_OPEN = -4, /*!< File open operation failed */
+ ERR_BADFMT = -5, /*!< Bad file format */
+ ERR_NOT_IMP = -6, /*!< Not implemented */
+ ERR_CPU_UNKN = -7, /*!< Unsupported processor */
+ ERR_NO_RDMSR = -8, /*!< RDMSR instruction is not supported */
+ ERR_NO_DRIVER= -9, /*!< RDMSR driver error (generic) */
+ ERR_NO_PERMS = -10, /*!< No permissions to install RDMSR driver */
+ ERR_EXTRACT = -11, /*!< Cannot extract RDMSR driver (read only media?) */
+ ERR_HANDLE = -12, /*!< Bad handle */
+ ERR_INVMSR = -13, /*!< Invalid MSR */
+ ERR_INVCNB = -14, /*!< Invalid core number */
+ ERR_HANDLE_R = -15, /*!< Error on handle read */
+ ERR_INVRANGE = -16, /*!< Invalid given range */
} cpu_error_t;
/**
@@ -668,7 +669,7 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw);
const char* cpuid_lib_version(void);
#ifdef __cplusplus
-}; /* extern "C" */
+} /* extern "C" */
#endif
diff --git a/src/3rdparty/libcpuid/libcpuid_internal.h b/src/3rdparty/libcpuid/libcpuid_internal.h
index 038aa209..64804616 100644
--- a/src/3rdparty/libcpuid/libcpuid_internal.h
+++ b/src/3rdparty/libcpuid/libcpuid_internal.h
@@ -75,8 +75,9 @@ enum _intel_bits_t {
_3 = LBIT( 14 ),
_5 = LBIT( 15 ),
_7 = LBIT( 16 ),
- XEON_ = LBIT( 17 ),
- ATOM_ = LBIT( 18 ),
+ _9 = LBIT( 17 ),
+ XEON_ = LBIT( 18 ),
+ ATOM_ = LBIT( 19 ),
};
typedef enum _intel_bits_t intel_bits_t;
diff --git a/src/3rdparty/libcpuid/libcpuid_types.h b/src/3rdparty/libcpuid/libcpuid_types.h
index 9e897275..0e667aa6 100644
--- a/src/3rdparty/libcpuid/libcpuid_types.h
+++ b/src/3rdparty/libcpuid/libcpuid_types.h
@@ -32,6 +32,32 @@
#ifndef __LIBCPUID_TYPES_H__
#define __LIBCPUID_TYPES_H__
-#include
+#if !defined(_MSC_VER) || _MSC_VER >= 1600
+# include
+#else
+/* we have to provide our own: */
+# if !defined(__int32_t_defined)
+typedef int int32_t;
+# endif
+
+# if !defined(__uint32_t_defined)
+typedef unsigned uint32_t;
+# endif
+
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+#if (defined _MSC_VER) && (_MSC_VER <= 1300)
+ /* MSVC 6.0: no long longs ... */
+ typedef signed __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+#else
+ /* all other sane compilers: */
+ typedef signed long long int64_t;
+ typedef unsigned long long uint64_t;
+#endif
+
+#endif
#endif /* __LIBCPUID_TYPES_H__ */
diff --git a/src/3rdparty/libcpuid/recog_amd.c b/src/3rdparty/libcpuid/recog_amd.c
index 352d733b..4726f633 100644
--- a/src/3rdparty/libcpuid/recog_amd.c
+++ b/src/3rdparty/libcpuid/recog_amd.c
@@ -49,6 +49,10 @@ enum _amd_model_codes_t {
_1400,
_1500,
_1600,
+ _1900,
+ _2400,
+ _2500,
+ _2700,
};
static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
diff --git a/src/3rdparty/libcpuid/recog_intel.c b/src/3rdparty/libcpuid/recog_intel.c
index 5467c19f..397d750e 100644
--- a/src/3rdparty/libcpuid/recog_intel.c
+++ b/src/3rdparty/libcpuid/recog_intel.c
@@ -376,7 +376,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
bits |= bit_matchtable[i].bit;
}
- if ((i = match_pattern(bs, "Core(TM) [im][357]")) != 0) {
+ if ((i = match_pattern(bs, "Core(TM) [im][3579]")) != 0) {
bits |= CORE_;
i--;
switch (bs[i + 9]) {
@@ -387,6 +387,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
case '3': bits |= _3; break;
case '5': bits |= _5; break;
case '7': bits |= _7; break;
+ case '9': bits |= _9; break;
}
}
for (i = 0; i < COUNT_OF(matchtable); i++)
diff --git a/src/App.cpp b/src/App.cpp
index adcc5752..134e4ef5 100644
--- a/src/App.cpp
+++ b/src/App.cpp
@@ -29,11 +29,11 @@
#include "api/Api.h"
#include "App.h"
#include "common/Console.h"
+#include "common/cpu/Cpu.h"
#include "common/log/Log.h"
#include "common/Platform.h"
#include "core/Config.h"
#include "core/Controller.h"
-#include "Cpu.h"
#include "crypto/CryptoNight.h"
#include "Mem.h"
#include "net/Network.h"
diff --git a/src/Summary.cpp b/src/Summary.cpp
index fe538fda..3c1d06a7 100644
--- a/src/Summary.cpp
+++ b/src/Summary.cpp
@@ -27,32 +27,31 @@
#include
+#include "common/cpu/Cpu.h"
#include "common/log/Log.h"
#include "common/net/Pool.h"
#include "core/Config.h"
#include "core/Controller.h"
-#include "Cpu.h"
+#include "crypto/Asm.h"
#include "Mem.h"
#include "Summary.h"
#include "version.h"
-static void print_versions(xmrig::Config *config)
+#ifndef XMRIG_NO_ASM
+static const char *coloredAsmNames[] = {
+ "\x1B[1;31mnone\x1B[0m",
+ "auto",
+ "\x1B[1;32mintel\x1B[0m",
+ "\x1B[1;32mryzen\x1B[0m"
+};
+
+
+inline static const char *asmName(xmrig::Assembly assembly, bool colors)
{
- char buf[16] = { 0 };
-
-# 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);
-# endif
-
- Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" libuv/%s%s")
- : " * %-13s%s/%s libuv/%s%s",
- "VERSIONS", APP_NAME, APP_VERSION, uv_version_string(), buf);
+ return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly);
}
+#endif
static void print_memory(xmrig::Config *config) {
@@ -70,21 +69,23 @@ static void print_memory(xmrig::Config *config) {
static void print_cpu(xmrig::Config *config)
{
+ using namespace xmrig;
+
if (config->isColors()) {
- Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s (%d) %sx64 %sAES-NI",
+ Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES",
"CPU",
- Cpu::brand(),
- Cpu::sockets(),
- Cpu::isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
- Cpu::hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-");
+ Cpu::info()->brand(),
+ Cpu::info()->sockets(),
+ Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
+ Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-");
# ifndef XMRIG_NO_LIBCPUID
- Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%.1f MB/%.1f MB", "CPU L2/L3", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
+ Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif
}
else {
- Log::i()->text(" * %-13s%s (%d) %sx64 %sAES-NI", "CPU", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-");
+ Log::i()->text(" * %-13s%s (%d) %sx64 %sAES", "CPU", Cpu::info()->brand(), Cpu::info()->sockets(), Cpu::info()->isX64() ? "" : "-", Cpu::info()->hasAES() ? "" : "-");
# ifndef XMRIG_NO_LIBCPUID
- Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
+ Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif
}
}
@@ -117,45 +118,21 @@ static void print_threads(xmrig::Config *config)
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel());
}
-}
+# ifndef XMRIG_NO_ASM
+ if (config->assembly() == xmrig::ASM_AUTO) {
+ const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
-static void print_pools(xmrig::Config *config)
-{
- const std::vector &pools = config->pools();
-
- for (size_t i = 0; i < pools.size(); ++i) {
- Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CYAN_BOLD("%s") " variant " WHITE_BOLD("%s")
- : " * POOL #%-7d%s variant %s",
- i + 1,
- pools[i].url(),
- pools[i].algorithm().variantName()
- );
+ Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
+ : " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
}
-
-# ifdef APP_DEBUG
- for (const Pool &pool : pools) {
- pool.print();
+ else {
+ Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
}
# endif
}
-#ifndef XMRIG_NO_API
-static void print_api(xmrig::Config *config)
-{
- const int port = config->apiPort();
- if (port == 0) {
- return;
- }
-
- Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN("%s:") CYAN_BOLD("%d")
- : " * %-13s%s:%d",
- "API BIND", config->isApiIPv6() ? "[::]" : "0.0.0.0", port);
-}
-#endif
-
-
static void print_commands(xmrig::Config *config)
{
if (config->isColors()) {
@@ -171,15 +148,12 @@ static void print_commands(xmrig::Config *config)
void Summary::print(xmrig::Controller *controller)
{
- print_versions(controller->config());
+ controller->config()->printVersions();
print_memory(controller->config());
print_cpu(controller->config());
print_threads(controller->config());
- print_pools(controller->config());
-
-# ifndef XMRIG_NO_API
- print_api(controller->config());
-# endif
+ controller->config()->printPools();
+ controller->config()->printAPI();
print_commands(controller->config());
}
diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp
index 07e425f1..dd7accf6 100644
--- a/src/api/ApiRouter.cpp
+++ b/src/api/ApiRouter.cpp
@@ -35,14 +35,13 @@
#include "api/ApiRouter.h"
#include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h"
+#include "common/cpu/Cpu.h"
#include "common/crypto/keccak.h"
#include "common/net/Job.h"
#include "common/Platform.h"
#include "core/Config.h"
#include "core/Controller.h"
-#include "Cpu.h"
#include "interfaces/IThread.h"
-#include "Mem.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
@@ -67,7 +66,7 @@ ApiRouter::ApiRouter(xmrig::Controller *controller) :
memset(m_workerId, 0, sizeof(m_workerId));
setWorkerId(controller->config()->apiWorkerId());
- genId();
+ genId(controller->config()->apiId());
}
@@ -145,10 +144,15 @@ void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) cons
}
-void ApiRouter::genId()
+void ApiRouter::genId(const char *id)
{
memset(m_id, 0, sizeof(m_id));
+ if (id && strlen(id) > 0) {
+ strncpy(m_id, id, sizeof(m_id) - 1);
+ return;
+ }
+
uv_interface_address_t *interfaces;
int count = 0;
@@ -160,11 +164,13 @@ void ApiRouter::genId()
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr);
- const size_t inSize = strlen(APP_KIND) + addrSize;
+ const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
+ const uint16_t port = static_cast(m_controller->config()->apiPort());
uint8_t *input = new uint8_t[inSize]();
- memcpy(input, interfaces[i].phys_addr, addrSize);
- memcpy(input + addrSize, APP_KIND, strlen(APP_KIND));
+ memcpy(input, &port, sizeof(uint16_t));
+ memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize);
+ memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
xmrig::keccak(input, inSize, hash);
Job::toHex(hash, 8, m_id);
@@ -232,13 +238,14 @@ void ApiRouter::getIdentify(rapidjson::Document &doc) const
void ApiRouter::getMiner(rapidjson::Document &doc) const
{
+ using namespace xmrig;
auto &allocator = doc.GetAllocator();
rapidjson::Value cpu(rapidjson::kObjectType);
- cpu.AddMember("brand", rapidjson::StringRef(Cpu::brand()), allocator);
- cpu.AddMember("aes", Cpu::hasAES(), allocator);
- cpu.AddMember("x64", Cpu::isX64(), allocator);
- cpu.AddMember("sockets", Cpu::sockets(), allocator);
+ cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator);
+ cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
+ cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
+ cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator);
diff --git a/src/api/ApiRouter.h b/src/api/ApiRouter.h
index 9e32cdae..b781d5a2 100644
--- a/src/api/ApiRouter.h
+++ b/src/api/ApiRouter.h
@@ -56,7 +56,7 @@ protected:
private:
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
- void genId();
+ void genId(const char *id);
void getConnection(rapidjson::Document &doc) const;
void getHashrate(rapidjson::Document &doc) const;
void getIdentify(rapidjson::Document &doc) const;
@@ -66,7 +66,7 @@ private:
void setWorkerId(const char *id);
void updateWorkerId(const char *id, const char *previousId);
- char m_id[17];
+ char m_id[32];
char m_workerId[128];
NetworkState m_network;
xmrig::Controller *m_controller;
diff --git a/src/common/Platform.cpp b/src/common/Platform.cpp
index 52b55987..a95f78e7 100644
--- a/src/common/Platform.cpp
+++ b/src/common/Platform.cpp
@@ -26,6 +26,12 @@
#include
+#ifndef XMRIG_NO_TLS
+# include
+# include
+#endif
+
+
#include "Platform.h"
@@ -61,3 +67,23 @@ const char *Platform::defaultConfigName()
*m_defaultConfigName = '\0';
return nullptr;
}
+
+
+void Platform::init(const char *userAgent)
+{
+# ifndef XMRIG_NO_TLS
+ SSL_library_init();
+ SSL_load_error_strings();
+ ERR_load_BIO_strings();
+ ERR_load_crypto_strings();
+ SSL_load_error_strings();
+ OpenSSL_add_all_digests();
+# endif
+
+ if (userAgent) {
+ m_userAgent = userAgent;
+ }
+ else {
+ m_userAgent = createUserAgent();
+ }
+}
diff --git a/src/common/Platform.h b/src/common/Platform.h
index 8704604a..5dfb9ff7 100644
--- a/src/common/Platform.h
+++ b/src/common/Platform.h
@@ -21,8 +21,8 @@
* along with this program. If not, see .
*/
-#ifndef __PLATFORM_H__
-#define __PLATFORM_H__
+#ifndef XMRIG_PLATFORM_H
+#define XMRIG_PLATFORM_H
#include
@@ -43,9 +43,11 @@ public:
static inline const char *userAgent() { return m_userAgent.data(); }
private:
+ static char *createUserAgent();
+
static char m_defaultConfigName[520];
static xmrig::c_str m_userAgent;
};
-#endif /* __PLATFORM_H__ */
+#endif /* XMRIG_PLATFORM_H */
diff --git a/src/common/Platform_mac.cpp b/src/common/Platform_mac.cpp
index b8181cc4..d0c533b0 100644
--- a/src/common/Platform_mac.cpp
+++ b/src/common/Platform_mac.cpp
@@ -38,7 +38,7 @@
#endif
-static inline char *createUserAgent()
+char *Platform::createUserAgent()
{
const size_t max = 160;
@@ -65,17 +65,6 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
}
-void Platform::init(const char *userAgent)
-{
- if (userAgent) {
- m_userAgent = userAgent;
- }
- else {
- m_userAgent = createUserAgent();
- }
-}
-
-
void Platform::setProcessPriority(int priority)
{
diff --git a/src/common/Platform_unix.cpp b/src/common/Platform_unix.cpp
index 97b32ee8..058920ec 100644
--- a/src/common/Platform_unix.cpp
+++ b/src/common/Platform_unix.cpp
@@ -52,7 +52,7 @@ typedef cpuset_t cpu_set_t;
#endif
-static inline char *createUserAgent()
+char *Platform::createUserAgent()
{
const size_t max = 160;
@@ -92,23 +92,11 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
}
-void Platform::init(const char *userAgent)
-{
- if (userAgent) {
- m_userAgent = userAgent;
- }
- else {
- m_userAgent = createUserAgent();
- }
-}
-
-
void Platform::setProcessPriority(int priority)
{
}
-
void Platform::setThreadPriority(int priority)
{
if (priority == -1) {
diff --git a/src/common/Platform_win.cpp b/src/common/Platform_win.cpp
index 47f41867..32b850d1 100644
--- a/src/common/Platform_win.cpp
+++ b/src/common/Platform_win.cpp
@@ -55,7 +55,7 @@ static inline OSVERSIONINFOEX winOsVersion()
}
-static inline char *createUserAgent()
+char *Platform::createUserAgent()
{
const auto osver = winOsVersion();
const size_t max = 160;
@@ -94,17 +94,6 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
}
-void Platform::init(const char *userAgent)
-{
- if (userAgent) {
- m_userAgent = userAgent;
- }
- else {
- m_userAgent = createUserAgent();
- }
-}
-
-
void Platform::setProcessPriority(int priority)
{
if (priority == -1) {
diff --git a/src/common/api/HttpRequest.cpp b/src/common/api/HttpRequest.cpp
index 01245dfc..6898a385 100644
--- a/src/common/api/HttpRequest.cpp
+++ b/src/common/api/HttpRequest.cpp
@@ -147,7 +147,7 @@ int xmrig::HttpRequest::end(int status, MHD_Response *rsp)
MHD_add_response_header(rsp, "Content-Type", "application/json");
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*");
MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT");
- MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization");
+ MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization, Content-Type");
const int ret = MHD_queue_response(m_connection, status, rsp);
MHD_destroy_response(rsp);
diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp
index 7e43b39d..beb2d0c9 100644
--- a/src/common/config/CommonConfig.cpp
+++ b/src/common/config/CommonConfig.cpp
@@ -29,12 +29,37 @@
#include
+#ifndef XMRIG_NO_HTTPD
+# include
+#endif
+
+
+#ifndef XMRIG_NO_TLS
+# include
+#endif
+
+
+#ifdef XMRIG_AMD_PROJECT
+# if defined(__APPLE__)
+# include
+# else
+# include "3rdparty/CL/cl.h"
+# endif
+#endif
+
+
+#ifdef XMRIG_NVIDIA_PROJECT
+# include "nvidia/cryptonight.h"
+#endif
+
+
#include "common/config/CommonConfig.h"
#include "common/log/Log.h"
#include "donate.h"
#include "rapidjson/document.h"
#include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h"
+#include "version.h"
xmrig::CommonConfig::CommonConfig() :
@@ -42,6 +67,7 @@ xmrig::CommonConfig::CommonConfig() :
m_adjusted(false),
m_apiIPv6(false),
m_apiRestricted(true),
+ m_autoSave(true),
m_background(false),
m_colors(true),
m_dryRun(false),
@@ -69,8 +95,102 @@ xmrig::CommonConfig::CommonConfig() :
}
-xmrig::CommonConfig::~CommonConfig()
+void xmrig::CommonConfig::printAPI()
{
+# ifndef XMRIG_NO_API
+ if (apiPort() == 0) {
+ return;
+ }
+
+ Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN("%s:") CYAN_BOLD("%d")
+ : " * %-13s%s:%d",
+ "API BIND", isApiIPv6() ? "[::]" : "0.0.0.0", apiPort());
+# endif
+}
+
+
+void xmrig::CommonConfig::printPools()
+{
+ for (size_t i = 0; i < m_activePools.size(); ++i) {
+ if (!isColors()) {
+ Log::i()->text(" * POOL #%-7zu%s variant=%s, TLS=%d",
+ i + 1,
+ m_activePools[i].url(),
+ m_activePools[i].algorithm().variantName(),
+ static_cast(m_activePools[i].isTLS())
+ );
+ }
+ else {
+ Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") "\x1B[1;%dm%s\x1B[0m variant " WHITE_BOLD("%s"),
+ i + 1,
+ m_activePools[i].isTLS() ? 32 : 36,
+ m_activePools[i].url(),
+ m_activePools[i].algorithm().variantName()
+ );
+ }
+ }
+
+# ifdef APP_DEBUG
+ LOG_NOTICE("POOLS --------------------------------------------------------------------");
+ for (const Pool &pool : m_activePools) {
+ pool.print();
+ }
+ LOG_NOTICE("--------------------------------------------------------------------------");
+# endif
+}
+
+
+void xmrig::CommonConfig::printVersions()
+{
+ char buf[256] = { 0 };
+
+# if defined(__clang__)
+ snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
+# elif defined(__GNUC__)
+ snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
+# elif defined(_MSC_VER)
+ snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION);
+# endif
+
+ Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s")
+ : " * %-13s%s/%s %s",
+ "ABOUT", APP_NAME, APP_VERSION, buf);
+
+# if defined(XMRIG_AMD_PROJECT)
+# if CL_VERSION_2_0
+ const char *ocl = "2.0";
+# elif CL_VERSION_1_2
+ const char *ocl = "1.2";
+# elif CL_VERSION_1_1
+ const char *ocl = "1.1";
+# elif CL_VERSION_1_0
+ const char *ocl = "1.0";
+# else
+ const char *ocl = "0.0";
+# endif
+ int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl);
+# elif defined(XMRIG_NVIDIA_PROJECT)
+ const int cudaVersion = cuda_get_runtime_version();
+ int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100);
+# else
+ memset(buf, 0, 16);
+ int length = 0;
+# endif
+
+# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
+ {
+ constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
+ length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast(strchr(v, ' ') - v), v);
+ }
+# endif
+
+# ifndef XMRIG_NO_HTTPD
+ length += snprintf(buf + length, (sizeof buf) - length, "microhttpd/%s ", MHD_get_version());
+# endif
+
+ Log::i()->text(isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s")
+ : " * %-13slibuv/%s %s",
+ "LIBS", uv_version_string(), buf);
}
@@ -98,7 +218,7 @@ bool xmrig::CommonConfig::save()
rapidjson::PrettyWriter writer(os);
doc.Accept(writer);
- fclose(fp);
+ fflush(fp);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
@@ -126,6 +246,12 @@ bool xmrig::CommonConfig::finalize()
pool.adjust(m_algorithm);
if (pool.isValid() && pool.algorithm().isValid()) {
+# ifdef XMRIG_NO_TLS
+ if (pool.isTLS()) {
+ continue;
+ }
+# endif
+
m_activePools.push_back(std::move(pool));
}
}
@@ -157,6 +283,10 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0);
break;
+ case TlsKey: /* --tls */
+ m_pools.back().setTLS(enable);
+ break;
+
# ifndef XMRIG_PROXY_PROJECT
case NicehashKey: /* --nicehash */
m_pools.back().setNicehash(enable);
@@ -179,10 +309,14 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
m_apiRestricted = enable;
break;
- case IConfig::DryRunKey: /* --dry-run */
+ case DryRunKey: /* --dry-run */
m_dryRun = enable;
break;
+ case AutoSaveKey:
+ m_autoSave = enable;
+ break;
+
default:
break;
}
@@ -235,6 +369,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
m_pools.back().setRigId(arg);
break;
+ case FingerprintKey: /* --tls-fingerprint */
+ m_pools.back().setFingerprint(arg);
+ break;
+
case VariantKey: /* --variant */
m_pools.back().algorithm().parseVariant(arg);
break;
@@ -251,6 +389,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
m_apiWorkerId = arg;
break;
+ case ApiIdKey: /* --api-id */
+ m_apiId = arg;
+ break;
+
case UserAgentKey: /* --user-agent */
m_userAgent = arg;
break;
@@ -265,6 +407,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
case SyslogKey: /* --syslog */
case KeepAliveKey: /* --keepalive */
case NicehashKey: /* --nicehash */
+ case TlsKey: /* --tls */
case ApiIPv6Key: /* --api-ipv6 */
case DryRunKey: /* --dry-run */
return parseBoolean(key, true);
diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h
index ffebb6b2..422a6bb2 100644
--- a/src/common/config/CommonConfig.h
+++ b/src/common/config/CommonConfig.h
@@ -21,8 +21,8 @@
* along with this program. If not, see .
*/
-#ifndef __COMMONCONFIG_H__
-#define __COMMONCONFIG_H__
+#ifndef XMRIG_COMMONCONFIG_H
+#define XMRIG_COMMONCONFIG_H
#include
@@ -41,14 +41,15 @@ class CommonConfig : public IConfig
{
public:
CommonConfig();
- ~CommonConfig();
inline bool isApiIPv6() const { return m_apiIPv6; }
inline bool isApiRestricted() const { return m_apiRestricted; }
+ inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; }
inline bool isColors() const { return m_colors; }
inline bool isDryRun() const { return m_dryRun; }
inline bool isSyslog() const { return m_syslog; }
+ inline const char *apiId() const { return m_apiId.data(); }
inline const char *apiToken() const { return m_apiToken.data(); }
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
inline const char *logFile() const { return m_logFile.data(); }
@@ -67,6 +68,10 @@ public:
bool save() override;
+ void printAPI();
+ void printPools();
+ void printVersions();
+
protected:
enum State {
NoneState,
@@ -84,6 +89,7 @@ protected:
bool m_adjusted;
bool m_apiIPv6;
bool m_apiRestricted;
+ bool m_autoSave;
bool m_background;
bool m_colors;
bool m_dryRun;
@@ -97,6 +103,7 @@ protected:
State m_state;
std::vector m_activePools;
std::vector m_pools;
+ xmrig::c_str m_apiId;
xmrig::c_str m_apiToken;
xmrig::c_str m_apiWorkerId;
xmrig::c_str m_fileName;
diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp
index cc5d9a49..484c2f8f 100644
--- a/src/common/config/ConfigLoader.cpp
+++ b/src/common/config/ConfigLoader.cpp
@@ -32,6 +32,11 @@
#endif
+#ifndef XMRIG_NO_TLS
+# include
+#endif
+
+
#include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h"
#include "common/interfaces/IConfig.h"
@@ -313,6 +318,13 @@ void xmrig::ConfigLoader::showVersion()
printf("\nlibuv/%s\n", uv_version_string());
# ifndef XMRIG_NO_HTTPD
- printf("libmicrohttpd/%s\n", MHD_get_version());
+ printf("microhttpd/%s\n", MHD_get_version());
+# endif
+
+# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
+ {
+ constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
+ printf("OpenSSL/%.*s\n", static_cast(strchr(v, ' ') - v), v);
+ }
# endif
}
diff --git a/src/Cpu_stub.cpp b/src/common/cpu/BasicCpuInfo.cpp
similarity index 77%
rename from src/Cpu_stub.cpp
rename to src/common/cpu/BasicCpuInfo.cpp
index 8b27ad65..66af53cc 100644
--- a/src/Cpu_stub.cpp
+++ b/src/common/cpu/BasicCpuInfo.cpp
@@ -21,6 +21,9 @@
* along with this program. If not, see .
*/
+#include
+#include
+
#ifdef _MSC_VER
# include
@@ -32,14 +35,8 @@
# define bit_AES (1 << 25)
#endif
-#ifndef bit_BMI2
-# define bit_BMI2 (1 << 8)
-#endif
-#include
-
-
-#include "Cpu.h"
+#include "common/cpu/BasicCpuInfo.h"
#define VENDOR_ID (0)
@@ -96,43 +93,18 @@ static inline bool has_aes_ni()
}
-static inline bool has_bmi2() {
- int cpu_info[4] = { 0 };
- cpuid(EXTENDED_FEATURES, cpu_info);
-
- return (cpu_info[EBX_Reg] & bit_BMI2) != 0;
-}
-
-
-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;
-size_t Cpu::m_totalThreads = 0;
-
-
-size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
-{
- const size_t count = m_totalThreads / 2;
- return count < 1 ? 1 : count;
-}
-
-
-void Cpu::initCommon()
+xmrig::BasicCpuInfo::BasicCpuInfo() :
+ m_aes(has_aes_ni()),
+ m_brand(),
+ m_threads(std::thread::hardware_concurrency())
{
cpu_brand_string(m_brand);
-
-# if defined(__x86_64__) || defined(_M_AMD64)
- m_flags |= X86_64;
-# endif
-
- if (has_aes_ni()) {
- m_flags |= AES;
- }
-
- if (has_bmi2()) {
- m_flags |= BMI2;
- }
+}
+
+
+size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
+{
+ const size_t count = threads() / 2;
+
+ return count < 1 ? 1 : count;
}
diff --git a/src/common/cpu/BasicCpuInfo.h b/src/common/cpu/BasicCpuInfo.h
new file mode 100644
index 00000000..f9d710d6
--- /dev/null
+++ b/src/common/cpu/BasicCpuInfo.h
@@ -0,0 +1,70 @@
+/* XMRig
+ * Copyright 2010 Jeff Garzik
+ * Copyright 2012-2014 pooler
+ * Copyright 2014 Lucas Jones
+ * Copyright 2014-2016 Wolf9466
+ * Copyright 2016 Jay D Dee
+ * Copyright 2017-2018 XMR-Stak ,
+ * Copyright 2016-2018 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_BASICCPUINFO_H
+#define XMRIG_BASICCPUINFO_H
+
+
+#include "common/interfaces/ICpuInfo.h"
+
+
+namespace xmrig {
+
+
+class BasicCpuInfo : public ICpuInfo
+{
+public:
+ BasicCpuInfo();
+
+protected:
+ size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
+
+ inline Assembly assembly() const override { return ASM_NONE; }
+ inline bool hasAES() const override { return m_aes; }
+ inline bool isSupported() const override { return true; }
+ inline const char *brand() const override { return m_brand; }
+ inline int32_t cores() const override { return -1; }
+ inline int32_t L2() const override { return -1; }
+ inline int32_t L3() const override { return -1; }
+ inline int32_t nodes() const override { return -1; }
+ inline int32_t sockets() const override { return 1; }
+ inline int32_t threads() const override { return m_threads; }
+
+# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
+ inline bool isX64() const override { return true; }
+# else
+ inline bool isX64() const override { return false; }
+# endif
+
+private:
+ bool m_aes;
+ char m_brand[64];
+ int32_t m_threads;
+};
+
+
+} /* namespace xmrig */
+
+
+#endif /* XMRIG_BASICCPUINFO_H */
diff --git a/src/Cpu_arm.cpp b/src/common/cpu/BasicCpuInfo_arm.cpp
similarity index 73%
rename from src/Cpu_arm.cpp
rename to src/common/cpu/BasicCpuInfo_arm.cpp
index 3e259d0d..c1c127db 100644
--- a/src/Cpu_arm.cpp
+++ b/src/common/cpu/BasicCpuInfo_arm.cpp
@@ -21,37 +21,27 @@
* along with this program. If not, see .
*/
-
#include
+#include
-#include "Cpu.h"
+#include "common/cpu/BasicCpuInfo.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;
-size_t Cpu::m_totalThreads = 0;
-
-
-size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
-{
- return m_totalThreads;
-}
-
-
-void Cpu::initCommon()
+xmrig::BasicCpuInfo::BasicCpuInfo() :
+ m_aes(false),
+ m_brand(),
+ m_threads(std::thread::hardware_concurrency())
{
memcpy(m_brand, "Unknown", 7);
-# if defined (__arm64__) || defined (__aarch64__)
- m_flags |= X86_64;
-# endif
-
# if __ARM_FEATURE_CRYPTO
- m_flags |= AES;
+ m_aes = true;
# endif
}
+
+
+size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
+{
+ return threads();
+}
diff --git a/src/Cpu_unix.cpp b/src/common/cpu/Cpu.cpp
similarity index 71%
rename from src/Cpu_unix.cpp
rename to src/common/cpu/Cpu.cpp
index b895c897..b1bb28ac 100644
--- a/src/Cpu_unix.cpp
+++ b/src/common/cpu/Cpu.cpp
@@ -22,33 +22,36 @@
*/
-#ifdef __FreeBSD__
-# include
-# include
-# include
-# include
-#endif
+#include
-#include
-#include
-#include
-#include
+#include "common/cpu/BasicCpuInfo.h"
+#include "common/cpu/Cpu.h"
-#include "Cpu.h"
+static xmrig::ICpuInfo *cpuInfo = nullptr;
-#ifdef __FreeBSD__
-typedef cpuset_t cpu_set_t;
-#endif
-
-
-void Cpu::init()
+xmrig::ICpuInfo *xmrig::Cpu::info()
{
-# ifdef XMRIG_NO_LIBCPUID
- m_totalThreads = sysconf(_SC_NPROCESSORS_CONF);
-# endif
+ assert(cpuInfo != nullptr);
- initCommon();
+ return cpuInfo;
+}
+
+
+void xmrig::Cpu::init()
+{
+ assert(cpuInfo == nullptr);
+
+ cpuInfo = new BasicCpuInfo();
+}
+
+
+void xmrig::Cpu::release()
+{
+ assert(cpuInfo != nullptr);
+
+ delete cpuInfo;
+ cpuInfo = nullptr;
}
diff --git a/src/Cpu_mac.cpp b/src/common/cpu/Cpu.h
similarity index 75%
rename from src/Cpu_mac.cpp
rename to src/common/cpu/Cpu.h
index 085148bc..1d5a9fb1 100644
--- a/src/Cpu_mac.cpp
+++ b/src/common/cpu/Cpu.h
@@ -4,7 +4,7 @@
* Copyright 2014 Lucas Jones
* Copyright 2014-2016 Wolf9466
* Copyright 2016 Jay D Dee
- * Copyright 2016 Jay D Dee
+ * Copyright 2017-2018 XMR-Stak ,
* Copyright 2016-2018 XMRig ,
*
* This program is free software: you can redistribute it and/or modify
@@ -21,20 +21,26 @@
* along with this program. If not, see .
*/
-
-#include
-#include
-#include
+#ifndef XMRIG_CPU_H
+#define XMRIG_CPU_H
-#include "Cpu.h"
+#include "common/interfaces/ICpuInfo.h"
-void Cpu::init()
+namespace xmrig {
+
+
+class Cpu
{
-# ifdef XMRIG_NO_LIBCPUID
- m_totalThreads = sysconf(_SC_NPROCESSORS_CONF);
-# endif
+public:
+ static ICpuInfo *info();
+ static void init();
+ static void release();
+};
- initCommon();
-}
+
+} /* namespace xmrig */
+
+
+#endif /* XMRIG_CPU_H */
diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp
index 31035fb1..a3cf48b2 100644
--- a/src/common/crypto/Algorithm.cpp
+++ b/src/common/crypto/Algorithm.cpp
@@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee
* Copyright 2017-2018 XMR-Stak ,
* Copyright 2018 Lee Clagett
+ * Copyright 2018 SChernykh
* Copyright 2016-2018 XMRig ,
*
* This program is free software: you can redistribute it and/or modify
@@ -60,6 +61,7 @@ static AlgoData const algorithms[] = {
{ "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR },
{ "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO },
{ "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO },
+ { "cryptonight/2", "cn/2", xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
# ifndef XMRIG_NO_AEON
{ "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
@@ -81,6 +83,8 @@ static AlgoData const algorithms[] = {
static AlgoData const xmrStakAlgorithms[] = {
{ "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
+ { "cryptonight-monerov8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
+ { "cryptonight_v8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
{ "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
{ "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 },
{ "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
@@ -103,7 +107,8 @@ static const char *variants[] = {
"msr",
"xhv",
"xao",
- "rto"
+ "rto",
+ "2",
};
@@ -172,11 +177,21 @@ void xmrig::Algorithm::parseVariant(const char *variant)
void xmrig::Algorithm::parseVariant(int variant)
{
- if (variant >= VARIANT_AUTO && variant < VARIANT_MAX) {
- m_variant = static_cast(variant);
- }
- else {
- assert(false);
+ assert(variant >= -1 && variant <= 2);
+
+ switch (variant) {
+ case -1:
+ case 0:
+ case 1:
+ m_variant = static_cast(variant);
+ break;
+
+ case 2:
+ m_variant = VARIANT_2;
+ break;
+
+ default:
+ break;
}
}
diff --git a/src/common/crypto/Algorithm.h b/src/common/crypto/Algorithm.h
index bcf029d8..731fa793 100644
--- a/src/common/crypto/Algorithm.h
+++ b/src/common/crypto/Algorithm.h
@@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee
* Copyright 2017-2018 XMR-Stak ,
* Copyright 2018 Lee Clagett
+ * Copyright 2018 SChernykh
* Copyright 2016-2018 XMRig ,
*
* This program is free software: you can redistribute it and/or modify
@@ -22,8 +23,8 @@
* along with this program. If not, see .
*/
-#ifndef __ALGORITHM_H__
-#define __ALGORITHM_H__
+#ifndef XMRIG_ALGORITHM_H
+#define XMRIG_ALGORITHM_H
#include
diff --git a/src/common/crypto/keccak.h b/src/common/crypto/keccak.h
index 0413ec2d..6121044a 100644
--- a/src/common/crypto/keccak.h
+++ b/src/common/crypto/keccak.h
@@ -23,8 +23,8 @@
*/
-#ifndef KECCAK_H_
-#define KECCAK_H_
+#ifndef XMRIG_KECCAK_H
+#define XMRIG_KECCAK_H
#include
#include
@@ -41,9 +41,15 @@ inline void keccak(const uint8_t *in, size_t inlen, uint8_t *md)
keccak(in, static_cast(inlen), md, 200);
}
+
+inline void keccak(const char *in, size_t inlen, uint8_t *md)
+{
+ keccak(reinterpret_cast(in), static_cast(inlen), md, 200);
+}
+
// update the state
void keccakf(uint64_t st[25], int norounds);
} /* namespace xmrig */
-#endif /* KECCAK_H_ */
+#endif /* XMRIG_KECCAK_H */
diff --git a/src/common/interfaces/IConfig.h b/src/common/interfaces/IConfig.h
index 62c7ba94..69f2ffab 100644
--- a/src/common/interfaces/IConfig.h
+++ b/src/common/interfaces/IConfig.h
@@ -20,8 +20,8 @@
* along with this program. If not, see .
*/
-#ifndef __ICONFIG_H__
-#define __ICONFIG_H__
+#ifndef XMRIG_ICONFIG_H
+#define XMRIG_ICONFIG_H
#include "common/crypto/Algorithm.h"
@@ -42,6 +42,7 @@ public:
ApiPort = 4000,
ApiRestrictedKey = 4004,
ApiWorkerIdKey = 4002,
+ ApiIdKey = 4005,
BackgroundKey = 'B',
ColorKey = 1002,
ConfigKey = 'c',
@@ -62,6 +63,9 @@ public:
VerboseKey = 1100,
VersionKey = 'V',
WatchKey = 1105,
+ TlsKey = 1013,
+ FingerprintKey = 1014,
+ AutoSaveKey = 1016,
// xmrig common
CPUPriorityKey = 1021,
@@ -77,12 +81,20 @@ public:
SafeKey = 1005,
ThreadsKey = 't',
HardwareAESKey = 1011,
+ AssemblyKey = 1015,
// xmrig amd
- OclPlatform = 1400,
- OclAffinity = 1401,
- OclDevices = 1402,
- OclLaunch = 1403,
+ OclPlatformKey = 1400,
+ OclAffinityKey = 1401,
+ OclDevicesKey = 1402,
+ OclLaunchKey = 1403,
+ OclCacheKey = 1404,
+ OclPrintKey = 1405,
+ OclLoaderKey = 1406,
+ OclSridedIndexKey = 1407,
+ OclMemChunkKey = 1408,
+ OclUnrollKey = 1409,
+ OclCompModeKey = 1410,
// xmrig-proxy
AccessLogFileKey = 'A',
@@ -94,6 +106,16 @@ public:
PoolCoinKey = 'C',
ReuseTimeoutKey = 1106,
WorkersKey = 1103,
+ WorkersAdvKey = 1107,
+
+ // xmrig nvidia
+ CudaMaxThreadsKey = 1200,
+ CudaBFactorKey = 1201,
+ CudaBSleepKey = 1202,
+ CudaDevicesKey = 1203,
+ CudaLaunchKey = 1204,
+ CudaAffinityKey = 1205,
+ CudaMaxUsageKey = 1206,
};
virtual ~IConfig() {}
@@ -115,4 +137,4 @@ public:
} /* namespace xmrig */
-#endif // __ICONFIG_H__
+#endif // XMRIG_ICONFIG_H
diff --git a/src/common/interfaces/IControllerListener.h b/src/common/interfaces/IControllerListener.h
index d6077138..35249bcd 100644
--- a/src/common/interfaces/IControllerListener.h
+++ b/src/common/interfaces/IControllerListener.h
@@ -21,8 +21,8 @@
* along with this program. If not, see .
*/
-#ifndef __ICONTROLLERLISTENER_H__
-#define __ICONTROLLERLISTENER_H__
+#ifndef XMRIG_ICONTROLLERLISTENER_H
+#define XMRIG_ICONTROLLERLISTENER_H
namespace xmrig {
@@ -43,4 +43,4 @@ public:
} /* namespace xmrig */
-#endif // __ICONTROLLERLISTENER_H__
+#endif // XMRIG_ICONTROLLERLISTENER_H
diff --git a/src/common/interfaces/ICpuInfo.h b/src/common/interfaces/ICpuInfo.h
new file mode 100644
index 00000000..267616d0
--- /dev/null
+++ b/src/common/interfaces/ICpuInfo.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-2018 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_CPUINFO_H
+#define XMRIG_CPUINFO_H
+
+
+#include
+#include
+
+
+#include "common/xmrig.h"
+
+
+namespace xmrig {
+
+
+class ICpuInfo
+{
+public:
+ virtual ~ICpuInfo() {}
+
+ virtual bool hasAES() const = 0;
+ virtual bool isSupported() const = 0;
+ virtual bool isX64() const = 0;
+ virtual const char *brand() const = 0;
+ virtual int32_t cores() const = 0;
+ virtual int32_t L2() const = 0;
+ virtual int32_t L3() const = 0;
+ virtual int32_t nodes() const = 0;
+ virtual int32_t sockets() const = 0;
+ virtual int32_t threads() const = 0;
+ virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0;
+ virtual xmrig::Assembly assembly() const = 0;
+};
+
+
+} /* namespace xmrig */
+
+
+#endif // XMRIG_CPUINFO_H
diff --git a/src/Cpu.h b/src/common/log/BasicLog.cpp
similarity index 50%
rename from src/Cpu.h
rename to src/common/log/BasicLog.cpp
index a125bae8..cb4defcd 100644
--- a/src/Cpu.h
+++ b/src/common/log/BasicLog.cpp
@@ -21,46 +21,69 @@
* along with this program. If not, see .
*/
-#ifndef __CPU_H__
-#define __CPU_H__
+
+#include
+#include
+#include
+#include
+#include
+
+#ifdef WIN32
+# include
+# include
+#endif
-#include
+#include "common/log/BasicLog.h"
+#include "common/log/Log.h"
-class Cpu
+BasicLog::BasicLog()
{
-public:
- enum Flags {
- X86_64 = 1,
- AES = 2,
- BMI2 = 4
- };
-
- static size_t optimalThreadsCount(size_t size, int maxCpuUsage);
- static void init();
-
- static inline bool hasAES() { return (m_flags & AES) != 0; }
- static inline bool isX64() { return (m_flags & X86_64) != 0; }
- 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 bool m_l2_exclusive;
- 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 size_t m_totalThreads;
-};
+}
-#endif /* __CPU_H__ */
+void BasicLog::message(Level 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
+
+ snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
+ stime.tm_year + 1900,
+ stime.tm_mon + 1,
+ stime.tm_mday,
+ stime.tm_hour,
+ stime.tm_min,
+ stime.tm_sec,
+ Log::colorByLevel(level, false),
+ fmt,
+ Log::endl(false)
+ );
+
+ print(args);
+}
+
+
+void BasicLog::text(const char* fmt, va_list args)
+{
+ snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(false));
+
+ print(args);
+}
+
+
+void BasicLog::print(va_list args)
+{
+ if (vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args) <= 0) {
+ return;
+ }
+
+ fputs(m_buf, stdout);
+ fflush(stdout);
+}
diff --git a/src/common/log/BasicLog.h b/src/common/log/BasicLog.h
new file mode 100644
index 00000000..523538e9
--- /dev/null
+++ b/src/common/log/BasicLog.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 2017-2018 XMR-Stak ,
+ * Copyright 2016-2018 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 __BASICLOG_H__
+#define __BASICLOG_H__
+
+
+#include
+
+
+#include "common/interfaces/ILogBackend.h"
+
+
+namespace xmrig {
+ class Controller;
+}
+
+
+class BasicLog : public ILogBackend
+{
+public:
+ BasicLog();
+
+ void message(Level level, const char *fmt, va_list args) override;
+ void text(const char *fmt, va_list args) override;
+
+private:
+ bool isWritable() const;
+ void print(va_list args);
+
+ char m_buf[kBufferSize];
+ char m_fmt[256];
+};
+
+#endif /* __BASICLOG_H__ */
diff --git a/src/common/log/Log.cpp b/src/common/log/Log.cpp
index ccf38008..2af90209 100644
--- a/src/common/log/Log.cpp
+++ b/src/common/log/Log.cpp
@@ -30,6 +30,7 @@
#include "common/interfaces/ILogBackend.h"
+#include "common/log/BasicLog.h"
#include "common/log/Log.h"
@@ -109,6 +110,14 @@ const char *Log::endl(bool isColors)
}
+void Log::defaultInit()
+{
+ m_self = new Log();
+
+ add(new BasicLog());
+}
+
+
Log::~Log()
{
for (auto backend : m_backends) {
diff --git a/src/common/log/Log.h b/src/common/log/Log.h
index bfa30717..2774ae0c 100644
--- a/src/common/log/Log.h
+++ b/src/common/log/Log.h
@@ -36,7 +36,7 @@
class Log
{
public:
- static inline Log* i() { assert(m_self != nullptr); return m_self; }
+ static inline Log* i() { if (!m_self) { defaultInit(); } return m_self; }
static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); }
static inline void init() { if (!m_self) { new Log(); } }
static inline void release() { assert(m_self != nullptr); delete m_self; }
@@ -46,6 +46,7 @@ public:
static const char *colorByLevel(ILogBackend::Level level, bool isColors = true);
static const char *endl(bool isColors = true);
+ static void defaultInit();
private:
inline Log() {
@@ -68,6 +69,8 @@ private:
#define RED(x) "\x1B[0;31m" x "\x1B[0m"
#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m"
#define GREEN(x) "\x1B[0;32m" x "\x1B[0m"
+#define YELLOW(x) "\x1B[0;33m" x "\x1B[0m"
+#define YELLOW_BOLD(x) "\x1B[1;33m" x "\x1B[0m"
#define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m"
#define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m"
#define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m"
diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp
index f4553d97..6a79749d 100644
--- a/src/common/net/Client.cpp
+++ b/src/common/net/Client.cpp
@@ -29,6 +29,13 @@
#include
+#ifndef XMRIG_NO_TLS
+# include
+# include
+# include "common/net/Tls.h"
+#endif
+
+
#include "common/interfaces/IClientListener.h"
#include "common/log/Log.h"
#include "common/net/Client.h"
@@ -48,6 +55,17 @@ int64_t Client::m_sequence = 1;
xmrig::Storage Client::m_storage;
+#ifdef APP_DEBUG
+static const char *states[] = {
+ "unconnected",
+ "host-lookup",
+ "connecting",
+ "connected",
+ "closing"
+};
+#endif
+
+
Client::Client(int id, const char *agent, IClientListener *listener) :
m_ipv6(false),
m_nicehash(false),
@@ -61,6 +79,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_failures(0),
m_recvBufPos(0),
m_state(UnconnectedState),
+ m_tls(nullptr),
m_expire(0),
m_jobs(0),
m_keepAlive(0),
@@ -92,6 +111,12 @@ Client::~Client()
void Client::connect()
{
+# ifndef XMRIG_NO_TLS
+ if (m_pool.isTLS()) {
+ m_tls = new Tls(this);
+ }
+# endif
+
resolve(m_pool.host());
}
@@ -122,6 +147,7 @@ void Client::deleteLater()
}
+
void Client::setPool(const Pool &pool)
{
if (!pool.isValid()) {
@@ -160,6 +186,30 @@ bool Client::disconnect()
}
+const char *Client::tlsFingerprint() const
+{
+# ifndef XMRIG_NO_TLS
+ if (isTLS() && m_pool.fingerprint() == nullptr) {
+ return m_tls->fingerprint();
+ }
+# endif
+
+ return nullptr;
+}
+
+
+const char *Client::tlsVersion() const
+{
+# ifndef XMRIG_NO_TLS
+ if (isTLS()) {
+ return m_tls->version();
+ }
+# endif
+
+ return nullptr;
+}
+
+
int64_t Client::submit(const JobResult &result)
{
using namespace rapidjson;
@@ -245,6 +295,16 @@ bool Client::isCriticalError(const char *message)
}
+bool Client::isTLS() const
+{
+# ifndef XMRIG_NO_TLS
+ return m_pool.isTLS() && m_tls;
+# else
+ return false;
+# endif
+}
+
+
bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
{
if (!params.IsObject()) {
@@ -270,17 +330,17 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code)
}
if (params.HasMember("algo")) {
- job.algorithm().parseAlgorithm(params["algo"].GetString());
+ job.setAlgorithm(params["algo"].GetString());
}
if (params.HasMember("variant")) {
const rapidjson::Value &variant = params["variant"];
if (variant.IsInt()) {
- job.algorithm().parseVariant(variant.GetInt());
+ job.setVariant(variant.GetInt());
}
else if (variant.IsString()){
- job.algorithm().parseVariant(variant.GetString());
+ job.setVariant(variant.GetString());
}
}
@@ -330,6 +390,39 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
}
+bool Client::send(BIO *bio)
+{
+# ifndef XMRIG_NO_TLS
+ uv_buf_t buf;
+ buf.len = BIO_get_mem_data(bio, &buf.base);
+
+ if (buf.len == 0) {
+ return true;
+ }
+
+ LOG_DEBUG("[%s] TLS send (%d bytes)", m_pool.url(), static_cast(buf.len));
+
+ bool result = false;
+ if (state() == ConnectedState && uv_is_writable(m_stream)) {
+ result = uv_try_write(m_stream, &buf, 1) > 0;
+
+ if (!result) {
+ close();
+ }
+ }
+ else {
+ LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state);
+ }
+
+ (void) BIO_reset(bio);
+
+ return result;
+# else
+ return false;
+# endif
+}
+
+
bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const
{
# ifdef XMRIG_PROXY_PROJECT
@@ -389,7 +482,9 @@ int64_t Client::send(const rapidjson::Document &doc)
doc.Accept(writer);
const size_t size = buffer.GetSize();
- if (size > (sizeof(m_buf) - 2)) {
+ if (size > (sizeof(m_sendBuf) - 2)) {
+ LOG_ERR("[%s] send failed: \"send buffer overflow: %zu > %zu\"", m_pool.url(), size, (sizeof(m_sendBuf) - 2));
+ close();
return -1;
}
@@ -404,16 +499,27 @@ int64_t Client::send(const rapidjson::Document &doc)
int64_t Client::send(size_t size)
{
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf);
- if (state() != ConnectedState || !uv_is_writable(m_stream)) {
- LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state);
- return -1;
+
+# ifndef XMRIG_NO_TLS
+ if (isTLS()) {
+ if (!m_tls->send(m_sendBuf, size)) {
+ return -1;
+ }
}
+ else
+# endif
+ {
+ if (state() != ConnectedState || !uv_is_writable(m_stream)) {
+ LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state);
+ return -1;
+ }
- uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
+ uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
- if (uv_try_write(m_stream, &buf, 1) < 0) {
- close();
- return -1;
+ if (uv_try_write(m_stream, &buf, 1) < 0) {
+ close();
+ return -1;
+ }
}
m_expire = uv_now(uv_default_loop()) + kResponseTimeout;
@@ -463,6 +569,22 @@ void Client::connect(sockaddr *addr)
}
+void Client::handshake()
+{
+# ifndef XMRIG_NO_TLS
+ if (isTLS()) {
+ m_expire = uv_now(uv_default_loop()) + kResponseTimeout;
+
+ m_tls->handshake();
+ }
+ else
+# endif
+ {
+ login();
+ }
+}
+
+
void Client::login()
{
using namespace rapidjson;
@@ -511,6 +633,13 @@ void Client::onClose()
m_socket = nullptr;
setState(UnconnectedState);
+# ifndef XMRIG_NO_TLS
+ if (m_tls) {
+ delete m_tls;
+ m_tls = nullptr;
+ }
+# endif
+
reconnect();
}
@@ -665,6 +794,35 @@ void Client::ping()
}
+void Client::read()
+{
+ char* end;
+ char* start = m_recvBuf.base;
+ size_t remaining = m_recvBufPos;
+
+ while ((end = static_cast(memchr(start, '\n', remaining))) != nullptr) {
+ end++;
+ size_t len = end - start;
+ parse(start, len);
+
+ remaining -= len;
+ start = end;
+ }
+
+ if (remaining == 0) {
+ m_recvBufPos = 0;
+ return;
+ }
+
+ if (start == m_recvBuf.base) {
+ return;
+ }
+
+ memcpy(m_recvBuf.base, start, remaining);
+ m_recvBufPos = remaining;
+}
+
+
void Client::reconnect()
{
if (!m_listener) {
@@ -689,7 +847,7 @@ void Client::reconnect()
void Client::setState(SocketState state)
{
- LOG_DEBUG("[%s] state: %d", m_pool.url(), state);
+ LOG_DEBUG("[%s] state: \"%s\"", m_pool.url(), states[state]);
if (m_state == state) {
return;
@@ -757,7 +915,7 @@ void Client::onConnect(uv_connect_t *req, int status)
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
delete req;
- client->login();
+ client->handshake();
}
@@ -789,30 +947,18 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
client->m_recvBufPos += nread;
- char* end;
- char* start = client->m_recvBuf.base;
- size_t remaining = client->m_recvBufPos;
+# ifndef XMRIG_NO_TLS
+ if (client->isTLS()) {
+ LOG_DEBUG("[%s] TLS received (%d bytes)", client->m_pool.url(), static_cast(nread));
- 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_tls->read(client->m_recvBuf.base, client->m_recvBufPos);
client->m_recvBufPos = 0;
- return;
}
-
- if (start == client->m_recvBuf.base) {
- return;
+ else
+# endif
+ {
+ client->read();
}
-
- memcpy(client->m_recvBuf.base, start, remaining);
- client->m_recvBufPos = remaining;
}
diff --git a/src/common/net/Client.h b/src/common/net/Client.h
index 4be8badb..d6418338 100644
--- a/src/common/net/Client.h
+++ b/src/common/net/Client.h
@@ -21,8 +21,8 @@
* along with this program. If not, see .
*/
-#ifndef __CLIENT_H__
-#define __CLIENT_H__
+#ifndef XMRIG_CLIENT_H
+#define XMRIG_CLIENT_H
#include