This commit is contained in:
robsen33 2018-10-09 00:48:14 +00:00 committed by GitHub
commit 9abc698e4e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
129 changed files with 6391 additions and 5472 deletions

View file

@ -1,167 +1,213 @@
# v2.6.0-beta3 # v2.8.1
- [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.** - [#768](https://github.com/xmrig/xmrig/issues/768) Fixed build with Visual Studio 2015.
- [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes. - [#769](https://github.com/xmrig/xmrig/issues/769) Fixed regression, some ANSI escape sequences was in log with disabled colors.
- [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization. - [#777](https://github.com/xmrig/xmrig/issues/777) Better report about pool connection issues.
- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option. - Simplified checks for ASM auto detection, only AES support necessary.
- Added missing options to `--help` output.
# v2.6.0-beta2
- Improved performance for `cryptonight v7` especially in double hash mode. # v2.8.0
- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems. - **[#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 short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. - Added global and per thread option `"asm"` and and command line equivalent.
- Fixed regressions (v2.6.0-beta1 affected) - **[#758](https://github.com/xmrig/xmrig/issues/758) Added SSL/TLS support for secure connections to pools.**
- [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. - Added per pool options `"tls"` and `"tls-fingerprint"` and command line equivalents.
- [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. - [#767](https://github.com/xmrig/xmrig/issues/767) Added config autosave feature, same with GPU miners.
- Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash. - [#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.0-beta1
- [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** # v2.6.4
- HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. - [#700](https://github.com/xmrig/xmrig/issues/700) `cryptonight-lite/ipbc` replaced to `cryptonight-heavy/tube` for **Bittube (TUBE)**.
- Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. - Added `cryptonight/rto` (cryptonight variant 1 with IPBC/TUBE mod) variant for **Arto (RTO)** coin.
- Added API endpoint `PUT /1/config` to update current config. - Added `cryptonight/xao` (original cryptonight with bigger iteration count) variant for **Alloy (XAO)** coin.
- Added API endpoint `GET /1/config` to get current active config. - Better variant detection for **nicehash.com** and **minergate.com**.
- Added API endpoint `GET /1/threads` to get current active threads configuration. - [#692](https://github.com/xmrig/xmrig/issues/692) Added support for specify both algorithm and variant via single `algo` option.
- API endpoint `GET /` now deprecated, use `GET /1/summary` instead.
- Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. # v2.6.3
- Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. - **Added support for new cryptonight-heavy variant xhv** (`cn-heavy/xhv`) for upcoming Haven Protocol fork.
- **Added support for new cryptonight variant msr** (`cn/msr`) also known as `cryptonight-fast` for upcoming Masari fork.
# v2.5.3 - Added new detailed hashrate report.
- Fixed critical bug, in some cases miner was can't recovery connection and switch to failover pool, version 2.5.2 affected. If you use v2.6.0-beta3 this issue doesn't concern you. - [#446](https://github.com/xmrig/xmrig/issues/446) Likely fixed SIGBUS error on 32 bit ARM CPUs.
- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 support disabled for internal HTTP API. - [#551](https://github.com/xmrig/xmrig/issues/551) Fixed `cn-heavy` algorithm on ARMv8.
- Added workaround for nicehash.com if you use `cryptonightv7.<region>.nicehash.com` option `variant=1` will be set automatically. - [#614](https://github.com/xmrig/xmrig/issues/614) Fixed display issue with huge pages percentage when colors disabled.
- [#615](https://github.com/xmrig/xmrig/issues/615) Fixed build without libcpuid.
# v2.5.2 - [#629](https://github.com/xmrig/xmrig/pull/629) Fixed file logging with non-seekable files.
- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. - [#672](https://github.com/xmrig/xmrig/pull/672) Reverted back `cryptonight-light` and exit if no valid algorithm specified.
# v2.5.1 # v2.6.2
- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35. - [#607](https://github.com/xmrig/xmrig/issues/607) Fixed donation bug.
- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced. - [#610](https://github.com/xmrig/xmrig/issues/610) Fixed ARM build.
- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**.
# v2.6.1
# v2.5.0 - [#168](https://github.com/xmrig/xmrig-proxy/issues/168) Added support for [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/blob/dev/doc/STRATUM_EXT.md#1-mining-algorithm-negotiation).
- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** - Added IPBC coin support, base algorithm `cn-lite` variant `ipbc`.
- Added full IPv6 support. - [#581](https://github.com/xmrig/xmrig/issues/581) Added support for upcoming Stellite (XTL) fork, base algorithm `cn` variant `xtl`, variant can set now, no need do it after fork.
- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. - Added support for **rig-id** stratum protocol extensions, compatible with xmr-stak.
- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. - Changed behavior for option `variant=-1` for `cryptonight`, now variant is `1` by default, if you mine old coins need change `variant` to `0`.
- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection. - A lot of small fixes and better unification with proxy code.
# v2.4.5 # v2.6.0-beta3
- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue). - [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.**
- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`. - [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes.
- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection. - [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization.
- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option.
# v2.4.4
- Added libmicrohttpd version to --version output. # v2.6.0-beta2
- Fixed bug in singal handler, in some cases miner wasn't shutdown properly. - Improved performance for `cryptonight v7` especially in double hash mode.
- Fixed recent MSVC 2017 version detection. - [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems.
- [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions. - Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`.
- Fixed regressions (v2.6.0-beta1 affected)
# v2.4.3 - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken.
- [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff). - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken.
- [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues. - Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash.
- [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading.
- [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout. # v2.6.0-beta1
- [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.**
# v2.4.2 - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization.
- [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur). - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested.
- [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com. - Added API endpoint `PUT /1/config` to update current config.
- Added API endpoint `GET /1/config` to get current active config.
# v2.4.1 - Added API endpoint `GET /1/threads` to get current active threads configuration.
- [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum. - API endpoint `GET /` now deprecated, use `GET /1/summary` instead.
- Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API.
# v2.4.0 - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified.
- Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API).
- Added comments support in config file. # v2.5.3
- libjansson replaced to rapidjson. - Fixed critical bug, in some cases miner was can't recovery connection and switch to failover pool, version 2.5.2 affected. If you use v2.6.0-beta3 this issue doesn't concern you.
- [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com. - [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 support disabled for internal HTTP API.
- [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection. - Added workaround for nicehash.com if you use `cryptonightv7.<region>.nicehash.com` option `variant=1` will be set automatically.
- [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option.
- [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support. # v2.5.2
- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect.
# v2.3.1
- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console. # v2.5.1
- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35.
# v2.3.0 - [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced.
- Added `--cpu-priority` option (0 idle, 2 normal to 5 highest). - [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**.
- Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`.
- Added `--no-huge-pages` option, to disable huge pages support. # v2.5.0
- [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool. - [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.**
- Force reconnect if pool block miner IP address. helps switch to backup pool. - Added full IPv6 support.
- Fixed: failed open default config file if path contains non English characters. - Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option.
- Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0. - [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly.
- Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds. - [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection.
# v2.2.1 # v2.4.5
- Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X. - [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue).
- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`.
# v2.2.0 - [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection.
- [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config.
- Improved colors support on Windows, now used uv_tty, legacy code removed. # v2.4.4
- QuickEdit Mode now disabled on Windows. - Added libmicrohttpd version to --version output.
- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume. - Fixed bug in singal handler, in some cases miner wasn't shutdown properly.
- Fixed autoconf mode for AMD FX CPUs. - Fixed recent MSVC 2017 version detection.
- [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions.
# v2.1.0
- [#40](https://github.com/xmrig/xmrig/issues/40) # v2.4.3
Improved miner shutdown, fixed crash on exit for Linux and OS X. - [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff).
- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`. - [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues.
- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one. - [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading.
- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon. - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout.
# v2.0.2 # v2.4.2
- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates. - [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur).
- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0. - [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com.
# v2.0.1 # v2.4.1
- [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems. - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum.
# v2.0.0 # v2.4.0
- Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API).
- [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. - Added comments support in config file.
- [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. - libjansson replaced to rapidjson.
- [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com.
- [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection.
- Fixed Windows XP support. - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option.
- Fixed regression, option `--no-color` was not fully disable colored output. - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support.
- Show resolved pool IP address in miner output.
# v2.3.1
# v1.0.1 - [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console.
- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected.
# v2.3.0
# v1.0.0 - Added `--cpu-priority` option (0 idle, 2 normal to 5 highest).
- Miner complete rewritten in C++ with libuv. - Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`.
- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. - Added `--no-huge-pages` option, to disable huge pages support.
- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). - [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool.
- Added new option `--print-time=N`, print hashrate report every N seconds. - Force reconnect if pool block miner IP address. helps switch to backup pool.
- New hashrate reports, by default every 60 secons. - Fixed: failed open default config file if path contains non English characters.
- Added Microsoft Visual C++ 2015 and 2017 support. - Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0.
- Removed dependency on libcurl. - Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds.
- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch.
# v2.2.1
# v0.8.2 - Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X.
- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture).
# v2.2.0
# v0.8.2 - [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config.
- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). - Improved colors support on Windows, now used uv_tty, legacy code removed.
- Fixed gcc 7.1 support. - QuickEdit Mode now disabled on Windows.
- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume.
# v0.8.1 - Fixed autoconf mode for AMD FX CPUs.
- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`.
# v2.1.0
# v0.8.0 - [#40](https://github.com/xmrig/xmrig/issues/40)
- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`. Improved miner shutdown, fixed crash on exit for Linux and OS X.
- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU. - Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`.
- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`. - [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one.
- Added `--max-cpu-usage` option for auto CPU configuration mode. - Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon.
- Added `--safe` option for adjust threads and algorithm variations to current CPU.
- No more manual steps to enable huge pages on Windows. XMRig will do it automatically. # v2.0.2
- Removed BMI2 algorithm variation. - Better deal with possible duplicate jobs from pool, show warning and ignore duplicates.
- Removed default pool URL. - For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0.
# v0.6.0 # v2.0.1
- Added automatic cryptonight self test. - [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems.
- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI.
- Added 32 bit builds. # v2.0.0
- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations). - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3`
- [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file.
# v0.5.0 - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only.
- Initial public release. - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency.
- [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads.
- Fixed Windows XP support.
- Fixed regression, option `--no-color` was not fully disable colored output.
- Show resolved pool IP address in miner output.
# v1.0.1
- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected.
# v1.0.0
- Miner complete rewritten in C++ with libuv.
- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions.
- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new).
- Added new option `--print-time=N`, print hashrate report every N seconds.
- New hashrate reports, by default every 60 secons.
- Added Microsoft Visual C++ 2015 and 2017 support.
- Removed dependency on libcurl.
- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch.
# v0.8.2
- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture).
# v0.8.2
- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture).
- Fixed gcc 7.1 support.
# v0.8.1
- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`.
# v0.8.0
- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`.
- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU.
- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`.
- Added `--max-cpu-usage` option for auto CPU configuration mode.
- Added `--safe` option for adjust threads and algorithm variations to current CPU.
- No more manual steps to enable huge pages on Windows. XMRig will do it automatically.
- Removed BMI2 algorithm variation.
- Removed default pool URL.
# v0.6.0
- Added automatic cryptonight self test.
- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI.
- Added 32 bit builds.
- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations).
# v0.5.0
- Initial public release.

View file

@ -1,12 +1,14 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
project(xmrig) project(xmrig)
option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_LIBCPUID "Use Libcpuid" ON)
option(WITH_AEON "CryptoNight-Lite support" ON) option(WITH_AEON "CryptoNight-Lite support" ON)
option(WITH_SUMO "CryptoNight-Heavy support" ON) option(WITH_SUMO "CryptoNight-Heavy support" ON)
option(WITH_IPBC "CryptoNight-IPBC support" ON) option(WITH_HTTPD "HTTP REST API" ON)
option(WITH_HTTPD "HTTP REST API" ON) option(WITH_DEBUG_LOG "Enable debug log output" OFF)
option(BUILD_STATIC "Build static binary" 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 (CheckIncludeFile)
include (cmake/cpu.cmake) include (cmake/cpu.cmake)
@ -19,8 +21,20 @@ set(HEADERS
src/common/config/ConfigLoader.h src/common/config/ConfigLoader.h
src/common/config/ConfigWatcher.h src/common/config/ConfigWatcher.h
src/common/Console.h src/common/Console.h
src/common/cpu/Cpu.h
src/common/crypto/Algorithm.h src/common/crypto/Algorithm.h
src/common/crypto/keccak.h src/common/crypto/keccak.h
src/common/interfaces/IClientListener.h
src/common/interfaces/IConfig.h
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/ConsoleLog.h
src/common/log/FileLog.h src/common/log/FileLog.h
src/common/log/Log.h src/common/log/Log.h
@ -36,21 +50,10 @@ set(HEADERS
src/common/utils/c_str.h src/common/utils/c_str.h
src/common/utils/mm_malloc.h src/common/utils/mm_malloc.h
src/common/xmrig.h src/common/xmrig.h
src/core/Config.cpp
src/core/ConfigLoader_platform.h src/core/ConfigLoader_platform.h
src/core/Controller.h src/core/Controller.h
src/Cpu.h
src/interfaces/IClientListener.h
src/interfaces/IConfig.h
src/interfaces/IConfigCreator.h
src/interfaces/IConsoleListener.h
src/interfaces/IControllerListener.h
src/interfaces/IJobResultListener.h src/interfaces/IJobResultListener.h
src/interfaces/ILogBackend.h
src/interfaces/IStrategy.h
src/interfaces/IStrategyListener.h
src/interfaces/IThread.h src/interfaces/IThread.h
src/interfaces/IWatcherListener.h
src/interfaces/IWorker.h src/interfaces/IWorker.h
src/Mem.h src/Mem.h
src/net/JobResult.h src/net/JobResult.h
@ -96,6 +99,7 @@ set(SOURCES
src/common/Console.cpp src/common/Console.cpp
src/common/crypto/Algorithm.cpp src/common/crypto/Algorithm.cpp
src/common/crypto/keccak.cpp src/common/crypto/keccak.cpp
src/common/log/BasicLog.cpp
src/common/log/ConsoleLog.cpp src/common/log/ConsoleLog.cpp
src/common/log/FileLog.cpp src/common/log/FileLog.cpp
src/common/log/Log.cpp src/common/log/Log.cpp
@ -133,7 +137,6 @@ if (WIN32)
res/app.rc res/app.rc
src/App_win.cpp src/App_win.cpp
src/common/Platform_win.cpp src/common/Platform_win.cpp
src/Cpu_win.cpp
src/Mem_win.cpp src/Mem_win.cpp
) )
@ -143,18 +146,16 @@ elseif (APPLE)
set(SOURCES_OS set(SOURCES_OS
src/App_unix.cpp src/App_unix.cpp
src/common/Platform_mac.cpp src/common/Platform_mac.cpp
src/Cpu_mac.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
else() else()
set(SOURCES_OS set(SOURCES_OS
src/App_unix.cpp src/App_unix.cpp
src/common/Platform_unix.cpp src/common/Platform_unix.cpp
src/Cpu_unix.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
set(EXTRA_LIBS pthread rt) set(EXTRA_LIBS pthread rt dl)
endif() endif()
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD) if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
@ -170,7 +171,6 @@ endif()
add_definitions(/D__STDC_FORMAT_MACROS) add_definitions(/D__STDC_FORMAT_MACROS)
add_definitions(/DUNICODE) add_definitions(/DUNICODE)
#add_definitions(/DAPP_DEBUG)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
@ -183,17 +183,21 @@ if (WITH_LIBCPUID)
include_directories(src/3rdparty/libcpuid) include_directories(src/3rdparty/libcpuid)
set(CPUID_LIB cpuid) 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() else()
add_definitions(/DXMRIG_NO_LIBCPUID) add_definitions(/DXMRIG_NO_LIBCPUID)
set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp)
if (XMRIG_ARM) if (XMRIG_ARM)
set(SOURCES_CPUID src/Cpu_arm.cpp) set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp)
else() else()
set(SOURCES_CPUID src/Cpu_stub.cpp) set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp)
endif() endif()
endif() endif()
include(cmake/OpenSSL.cmake)
include(cmake/asm.cmake)
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H) CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H) if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_SYSLOG_H) add_definitions(/DHAVE_SYSLOG_H)
@ -233,6 +237,7 @@ if (WITH_HTTPD)
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support") message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
endif() endif()
else() else()
set(HTTPD_SOURCES "")
set(MHD_LIBRARY "") set(MHD_LIBRARY "")
add_definitions(/DXMRIG_NO_HTTPD) add_definitions(/DXMRIG_NO_HTTPD)
add_definitions(/DXMRIG_NO_API) add_definitions(/DXMRIG_NO_API)
@ -246,5 +251,9 @@ if (BUILD_STATIC)
set(CMAKE_EXE_LINKER_FLAGS " -static") set(CMAKE_EXE_LINKER_FLAGS " -static")
endif() endif()
add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES}) if (WITH_DEBUG_LOG)
target_link_libraries(xmrig ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB}) 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})

View file

@ -1,6 +1,6 @@
# XMRig # XMRig
:warning: **You must update miners to version 2.5 before April 6 due [Monero PoW change](https://getmonero.org/2018/02/11/PoW-change-and-key-reuse.html).** :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+](https://github.com/xmrig/xmrig/releases/tag/v2.8.1)** :warning:
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases) [![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) [![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
@ -52,14 +52,21 @@ Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or shar
### Options ### Options
``` ```
-a, --algo=ALGO cryptonight (default) or cryptonight-lite -a, --algo=ALGO specify the algorithm to use
cryptonight
cryptonight-lite
cryptonight-heavy
-o, --url=URL URL of mining server -o, --url=URL URL of mining server
-O, --userpass=U:P username:password pair for mining server -O, --userpass=U:P username:password pair for mining server
-u, --user=USERNAME username for mining server -u, --user=USERNAME username for mining server
-p, --pass=PASSWORD password for mining server -p, --pass=PASSWORD password for mining server
--rig-id=ID rig identifier for pool-side statistics (needs pool support)
-t, --threads=N number of miner threads -t, --threads=N number of miner threads
-v, --av=N algorithm variation, 0 auto select -v, --av=N algorithm variation, 0 auto select
-k, --keepalive send keepalived for prevent timeout (need pool support) -k, --keepalive send keepalived packet for prevent timeout (needs pool support)
--nicehash enable nicehash.com support
--tls enable SSL/TLS support (needs pool support)
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning
-r, --retries=N number of times to retry before switch to backup server (default: 5) -r, --retries=N number of times to retry before switch to backup server (default: 5)
-R, --retry-pause=N time to pause between retries (default: 5) -R, --retry-pause=N time to pause between retries (default: 5)
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1 --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
@ -75,23 +82,38 @@ Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or shar
-S, --syslog use system log for output messages -S, --syslog use system log for output messages
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75) --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)
--safe safe adjust threads and av settings for current CPU --safe safe adjust threads and av settings for current CPU
--nicehash enable nicehash/xmrig-proxy support --asm=ASM ASM code for cn/2, possible values: auto, none, intel, ryzen.
--print-time=N print hashrate report every N seconds --print-time=N print hashrate report every N seconds
--api-port=N port for the miner API --api-port=N port for the miner API
--api-access-token=T access token for API --api-access-token=T access token for API
--api-worker-id=ID custom worker-id for API --api-worker-id=ID custom worker-id for API
--api-id=ID custom instance ID for API
--api-ipv6 enable IPv6 support for API
--api-no-restricted enable full remote access (only if API token set)
--dry-run test configuration and exit
-h, --help display this help and exit -h, --help display this help and exit
-V, --version output version information and exit -V, --version output version information and exit
``` ```
Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options. Also you can use configuration via config file, default name **config.json**. Some options available only via config file: [`autosave`](https://github.com/xmrig/xmrig/issues/767), [`hw-aes`](https://github.com/xmrig/xmrig/issues/563). `watch` option currently not implemented in miners only in proxy.
## Algorithm variations ## Algorithm variations
Since version 0.8.0.
* `--av=1` For CPUs with hardware AES. - `av` option used for automatic and simple threads mode (when you specify only threads count).
* `--av=2` Lower power mode (double hash) of `1`. - For [advanced threads mode](https://github.com/xmrig/xmrig/issues/563) each thread configured individually and `av` option not used.
* `--av=3` Software AES implementation.
* `--av=4` Lower power mode (double hash) of `3`. | 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 ## Common Issues
### HUGE PAGES unavailable ### HUGE PAGES unavailable
@ -100,8 +122,7 @@ Since version 0.8.0.
## Other information ## Other information
* No HTTP support, only stratum protocol support. * No HTTP support, only stratum protocol support.
* No TLS support. * Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via option `donate-level`.
* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
### CPU mining performance ### CPU mining performance
@ -124,12 +145,17 @@ Please note performance is highly dependent on system load. The numbers above ar
## Release checksums ## Release checksums
### SHA-256 ### SHA-256
``` ```
6b32fefb356b27caa2180be17755d09639f0654096a1a0c61e8f10f4f2ac1626 xmrig-2.6.0-beta3-xenial-amd64.tar.gz/xmrig-2.6.0-beta3/xmrig fd909cef75c65c1ee8facd78e968c359e4ac4d2f0b2aaef8c6d3e0138979d0ea xmrig-2.8.1-xenial-amd64.tar.gz/xmrig-2.8.1/xmrig
c8b40f4d7aac9d0cc7c3d02cadeac91b0bdb034aae2fb6b415d503272eabb987 xmrig-2.6.0-beta3-gcc-win32.zip/xmrig.exe e4987eaec57c1784c423e03978e22262adf070ab3ad7b2a6ce8d0d0626db4cbd xmrig-2.8.1-xenial-amd64.tar.gz/xmrig-2.8.1/xmrig-notls
32cf7958f97a23296186e38a4addb9cf234adcbd9c7914b15e4209a87fe272e7 xmrig-2.6.0-beta3-gcc-win64.zip/xmrig.exe 4ebf6053513c8b72b46f54481f33367aae6356fc5f271c9236d708a34cd16e2a xmrig-2.8.1-gcc-win32.zip/xmrig.exe
4f176ee4c4be52701edc0d573cf9647c4aacbb4ff14975b80b98e6fe63068542 xmrig-2.6.0-beta3-msvc-win64.zip/xmrig.exe f4ce5b76a611f6768c9a035eae1e49f61666f3e5370b54bd447ecc3b0098efcb xmrig-2.8.1-gcc-win32.zip/xmrig-notls.exe
39259979b4228899c0ef985bcfc283e169afd44323eedb0341144dbc0c0f30e9 xmrig-2.8.1-gcc-win64.zip/xmrig.exe
68af0f11b29b9b67414d0b661446baa0ad6020598c04c5d0cf24797167753117 xmrig-2.8.1-gcc-win64.zip/xmrig-notls.exe
5d8b94157ebb4a7729f0eb8622945c266b756c994c60f91514b329edeb287867 xmrig-2.8.1-msvc-win64.zip/xmrig.exe
d97c691d6044f916b9253820832f1a08402bb63aa75fb146ea8c31f51cebe974 xmrig-2.8.1-msvc-win64.zip/xmrig-notls.exe
``` ```
## Contacts ## Contacts
* support@xmrig.com * support@xmrig.com
* [reddit](https://www.reddit.com/user/XMRig/) * [reddit](https://www.reddit.com/user/XMRig/)
* [twitter](https://twitter.com/xmrig_dev)

23
cmake/OpenSSL.cmake Normal file
View file

@ -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()

33
cmake/asm.cmake Normal file
View file

@ -0,0 +1,33 @@
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)
if (MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
set(XMRIG_ASM_FILE "src/crypto/asm/cnv2_main_loop.asm")
else()
set(XMRIG_ASM_FILE "src/crypto/asm/win64/cnv2_main_loop.asm")
endif()
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/win64/cnv2_main_loop.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()

View file

@ -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 "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast") 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") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
if (XMRIG_ARMv8) if (XMRIG_ARMv8)

31
doc/ALGORITHMS.md Normal file
View file

@ -0,0 +1,31 @@
# Algorithms
XMRig uses a different way to specify algorithms, compared to other miners.
Algorithm selection splitted to 2 parts:
* Global base algorithm per miner or proxy instance, `algo` option. Possible values: `cryptonight`, `cryptonight-lite`, `cryptonight-heavy`.
* Algorithm variant specified separately for each pool, `variant` option.
* [Full table for supported algorithm and variants.](https://github.com/xmrig/xmrig-proxy/blob/master/doc/STRATUM_EXT.md#14-algorithm-names-and-variants)
#### Example
```json
{
"algo": "cryptonight",
...
"pools": [
{
"url": "...",
"variant": 1,
...
}
],
...
}
```
## Mining algorithm negotiation
If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) miner will choice proper variant automaticaly and if you choice wrong base algorithm you will see error message.
Pools with mining algorithm negotiation support.
* [www.hashvault.pro](https://www.hashvault.pro/)

View file

@ -4,8 +4,8 @@
IDI_ICON1 ICON DISCARDABLE "app.ico" IDI_ICON1 ICON DISCARDABLE "app.ico"
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0
PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG FILEFLAGS VS_FF_DEBUG

File diff suppressed because it is too large Load diff

View file

@ -1,53 +1,71 @@
/* /*
* Copyright 2008 Veselin Georgiev, * Copyright 2008 Veselin Georgiev,
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail) * anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __ASM_BITS_H__ #ifndef __ASM_BITS_H__
#define __ASM_BITS_H__ #define __ASM_BITS_H__
#include "libcpuid.h" #include "libcpuid.h"
/* Determine Compiler: */ /* Determine Compiler: */
#if defined(_MSC_VER) #if defined(_MSC_VER)
# define COMPILER_MICROSOFT #if !defined(COMPILER_MICROSOFT)
#elif defined(__GNUC__) # define COMPILER_MICROSOFT
# define COMPILER_GCC #endif
#endif #elif defined(__GNUC__)
#if !defined(COMPILER_GCC)
/* Determine Platform */ # define COMPILER_GCC
#if defined(__x86_64__) || defined(_M_AMD64) #endif
# define PLATFORM_X64 #elif defined(__clang__)
#elif defined(__i386__) || defined(_M_IX86) #if !defined(COMPILER_CLANG)
# define PLATFORM_X86 # define COMPILER_CLANG
#endif #endif
#endif
/* Under Windows/AMD64 with MSVC, inline assembly isn't supported */
#if (defined(COMPILER_GCC) && defined(PLATFORM_X64)) || defined(PLATFORM_X86) /* Determine Platform */
# define INLINE_ASM_SUPPORTED #if defined(__x86_64__) || defined(_M_AMD64)
#endif #if !defined(PLATFORM_X64)
# define PLATFORM_X64
int cpuid_exists_by_eflags(void); #endif
void exec_cpuid(uint32_t *regs); #elif defined(__i386__) || defined(_M_IX86)
void busy_sse_loop(int cycles); #if !defined(PLATFORM_X86)
# define PLATFORM_X86
#endif /* __ASM_BITS_H__ */ #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__ */

View file

@ -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) static cpu_vendor_t cpuid_vendor_identify(const uint32_t *raw_vendor, char *vendor_str)
{ {
int i; int i;
cpu_vendor_t vendor = VENDOR_UNKNOWN; cpu_vendor_t vendor = VENDOR_UNKNOWN;
const struct { cpu_vendor_t vendor; char match[16]; } const struct { cpu_vendor_t vendor; char match[16]; }
matchtable[NUM_CPU_VENDORS] = { matchtable[NUM_CPU_VENDORS] = {
/* source: http://www.sandpile.org/ia32/cpuid.htm */ /* source: http://www.sandpile.org/ia32/cpuid.htm */
{ VENDOR_INTEL , "GenuineIntel" }, { VENDOR_INTEL , "GenuineIntel" },
{ VENDOR_AMD , "AuthenticAMD" }, { VENDOR_AMD , "AuthenticAMD" },
{ VENDOR_CYRIX , "CyrixInstead" }, { VENDOR_CYRIX , "CyrixInstead" },
{ VENDOR_NEXGEN , "NexGenDriven" }, { VENDOR_NEXGEN , "NexGenDriven" },
{ VENDOR_TRANSMETA , "GenuineTMx86" }, { VENDOR_TRANSMETA , "GenuineTMx86" },
{ VENDOR_UMC , "UMC UMC UMC " }, { VENDOR_UMC , "UMC UMC UMC " },
{ VENDOR_CENTAUR , "CentaurHauls" }, { VENDOR_CENTAUR , "CentaurHauls" },
{ VENDOR_RISE , "RiseRiseRise" }, { VENDOR_RISE , "RiseRiseRise" },
{ VENDOR_SIS , "SiS SiS SiS " }, { VENDOR_SIS , "SiS SiS SiS " },
{ VENDOR_NSC , "Geode by NSC" }, { VENDOR_NSC , "Geode by NSC" },
}; };
memcpy(vendor_str + 0, &raw_vendor[1], 4); memcpy(vendor_str + 0, &raw_vendor[1], 4);
memcpy(vendor_str + 4, &raw_vendor[3], 4); memcpy(vendor_str + 4, &raw_vendor[3], 4);
memcpy(vendor_str + 8, &raw_vendor[2], 4); memcpy(vendor_str + 8, &raw_vendor[2], 4);
vendor_str[12] = 0; vendor_str[12] = 0;
/* Determine vendor: */ /* Determine vendor: */
for (i = 0; i < NUM_CPU_VENDORS; i++) for (i = 0; i < NUM_CPU_VENDORS; i++)
if (!strcmp(vendor_str, matchtable[i].match)) { if (!strcmp(vendor_str, matchtable[i].match)) {
vendor = matchtable[i].vendor; vendor = matchtable[i].vendor;
break; break;
} }
return vendor; return vendor;
} }
static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{ {
int i, j, basic, xmodel, xfamily, ext; int i, j, basic, xmodel, xfamily, ext;
char brandstr[64] = {0}; 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) if (data->vendor == VENDOR_UNKNOWN)
return set_error(ERR_CPU_UNKN); return set_error(ERR_CPU_UNKN);

View file

@ -60,7 +60,7 @@
*/ */
/** @mainpage A simple libcpuid introduction /** @mainpage A simple libcpuid introduction
* *
* LibCPUID provides CPU identification and access to the CPUID and RDTSC * LibCPUID provides CPU identification and access to the CPUID and RDTSC
* instructions on the x86. * instructions on the x86.
* <p> * <p>
@ -82,6 +82,7 @@
*/ */
/** @defgroup libcpuid LibCPUID /** @defgroup libcpuid LibCPUID
* @brief LibCPUID provides CPU identification
@{ */ @{ */
/* Include some integer type specifications: */ /* Include some integer type specifications: */
@ -535,23 +536,23 @@ typedef enum {
* @brief Describes common library error codes * @brief Describes common library error codes
*/ */
typedef enum { typedef enum {
ERR_OK = 0, /*!< "No error" */ ERR_OK = 0, /*!< No error */
ERR_NO_CPUID = -1, /*!< "CPUID instruction is not supported" */ ERR_NO_CPUID = -1, /*!< CPUID instruction is not supported */
ERR_NO_RDTSC = -2, /*!< "RDTSC instruction is not supported" */ ERR_NO_RDTSC = -2, /*!< RDTSC instruction is not supported */
ERR_NO_MEM = -3, /*!< "Memory allocation failed" */ ERR_NO_MEM = -3, /*!< Memory allocation failed */
ERR_OPEN = -4, /*!< "File open operation failed" */ ERR_OPEN = -4, /*!< File open operation failed */
ERR_BADFMT = -5, /*!< "Bad file format" */ ERR_BADFMT = -5, /*!< Bad file format */
ERR_NOT_IMP = -6, /*!< "Not implemented" */ ERR_NOT_IMP = -6, /*!< Not implemented */
ERR_CPU_UNKN = -7, /*!< "Unsupported processor" */ ERR_CPU_UNKN = -7, /*!< Unsupported processor */
ERR_NO_RDMSR = -8, /*!< "RDMSR instruction is not supported" */ ERR_NO_RDMSR = -8, /*!< RDMSR instruction is not supported */
ERR_NO_DRIVER= -9, /*!< "RDMSR driver error (generic)" */ ERR_NO_DRIVER= -9, /*!< RDMSR driver error (generic) */
ERR_NO_PERMS = -10, /*!< "No permissions to install RDMSR driver" */ ERR_NO_PERMS = -10, /*!< No permissions to install RDMSR driver */
ERR_EXTRACT = -11, /*!< "Cannot extract RDMSR driver (read only media?)" */ ERR_EXTRACT = -11, /*!< Cannot extract RDMSR driver (read only media?) */
ERR_HANDLE = -12, /*!< "Bad handle" */ ERR_HANDLE = -12, /*!< Bad handle */
ERR_INVMSR = -13, /*!< "Invalid MSR" */ ERR_INVMSR = -13, /*!< Invalid MSR */
ERR_INVCNB = -14, /*!< "Invalid core number" */ ERR_INVCNB = -14, /*!< Invalid core number */
ERR_HANDLE_R = -15, /*!< "Error on handle read" */ ERR_HANDLE_R = -15, /*!< Error on handle read */
ERR_INVRANGE = -16, /*!< "Invalid given range" */ ERR_INVRANGE = -16, /*!< Invalid given range */
} cpu_error_t; } 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); const char* cpuid_lib_version(void);
#ifdef __cplusplus #ifdef __cplusplus
}; /* extern "C" */ } /* extern "C" */
#endif #endif

View file

@ -75,8 +75,9 @@ enum _intel_bits_t {
_3 = LBIT( 14 ), _3 = LBIT( 14 ),
_5 = LBIT( 15 ), _5 = LBIT( 15 ),
_7 = LBIT( 16 ), _7 = LBIT( 16 ),
XEON_ = LBIT( 17 ), _9 = LBIT( 17 ),
ATOM_ = LBIT( 18 ), XEON_ = LBIT( 18 ),
ATOM_ = LBIT( 19 ),
}; };
typedef enum _intel_bits_t intel_bits_t; typedef enum _intel_bits_t intel_bits_t;

View file

@ -32,6 +32,32 @@
#ifndef __LIBCPUID_TYPES_H__ #ifndef __LIBCPUID_TYPES_H__
#define __LIBCPUID_TYPES_H__ #define __LIBCPUID_TYPES_H__
#include <stdint.h> #if !defined(_MSC_VER) || _MSC_VER >= 1600
# include <stdint.h>
#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__ */ #endif /* __LIBCPUID_TYPES_H__ */

View file

@ -49,6 +49,10 @@ enum _amd_model_codes_t {
_1400, _1400,
_1500, _1500,
_1600, _1600,
_1900,
_2400,
_2500,
_2700,
}; };
static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data) static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)

View file

@ -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; 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_; bits |= CORE_;
i--; i--;
switch (bs[i + 9]) { 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 '3': bits |= _3; break;
case '5': bits |= _5; break; case '5': bits |= _5; break;
case '7': bits |= _7; break; case '7': bits |= _7; break;
case '9': bits |= _9; break;
} }
} }
for (i = 0; i < COUNT_OF(matchtable); i++) for (i = 0; i < COUNT_OF(matchtable); i++)

View file

@ -29,11 +29,11 @@
#include "api/Api.h" #include "api/Api.h"
#include "App.h" #include "App.h"
#include "common/Console.h" #include "common/Console.h"
#include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "Mem.h" #include "Mem.h"
#include "net/Network.h" #include "net/Network.h"

View file

@ -28,7 +28,7 @@
#include <uv.h> #include <uv.h>
#include "interfaces/IConsoleListener.h" #include "common/interfaces/IConsoleListener.h"
class Console; class Console;

View file

@ -27,44 +27,41 @@
#include <uv.h> #include <uv.h>
#include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h" #include "crypto/Asm.h"
#include "Mem.h" #include "Mem.h"
#include "Summary.h" #include "Summary.h"
#include "version.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]; return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly);
# 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);
# else
buf[0] = '\0';
# endif
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s",
APP_VERSION, uv_version_string(), buf);
} }
#endif
static void print_memory(xmrig::Config *config) { static void print_memory(xmrig::Config *config) {
# ifdef _WIN32 # ifdef _WIN32
if (config->isColors()) { if (config->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s", Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable"); "HUGE PAGES", Mem::isHugepagesAvailable() ? "\x1B[1;32mavailable" : "\x1B[01;31munavailable");
} }
else { else {
Log::i()->text(" * HUGE PAGES: %s", Mem::isHugepagesAvailable() ? "available" : "unavailable"); Log::i()->text(" * %-13s%s", "HUGE PAGES", Mem::isHugepagesAvailable() ? "available" : "unavailable");
} }
# endif # endif
} }
@ -72,20 +69,23 @@ static void print_memory(xmrig::Config *config) {
static void print_cpu(xmrig::Config *config) static void print_cpu(xmrig::Config *config)
{ {
using namespace xmrig;
if (config->isColors()) { if (config->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI", Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES",
Cpu::brand(), "CPU",
Cpu::sockets(), Cpu::info()->brand(),
Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-", Cpu::info()->sockets(),
Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-"); Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-");
# ifndef XMRIG_NO_LIBCPUID # ifndef XMRIG_NO_LIBCPUID
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif # endif
} }
else { else {
Log::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", 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 # ifndef XMRIG_NO_LIBCPUID
Log::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", 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 # endif
} }
} }
@ -94,87 +94,66 @@ static void print_cpu(xmrig::Config *config)
static void print_threads(xmrig::Config *config) static void print_threads(xmrig::Config *config)
{ {
if (config->threadsMode() != xmrig::Config::Advanced) { if (config->threadsMode() != xmrig::Config::Advanced) {
char buf[32]; char buf[32] = { 0 };
if (config->affinity() != -1L) { if (config->affinity() != -1L) {
snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity()); snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity());
}
else {
buf[0] = '\0';
} }
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s")
: " * %-13s%d, %s, av=%d, %sdonate=%d%%%s",
"THREADS",
config->threadsCount(), config->threadsCount(),
config->algorithm().name(), config->algorithm().name(),
config->algoVariant(), config->algoVariant(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel(), config->donateLevel(),
buf); buf);
} }
else { else {
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%", Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%")
: " * %-13s%d, %s, %sdonate=%d%%",
"THREADS",
config->threadsCount(), config->threadsCount(),
config->algorithm().name(), config->algorithm().name(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel()); 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) Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
{ : " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
const std::vector<Pool> &pools = config->pools();
for (size_t i = 0; i < pools.size(); ++i) {
Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s" : " * POOL #%d: %s",
i + 1,
pools[i].url()
);
} }
else {
# ifdef APP_DEBUG Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
for (const Pool &pool : pools) {
pool.print();
} }
# endif # 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() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d",
config->isApiIPv6() ? "[::]" : "0.0.0.0", port);
}
#endif
static void print_commands(xmrig::Config *config) static void print_commands(xmrig::Config *config)
{ {
if (config->isColors()) { if (config->isColors()) {
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume"); Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
MAGENTA_BOLD("p") WHITE_BOLD("ause, ")
MAGENTA_BOLD("r") WHITE_BOLD("esume"));
} }
else { else {
Log::i()->text(" * COMMANDS: 'h' hashrate, 'p' pause, 'r' resume"); Log::i()->text(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume");
} }
} }
void Summary::print(xmrig::Controller *controller) void Summary::print(xmrig::Controller *controller)
{ {
print_versions(controller->config()); controller->config()->printVersions();
print_memory(controller->config()); print_memory(controller->config());
print_cpu(controller->config()); print_cpu(controller->config());
print_threads(controller->config()); print_threads(controller->config());
print_pools(controller->config()); controller->config()->printPools();
controller->config()->printAPI();
# ifndef XMRIG_NO_API
print_api(controller->config());
# endif
print_commands(controller->config()); print_commands(controller->config());
} }

View file

@ -35,14 +35,13 @@
#include "api/ApiRouter.h" #include "api/ApiRouter.h"
#include "common/api/HttpReply.h" #include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h" #include "common/api/HttpRequest.h"
#include "common/cpu/Cpu.h"
#include "common/crypto/keccak.h" #include "common/crypto/keccak.h"
#include "common/net/Job.h" #include "common/net/Job.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "interfaces/IThread.h" #include "interfaces/IThread.h"
#include "Mem.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h" #include "rapidjson/stringbuffer.h"
@ -67,7 +66,7 @@ ApiRouter::ApiRouter(xmrig::Controller *controller) :
memset(m_workerId, 0, sizeof(m_workerId)); memset(m_workerId, 0, sizeof(m_workerId));
setWorkerId(controller->config()->apiWorkerId()); 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)); 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; uv_interface_address_t *interfaces;
int count = 0; int count = 0;
@ -160,11 +164,13 @@ void ApiRouter::genId()
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) { if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
uint8_t hash[200]; uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr); 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<uint16_t>(m_controller->config()->apiPort());
uint8_t *input = new uint8_t[inSize](); uint8_t *input = new uint8_t[inSize]();
memcpy(input, interfaces[i].phys_addr, addrSize); memcpy(input, &port, sizeof(uint16_t));
memcpy(input + addrSize, APP_KIND, strlen(APP_KIND)); 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); xmrig::keccak(input, inSize, hash);
Job::toHex(hash, 8, m_id); Job::toHex(hash, 8, m_id);
@ -232,13 +238,14 @@ void ApiRouter::getIdentify(rapidjson::Document &doc) const
void ApiRouter::getMiner(rapidjson::Document &doc) const void ApiRouter::getMiner(rapidjson::Document &doc) const
{ {
using namespace xmrig;
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
rapidjson::Value cpu(rapidjson::kObjectType); rapidjson::Value cpu(rapidjson::kObjectType);
cpu.AddMember("brand", rapidjson::StringRef(Cpu::brand()), allocator); cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator);
cpu.AddMember("aes", Cpu::hasAES(), allocator); cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
cpu.AddMember("x64", Cpu::isX64(), allocator); cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
cpu.AddMember("sockets", Cpu::sockets(), allocator); cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
doc.AddMember("version", APP_VERSION, allocator); doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator); doc.AddMember("kind", APP_KIND, allocator);

View file

@ -26,7 +26,7 @@
#include "api/NetworkState.h" #include "api/NetworkState.h"
#include "interfaces/IControllerListener.h" #include "common/interfaces/IControllerListener.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@ -56,7 +56,7 @@ protected:
private: private:
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const; void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
void genId(); void genId(const char *id);
void getConnection(rapidjson::Document &doc) const; void getConnection(rapidjson::Document &doc) const;
void getHashrate(rapidjson::Document &doc) const; void getHashrate(rapidjson::Document &doc) const;
void getIdentify(rapidjson::Document &doc) const; void getIdentify(rapidjson::Document &doc) const;
@ -66,7 +66,7 @@ private:
void setWorkerId(const char *id); void setWorkerId(const char *id);
void updateWorkerId(const char *id, const char *previousId); void updateWorkerId(const char *id, const char *previousId);
char m_id[17]; char m_id[32];
char m_workerId[128]; char m_workerId[128];
NetworkState m_network; NetworkState m_network;
xmrig::Controller *m_controller; xmrig::Controller *m_controller;

View file

@ -26,6 +26,12 @@
#include <uv.h> #include <uv.h>
#ifndef XMRIG_NO_TLS
# include <openssl/ssl.h>
# include <openssl/err.h>
#endif
#include "Platform.h" #include "Platform.h"
@ -61,3 +67,23 @@ const char *Platform::defaultConfigName()
*m_defaultConfigName = '\0'; *m_defaultConfigName = '\0';
return nullptr; 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();
}
}

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __PLATFORM_H__ #ifndef XMRIG_PLATFORM_H
#define __PLATFORM_H__ #define XMRIG_PLATFORM_H
#include <stdint.h> #include <stdint.h>
@ -43,9 +43,11 @@ public:
static inline const char *userAgent() { return m_userAgent.data(); } static inline const char *userAgent() { return m_userAgent.data(); }
private: private:
static char *createUserAgent();
static char m_defaultConfigName[520]; static char m_defaultConfigName[520];
static xmrig::c_str m_userAgent; static xmrig::c_str m_userAgent;
}; };
#endif /* __PLATFORM_H__ */ #endif /* XMRIG_PLATFORM_H */

View file

@ -38,7 +38,7 @@
#endif #endif
static inline char *createUserAgent() char *Platform::createUserAgent()
{ {
const size_t max = 160; 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) void Platform::setProcessPriority(int priority)
{ {

View file

@ -29,11 +29,13 @@
#endif #endif
#include <pthread.h>
#include <sched.h> #include <sched.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <unistd.h>
#include <uv.h> #include <uv.h>
@ -50,7 +52,7 @@ typedef cpuset_t cpu_set_t;
#endif #endif
static inline char *createUserAgent() char *Platform::createUserAgent()
{ {
const size_t max = 160; const size_t max = 160;
@ -90,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::setProcessPriority(int priority)
{ {
} }
void Platform::setThreadPriority(int priority) void Platform::setThreadPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {

View file

@ -55,7 +55,7 @@ static inline OSVERSIONINFOEX winOsVersion()
} }
static inline char *createUserAgent() char *Platform::createUserAgent()
{ {
const auto osver = winOsVersion(); const auto osver = winOsVersion();
const size_t max = 160; 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) void Platform::setProcessPriority(int priority)
{ {
if (priority == -1) { if (priority == -1) {

View file

@ -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, "Content-Type", "application/json");
MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*"); 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-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); const int ret = MHD_queue_response(m_connection, status, rsp);
MHD_destroy_response(rsp); MHD_destroy_response(rsp);

View file

@ -29,20 +29,48 @@
#include <uv.h> #include <uv.h>
#ifndef XMRIG_NO_HTTPD
# include <microhttpd.h>
#endif
#ifndef XMRIG_NO_TLS
# include <openssl/opensslv.h>
#endif
#ifdef XMRIG_AMD_PROJECT
# if defined(__APPLE__)
# include <OpenCL/cl.h>
# else
# include "3rdparty/CL/cl.h"
# endif
#endif
#ifdef XMRIG_NVIDIA_PROJECT
# include "nvidia/cryptonight.h"
#endif
#include "common/config/CommonConfig.h" #include "common/config/CommonConfig.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "donate.h" #include "donate.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "version.h"
xmrig::CommonConfig::CommonConfig() : xmrig::CommonConfig::CommonConfig() :
m_algorithm(CRYPTONIGHT, VARIANT_AUTO),
m_adjusted(false), m_adjusted(false),
m_apiIPv6(false), m_apiIPv6(false),
m_apiRestricted(true), m_apiRestricted(true),
m_autoSave(true),
m_background(false), m_background(false),
m_colors(true), m_colors(true),
m_dryRun(false),
m_syslog(false), m_syslog(false),
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
@ -67,8 +95,136 @@ 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<int>(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<int>(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);
}
bool xmrig::CommonConfig::save()
{
if (m_fileName.isNull()) {
return false;
}
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName.data(), O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr);
if (fd < 0) {
return false;
}
uv_fs_req_cleanup(&req);
rapidjson::Document doc;
getJSON(doc);
FILE *fp = fdopen(fd, "w");
char buf[4096];
rapidjson::FileWriteStream os(fp, buf, sizeof(buf));
rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
doc.Accept(writer);
fflush(fp);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
return true;
} }
@ -83,13 +239,19 @@ bool xmrig::CommonConfig::finalize()
} }
if (!m_algorithm.isValid()) { if (!m_algorithm.isValid()) {
m_algorithm.setAlgo(CRYPTONIGHT); return false;
} }
for (Pool &pool : m_pools) { for (Pool &pool : m_pools) {
pool.adjust(m_algorithm.algo()); pool.adjust(m_algorithm);
if (pool.isValid() && pool.algorithm().isValid()) { if (pool.isValid() && pool.algorithm().isValid()) {
# ifdef XMRIG_NO_TLS
if (pool.isTLS()) {
continue;
}
# endif
m_activePools.push_back(std::move(pool)); m_activePools.push_back(std::move(pool));
} }
} }
@ -121,6 +283,10 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0); m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0);
break; break;
case TlsKey: /* --tls */
m_pools.back().setTLS(enable);
break;
# ifndef XMRIG_PROXY_PROJECT # ifndef XMRIG_PROXY_PROJECT
case NicehashKey: /* --nicehash */ case NicehashKey: /* --nicehash */
m_pools.back().setNicehash(enable); m_pools.back().setNicehash(enable);
@ -137,9 +303,19 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable)
case ApiIPv6Key: /* ipv6 */ case ApiIPv6Key: /* ipv6 */
m_apiIPv6 = enable; m_apiIPv6 = enable;
break;
case ApiRestrictedKey: /* restricted */ case ApiRestrictedKey: /* restricted */
m_apiRestricted = enable; m_apiRestricted = enable;
break;
case DryRunKey: /* --dry-run */
m_dryRun = enable;
break;
case AutoSaveKey:
m_autoSave = enable;
break;
default: default:
break; break;
@ -193,6 +369,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
m_pools.back().setRigId(arg); m_pools.back().setRigId(arg);
break; break;
case FingerprintKey: /* --tls-fingerprint */
m_pools.back().setFingerprint(arg);
break;
case VariantKey: /* --variant */ case VariantKey: /* --variant */
m_pools.back().algorithm().parseVariant(arg); m_pools.back().algorithm().parseVariant(arg);
break; break;
@ -209,6 +389,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
m_apiWorkerId = arg; m_apiWorkerId = arg;
break; break;
case ApiIdKey: /* --api-id */
m_apiId = arg;
break;
case UserAgentKey: /* --user-agent */ case UserAgentKey: /* --user-agent */
m_userAgent = arg; m_userAgent = arg;
break; break;
@ -223,7 +407,9 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg)
case SyslogKey: /* --syslog */ case SyslogKey: /* --syslog */
case KeepAliveKey: /* --keepalive */ case KeepAliveKey: /* --keepalive */
case NicehashKey: /* --nicehash */ case NicehashKey: /* --nicehash */
case TlsKey: /* --tls */
case ApiIPv6Key: /* --api-ipv6 */ case ApiIPv6Key: /* --api-ipv6 */
case DryRunKey: /* --dry-run */
return parseBoolean(key, true); return parseBoolean(key, true);
case ColorKey: /* --no-color */ case ColorKey: /* --no-color */
@ -254,40 +440,6 @@ bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg)
} }
bool xmrig::CommonConfig::save()
{
if (m_fileName.isNull()) {
return false;
}
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName.data(), O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr);
if (fd < 0) {
return false;
}
uv_fs_req_cleanup(&req);
rapidjson::Document doc;
getJSON(doc);
FILE *fp = fdopen(fd, "w");
char buf[4096];
rapidjson::FileWriteStream os(fp, buf, sizeof(buf));
rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
doc.Accept(writer);
fclose(fp);
uv_fs_close(uv_default_loop(), &req, fd, nullptr);
uv_fs_req_cleanup(&req);
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
return true;
}
void xmrig::CommonConfig::setFileName(const char *fileName) void xmrig::CommonConfig::setFileName(const char *fileName)
{ {
m_fileName = fileName; m_fileName = fileName;

View file

@ -21,17 +21,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __COMMONCONFIG_H__ #ifndef XMRIG_COMMONCONFIG_H
#define __COMMONCONFIG_H__ #define XMRIG_COMMONCONFIG_H
#include <vector> #include <vector>
#include "common/interfaces/IConfig.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "common/utils/c_str.h" #include "common/utils/c_str.h"
#include "common/xmrig.h" #include "common/xmrig.h"
#include "interfaces/IConfig.h"
namespace xmrig { namespace xmrig {
@ -41,14 +41,15 @@ class CommonConfig : public IConfig
{ {
public: public:
CommonConfig(); CommonConfig();
~CommonConfig();
inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiIPv6() const { return m_apiIPv6; }
inline bool isApiRestricted() const { return m_apiRestricted; } inline bool isApiRestricted() const { return m_apiRestricted; }
inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; } inline bool isBackground() const { return m_background; }
inline bool isColors() const { return m_colors; } inline bool isColors() const { return m_colors; }
inline bool isDryRun() const { return m_dryRun; }
inline bool isSyslog() const { return m_syslog; } inline bool isSyslog() const { return m_syslog; }
inline const Algorithm &algorithm() const { return m_algorithm; } inline const char *apiId() const { return m_apiId.data(); }
inline const char *apiToken() const { return m_apiToken.data(); } inline const char *apiToken() const { return m_apiToken.data(); }
inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *apiWorkerId() const { return m_apiWorkerId.data(); }
inline const char *logFile() const { return m_logFile.data(); } inline const char *logFile() const { return m_logFile.data(); }
@ -61,8 +62,15 @@ public:
inline int retryPause() const { return m_retryPause; } inline int retryPause() const { return m_retryPause; }
inline void setColors(bool colors) { m_colors = colors; } inline void setColors(bool colors) { m_colors = colors; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const char *fileName() const override { return m_fileName.data(); } inline const Algorithm &algorithm() const override { return m_algorithm; }
inline const char *fileName() const override { return m_fileName.data(); }
bool save() override;
void printAPI();
void printPools();
void printVersions();
protected: protected:
enum State { enum State {
@ -75,15 +83,16 @@ protected:
bool parseBoolean(int key, bool enable) override; bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override; bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override; bool parseUint64(int key, uint64_t arg) override;
bool save() override;
void setFileName(const char *fileName) override; void setFileName(const char *fileName) override;
Algorithm m_algorithm; Algorithm m_algorithm;
bool m_adjusted; bool m_adjusted;
bool m_apiIPv6; bool m_apiIPv6;
bool m_apiRestricted; bool m_apiRestricted;
bool m_autoSave;
bool m_background; bool m_background;
bool m_colors; bool m_colors;
bool m_dryRun;
bool m_syslog; bool m_syslog;
bool m_watch; bool m_watch;
int m_apiPort; int m_apiPort;
@ -94,6 +103,7 @@ protected:
State m_state; State m_state;
std::vector<Pool> m_activePools; std::vector<Pool> m_activePools;
std::vector<Pool> m_pools; std::vector<Pool> m_pools;
xmrig::c_str m_apiId;
xmrig::c_str m_apiToken; xmrig::c_str m_apiToken;
xmrig::c_str m_apiWorkerId; xmrig::c_str m_apiWorkerId;
xmrig::c_str m_fileName; xmrig::c_str m_fileName;

View file

@ -32,14 +32,19 @@
#endif #endif
#ifndef XMRIG_NO_TLS
# include <openssl/opensslv.h>
#endif
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h" #include "common/config/ConfigWatcher.h"
#include "common/interfaces/IConfig.h"
#include "common/interfaces/IWatcherListener.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "core/ConfigLoader_platform.h" #include "core/ConfigLoader_platform.h"
#include "interfaces/IConfig.h"
#include "interfaces/IWatcherListener.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
#include "rapidjson/filereadstream.h" #include "rapidjson/filereadstream.h"
@ -170,7 +175,13 @@ xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator
} }
if (!config->finalize()) { if (!config->finalize()) {
fprintf(stderr, "No valid configuration found. Exiting.\n"); if (!config->algorithm().isValid()) {
fprintf(stderr, "No valid algorithm specified. Exiting.\n");
}
else {
fprintf(stderr, "No valid configuration found. Exiting.\n");
}
delete config; delete config;
return nullptr; return nullptr;
} }
@ -307,6 +318,13 @@ void xmrig::ConfigLoader::showVersion()
printf("\nlibuv/%s\n", uv_version_string()); printf("\nlibuv/%s\n", uv_version_string());
# ifndef XMRIG_NO_HTTPD # 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<int>(strchr(v, ' ') - v), v);
}
# endif # endif
} }

View file

@ -27,9 +27,9 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h" #include "common/config/ConfigWatcher.h"
#include "common/interfaces/IWatcherListener.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "interfaces/IWatcherListener.h"
xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) : xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) :

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -21,6 +21,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <thread>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <intrin.h> # include <intrin.h>
@ -32,14 +35,8 @@
# define bit_AES (1 << 25) # define bit_AES (1 << 25)
#endif #endif
#ifndef bit_BMI2
# define bit_BMI2 (1 << 8)
#endif
#include <string.h> #include "common/cpu/BasicCpuInfo.h"
#include "Cpu.h"
#define VENDOR_ID (0) #define VENDOR_ID (0)
@ -74,7 +71,7 @@ static inline void cpuid(int level, int output[4]) {
static inline void cpu_brand_string(char* s) { static inline void cpu_brand_string(char* s) {
int cpu_info[4] = { 0 }; int32_t cpu_info[4] = { 0 };
cpuid(VENDOR_ID, cpu_info); cpuid(VENDOR_ID, cpu_info);
if (cpu_info[EAX_Reg] >= 4) { if (cpu_info[EAX_Reg] >= 4) {
@ -89,50 +86,46 @@ static inline void cpu_brand_string(char* s) {
static inline bool has_aes_ni() static inline bool has_aes_ni()
{ {
int cpu_info[4] = { 0 }; int32_t cpu_info[4] = { 0 };
cpuid(PROCESSOR_INFO, cpu_info); cpuid(PROCESSOR_INFO, cpu_info);
return (cpu_info[ECX_Reg] & bit_AES) != 0; return (cpu_info[ECX_Reg] & bit_AES) != 0;
} }
static inline bool has_bmi2() { xmrig::BasicCpuInfo::BasicCpuInfo() :
int cpu_info[4] = { 0 }; m_assembly(ASM_NONE),
cpuid(EXTENDED_FEATURES, cpu_info); m_aes(has_aes_ni()),
m_brand(),
return (cpu_info[EBX_Reg] & bit_BMI2) != 0; m_threads(std::thread::hardware_concurrency())
}
char Cpu::m_brand[64] = { 0 };
int Cpu::m_flags = 0;
int Cpu::m_l2_cache = 0;
int Cpu::m_l3_cache = 0;
int Cpu::m_sockets = 1;
int Cpu::m_totalCores = 0;
int Cpu::m_totalThreads = 0;
int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
{
int count = m_totalThreads / 2;
return count < 1 ? 1 : count;
}
void Cpu::initCommon()
{ {
cpu_brand_string(m_brand); cpu_brand_string(m_brand);
# if defined(__x86_64__) || defined(_M_AMD64) # ifndef XMRIG_NO_ASM
m_flags |= X86_64; if (hasAES()) {
char vendor[13] = { 0 };
int32_t data[4] = { 0 };
cpuid(0, data);
memcpy(vendor + 0, &data[1], 4);
memcpy(vendor + 4, &data[3], 4);
memcpy(vendor + 8, &data[2], 4);
if (memcmp(vendor, "GenuineIntel", 12) == 0) {
m_assembly = ASM_INTEL;
}
else if (memcmp(vendor, "AuthenticAMD", 12) == 0) {
m_assembly = ASM_RYZEN;
}
}
# endif # endif
}
if (has_aes_ni()) {
m_flags |= AES;
} size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
if (has_bmi2()) { const size_t count = threads() / 2;
m_flags |= BMI2;
} return count < 1 ? 1 : count;
} }

View file

@ -0,0 +1,70 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 m_assembly; }
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:
Assembly m_assembly;
bool m_aes;
char m_brand[64];
int32_t m_threads;
};
} /* namespace xmrig */
#endif /* XMRIG_BASICCPUINFO_H */

View file

@ -21,34 +21,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h> #include <string.h>
#include <thread>
#include "Cpu.h" #include "common/cpu/BasicCpuInfo.h"
char Cpu::m_brand[64] = { 0 }; xmrig::BasicCpuInfo::BasicCpuInfo() :
int Cpu::m_flags = 0; m_aes(false),
int Cpu::m_l2_cache = 0; m_brand(),
int Cpu::m_l3_cache = 0; m_threads(std::thread::hardware_concurrency())
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()
{ {
memcpy(m_brand, "Unknown", 7); memcpy(m_brand, "Unknown", 7);
# if defined(XMRIG_ARMv8) # if __ARM_FEATURE_CRYPTO
m_flags |= X86_64; m_aes = true;
m_flags |= AES;
# endif # endif
} }
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
return threads();
}

View file

@ -22,33 +22,36 @@
*/ */
#ifdef __FreeBSD__ #include <assert.h>
# include <sys/types.h>
# include <sys/param.h>
# include <sys/cpuset.h>
# include <pthread_np.h>
#endif
#include <pthread.h> #include "common/cpu/BasicCpuInfo.h"
#include <sched.h> #include "common/cpu/Cpu.h"
#include <unistd.h>
#include <string.h>
#include "Cpu.h" static xmrig::ICpuInfo *cpuInfo = nullptr;
#ifdef __FreeBSD__ xmrig::ICpuInfo *xmrig::Cpu::info()
typedef cpuset_t cpu_set_t;
#endif
void Cpu::init()
{ {
# ifdef XMRIG_NO_LIBCPUID assert(cpuInfo != nullptr);
m_totalThreads = sysconf(_SC_NPROCESSORS_CONF);
# endif
initCommon(); return cpuInfo;
}
void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
cpuInfo = new BasicCpuInfo();
}
void xmrig::Cpu::release()
{
assert(cpuInfo != nullptr);
delete cpuInfo;
cpuInfo = nullptr;
} }

View file

@ -4,7 +4,7 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -21,20 +21,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_CPU_H
#include <pthread.h> #define XMRIG_CPU_H
#include <sched.h>
#include <unistd.h>
#include "Cpu.h" #include "common/interfaces/ICpuInfo.h"
void Cpu::init() namespace xmrig {
class Cpu
{ {
# ifdef XMRIG_NO_LIBCPUID public:
m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); static ICpuInfo *info();
# endif static void init();
static void release();
};
initCommon();
} } /* namespace xmrig */
#endif /* XMRIG_CPU_H */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -57,29 +58,43 @@ static AlgoData const algorithms[] = {
{ "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 }, { "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 },
{ "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, { "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, { "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
{ "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 # ifndef XMRIG_NO_AEON
{ "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
{ "cryptonight-light", "cn-light", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO },
{ "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, { "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 },
{ "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, { "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
{ "cryptonight-lite/ipbc", "cn-lite/ipbc", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC },
# endif # endif
# ifndef XMRIG_NO_SUMO # ifndef XMRIG_NO_SUMO
{ "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, { "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_AUTO },
{ "cryptonight-heavy/0", "cn-heavy/0", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 },
{ "cryptonight-heavy/xhv", "cn-heavy/xhv", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_XHV },
{ "cryptonight-heavy/tube", "cn-heavy/tube", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_TUBE },
# endif # endif
}; };
#ifdef XMRIG_PROXY_PROJECT #ifdef XMRIG_PROXY_PROJECT
static AlgoData const xmrStakAlgorithms[] = { static AlgoData const xmrStakAlgorithms[] = {
{ "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, { "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, { "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 },
{ "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, { "cryptonight-monerov8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
{ "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, { "cryptonight_v8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 },
{ "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, { "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL },
{ "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, { "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 },
{ "cryptonight_lite_v7_xor", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC }, { "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
{ "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 },
{ "cryptonight_heavy", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 },
{ "cryptonight_haven", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_XHV },
{ "cryptonight_masari", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR },
{ "cryptonight_masari", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR },
{ "cryptonight-bittube2", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_TUBE }, // bittube-miner
{ "cryptonight_alloy", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, // xmr-stak-alloy
}; };
#endif #endif
@ -87,8 +102,13 @@ static AlgoData const xmrStakAlgorithms[] = {
static const char *variants[] = { static const char *variants[] = {
"0", "0",
"1", "1",
"ipbc", "tube",
"xtl" "xtl",
"msr",
"xhv",
"xao",
"rto",
"2",
}; };
@ -144,11 +164,6 @@ void xmrig::Algorithm::parseAlgorithm(const char *algo)
void xmrig::Algorithm::parseVariant(const char *variant) void xmrig::Algorithm::parseVariant(const char *variant)
{ {
if (m_algo == CRYPTONIGHT_HEAVY) {
m_variant = VARIANT_0;
return;
}
m_variant = VARIANT_AUTO; m_variant = VARIANT_AUTO;
for (size_t i = 0; i < ARRAY_SIZE(variants); i++) { for (size_t i = 0; i < ARRAY_SIZE(variants); i++) {
@ -162,11 +177,21 @@ void xmrig::Algorithm::parseVariant(const char *variant)
void xmrig::Algorithm::parseVariant(int variant) void xmrig::Algorithm::parseVariant(int variant)
{ {
if (variant >= VARIANT_AUTO && variant <= VARIANT_XTL) { assert(variant >= -1 && variant <= 2);
m_variant = static_cast<Variant>(variant);
} switch (variant) {
else { case -1:
assert(false); case 0:
case 1:
m_variant = static_cast<Variant>(variant);
break;
case 2:
m_variant = VARIANT_2;
break;
default:
break;
} }
} }
@ -174,10 +199,6 @@ void xmrig::Algorithm::parseVariant(int variant)
void xmrig::Algorithm::setAlgo(Algo algo) void xmrig::Algorithm::setAlgo(Algo algo)
{ {
m_algo = algo; m_algo = algo;
if (m_algo == CRYPTONIGHT_HEAVY) {
m_variant = VARIANT_0;
}
} }

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,8 +23,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ALGORITHM_H__ #ifndef XMRIG_ALGORITHM_H
#define __ALGORITHM_H__ #define XMRIG_ALGORITHM_H
#include <vector> #include <vector>

View file

@ -23,8 +23,8 @@
*/ */
#ifndef KECCAK_H_ #ifndef XMRIG_KECCAK_H
#define KECCAK_H_ #define XMRIG_KECCAK_H
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -41,9 +41,15 @@ inline void keccak(const uint8_t *in, size_t inlen, uint8_t *md)
keccak(in, static_cast<int>(inlen), md, 200); keccak(in, static_cast<int>(inlen), md, 200);
} }
inline void keccak(const char *in, size_t inlen, uint8_t *md)
{
keccak(reinterpret_cast<const uint8_t *>(in), static_cast<int>(inlen), md, 200);
}
// update the state // update the state
void keccakf(uint64_t st[25], int norounds); void keccakf(uint64_t st[25], int norounds);
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* KECCAK_H_ */ #endif /* XMRIG_KECCAK_H */

View file

@ -20,10 +20,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ICONFIG_H__ #ifndef XMRIG_ICONFIG_H
#define __ICONFIG_H__ #define XMRIG_ICONFIG_H
#include "common/crypto/Algorithm.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@ -41,6 +42,7 @@ public:
ApiPort = 4000, ApiPort = 4000,
ApiRestrictedKey = 4004, ApiRestrictedKey = 4004,
ApiWorkerIdKey = 4002, ApiWorkerIdKey = 4002,
ApiIdKey = 4005,
BackgroundKey = 'B', BackgroundKey = 'B',
ColorKey = 1002, ColorKey = 1002,
ConfigKey = 'c', ConfigKey = 'c',
@ -61,6 +63,9 @@ public:
VerboseKey = 1100, VerboseKey = 1100,
VersionKey = 'V', VersionKey = 'V',
WatchKey = 1105, WatchKey = 1105,
TlsKey = 1013,
FingerprintKey = 1014,
AutoSaveKey = 1016,
// xmrig common // xmrig common
CPUPriorityKey = 1021, CPUPriorityKey = 1021,
@ -76,6 +81,20 @@ public:
SafeKey = 1005, SafeKey = 1005,
ThreadsKey = 't', ThreadsKey = 't',
HardwareAESKey = 1011, HardwareAESKey = 1011,
AssemblyKey = 1015,
// xmrig amd
OclPlatformKey = 1400,
OclAffinityKey = 1401,
OclDevicesKey = 1402,
OclLaunchKey = 1403,
OclCacheKey = 1404,
OclPrintKey = 1405,
OclLoaderKey = 1406,
OclSridedIndexKey = 1407,
OclMemChunkKey = 1408,
OclUnrollKey = 1409,
OclCompModeKey = 1410,
// xmrig-proxy // xmrig-proxy
AccessLogFileKey = 'A', AccessLogFileKey = 'A',
@ -87,6 +106,16 @@ public:
PoolCoinKey = 'C', PoolCoinKey = 'C',
ReuseTimeoutKey = 1106, ReuseTimeoutKey = 1106,
WorkersKey = 1103, WorkersKey = 1103,
WorkersAdvKey = 1107,
// xmrig nvidia
CudaMaxThreadsKey = 1200,
CudaBFactorKey = 1201,
CudaBSleepKey = 1202,
CudaDevicesKey = 1203,
CudaLaunchKey = 1204,
CudaAffinityKey = 1205,
CudaMaxUsageKey = 1206,
}; };
virtual ~IConfig() {} virtual ~IConfig() {}
@ -97,6 +126,7 @@ public:
virtual bool parseString(int key, const char *arg) = 0; virtual bool parseString(int key, const char *arg) = 0;
virtual bool parseUint64(int key, uint64_t arg) = 0; virtual bool parseUint64(int key, uint64_t arg) = 0;
virtual bool save() = 0; virtual bool save() = 0;
virtual const Algorithm &algorithm() const = 0;
virtual const char *fileName() const = 0; virtual const char *fileName() const = 0;
virtual void getJSON(rapidjson::Document &doc) const = 0; virtual void getJSON(rapidjson::Document &doc) const = 0;
virtual void parseJSON(const rapidjson::Document &doc) = 0; virtual void parseJSON(const rapidjson::Document &doc) = 0;
@ -107,4 +137,4 @@ public:
} /* namespace xmrig */ } /* namespace xmrig */
#endif // __ICONFIG_H__ #endif // XMRIG_ICONFIG_H

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __ICONTROLLERLISTENER_H__ #ifndef XMRIG_ICONTROLLERLISTENER_H
#define __ICONTROLLERLISTENER_H__ #define XMRIG_ICONTROLLERLISTENER_H
namespace xmrig { namespace xmrig {
@ -43,4 +43,4 @@ public:
} /* namespace xmrig */ } /* namespace xmrig */
#endif // __ICONTROLLERLISTENER_H__ #endif // XMRIG_ICONTROLLERLISTENER_H

View file

@ -0,0 +1,60 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2018 XMRig <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CPUINFO_H
#define XMRIG_CPUINFO_H
#include <stddef.h>
#include <stdint.h>
#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

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -26,15 +26,30 @@
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h>
class ILogBackend class ILogBackend
{ {
public: public:
enum Level {
ERR,
WARNING,
NOTICE,
INFO,
DEBUG
};
# ifdef APP_DEBUG
constexpr static const size_t kBufferSize = 1024;
# else
constexpr static const size_t kBufferSize = 512;
# endif
virtual ~ILogBackend() {} virtual ~ILogBackend() {}
virtual void message(int level, const char* fmt, va_list args) = 0; virtual void message(Level level, const char* fmt, va_list args) = 0;
virtual void text(const char* fmt, va_list args) = 0; virtual void text(const char* fmt, va_list args) = 0;
}; };

View file

@ -21,46 +21,69 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CPU_H__
#define __CPU_H__ #include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <stdint.h> #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);
}

55
src/common/log/BasicLog.h Normal file
View file

@ -0,0 +1,55 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __BASICLOG_H__
#define __BASICLOG_H__
#include <uv.h>
#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__ */

View file

@ -66,7 +66,7 @@ ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
} }
void ConsoleLog::message(int level, const char* fmt, va_list args) void ConsoleLog::message(Level level, const char* fmt, va_list args)
{ {
time_t now = time(nullptr); time_t now = time(nullptr);
tm stime; tm stime;
@ -77,43 +77,18 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
localtime_r(&now, &stime); localtime_r(&now, &stime);
# endif # endif
const char* color = nullptr; const bool isColors = m_controller->config()->isColors();
const bool colors = m_controller->config()->isColors();
if (colors) { snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
switch (level) {
case Log::ERR:
color = Log::kCL_RED;
break;
case Log::WARNING:
color = Log::kCL_YELLOW;
break;
case Log::NOTICE:
color = Log::kCL_WHITE;
break;
case Log::DEBUG:
color = Log::kCL_GRAY;
break;
default:
color = "";
break;
}
}
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n",
stime.tm_year + 1900, stime.tm_year + 1900,
stime.tm_mon + 1, stime.tm_mon + 1,
stime.tm_mday, stime.tm_mday,
stime.tm_hour, stime.tm_hour,
stime.tm_min, stime.tm_min,
stime.tm_sec, stime.tm_sec,
colors ? color : "", Log::colorByLevel(level, isColors),
fmt, fmt,
colors ? Log::kCL_N : "" Log::endl(isColors)
); );
print(args); print(args);
@ -122,7 +97,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args)
void ConsoleLog::text(const char* fmt, va_list args) void ConsoleLog::text(const char* fmt, va_list args)
{ {
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->isColors() ? Log::kCL_N : ""); snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(m_controller->config()->isColors()));
print(args); print(args);
} }

View file

@ -28,7 +28,7 @@
#include <uv.h> #include <uv.h>
#include "interfaces/ILogBackend.h" #include "common/interfaces/ILogBackend.h"
namespace xmrig { namespace xmrig {
@ -41,14 +41,14 @@ class ConsoleLog : public ILogBackend
public: public:
ConsoleLog(xmrig::Controller *controller); ConsoleLog(xmrig::Controller *controller);
void message(int level, const char *fmt, va_list args) override; void message(Level level, const char *fmt, va_list args) override;
void text(const char *fmt, va_list args) override; void text(const char *fmt, va_list args) override;
private: private:
bool isWritable() const; bool isWritable() const;
void print(va_list args); void print(va_list args);
char m_buf[512]; char m_buf[kBufferSize];
char m_fmt[256]; char m_fmt[256];
uv_buf_t m_uvBuf; uv_buf_t m_uvBuf;
uv_stream_t *m_stream; uv_stream_t *m_stream;

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -30,9 +30,13 @@
#include "common/log/FileLog.h" #include "common/log/FileLog.h"
#include "common/log/Log.h"
#include "core/Config.h"
#include "core/Controller.h"
FileLog::FileLog(const char *fileName) FileLog::FileLog(xmrig::Controller *controller, const char *fileName) :
m_controller(controller)
{ {
uv_fs_t req; uv_fs_t req;
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr); m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
@ -40,7 +44,7 @@ FileLog::FileLog(const char *fileName)
} }
void FileLog::message(int level, const char* fmt, va_list args) void FileLog::message(Level level, const char* fmt, va_list args)
{ {
if (m_file < 0) { if (m_file < 0) {
return; return;
@ -55,29 +59,33 @@ void FileLog::message(int level, const char* fmt, va_list args)
localtime_r(&now, &stime); localtime_r(&now, &stime);
# endif # endif
char *buf = new char[512]; const bool isColors = m_controller->config()->isColors();
int size = snprintf(buf, 23, "[%d-%02d-%02d %02d:%02d:%02d] ",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec);
size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size; snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
buf[size] = '\n'; stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
Log::colorByLevel(level, isColors),
fmt,
Log::endl(isColors)
);
write(buf, size + 1); char *buf = new char[kBufferSize];
const int size = vsnprintf(buf, kBufferSize - 1, m_fmt, args);
write(buf, size);
} }
void FileLog::text(const char* fmt, va_list args) void FileLog::text(const char* fmt, va_list args)
{ {
message(0, fmt, args); message(INFO, fmt, args);
} }
void FileLog::onWrite(uv_fs_t *req) void FileLog::onWrite(uv_fs_t *req)
{ {
delete [] static_cast<char *>(req->data); delete [] static_cast<char *>(req->data);
@ -93,5 +101,5 @@ void FileLog::write(char *data, size_t size)
uv_fs_t *req = new uv_fs_t; uv_fs_t *req = new uv_fs_t;
req->data = buf.base; req->data = buf.base;
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, 0, FileLog::onWrite); uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, FileLog::onWrite);
} }

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -28,15 +28,20 @@
#include <uv.h> #include <uv.h>
#include "interfaces/ILogBackend.h" #include "common/interfaces/ILogBackend.h"
namespace xmrig {
class Controller;
}
class FileLog : public ILogBackend class FileLog : public ILogBackend
{ {
public: public:
FileLog(const char *fileName); FileLog(xmrig::Controller *controller, const char *fileName);
void message(int level, const char* fmt, va_list args) override; void message(Level level, const char* fmt, va_list args) override;
void text(const char* fmt, va_list args) override; void text(const char* fmt, va_list args) override;
private: private:
@ -44,7 +49,9 @@ private:
void write(char *data, size_t size); void write(char *data, size_t size);
char m_fmt[256];
int m_file; int m_file;
xmrig::Controller *m_controller;
}; };
#endif /* __FILELOG_H__ */ #endif /* __FILELOG_H__ */

View file

@ -29,14 +29,28 @@
#include <time.h> #include <time.h>
#include "common/interfaces/ILogBackend.h"
#include "common/log/BasicLog.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "interfaces/ILogBackend.h"
Log *Log::m_self = nullptr; Log *Log::m_self = nullptr;
void Log::message(Log::Level level, const char* fmt, ...) static const char *colors[5] = {
"\x1B[0;31m", /* ERR */
"\x1B[0;33m", /* WARNING */
"\x1B[1;37m", /* NOTICE */
"", /* INFO */
# ifdef WIN32
"\x1B[1;30m" /* DEBUG */
# else
"\x1B[90m" /* DEBUG */
# endif
};
void Log::message(ILogBackend::Level level, const char* fmt, ...)
{ {
uv_mutex_lock(&m_mutex); uv_mutex_lock(&m_mutex);
@ -76,6 +90,34 @@ void Log::text(const char* fmt, ...)
} }
const char *Log::colorByLevel(ILogBackend::Level level, bool isColors)
{
if (!isColors) {
return "";
}
return colors[level];
}
const char *Log::endl(bool isColors)
{
# ifdef _WIN32
return isColors ? "\x1B[0m\r\n" : "\r\n";
# else
return isColors ? "\x1B[0m\n" : "\n";
# endif
}
void Log::defaultInit()
{
m_self = new Log();
add(new BasicLog());
}
Log::~Log() Log::~Log()
{ {
for (auto backend : m_backends) { for (auto backend : m_backends) {

View file

@ -30,39 +30,24 @@
#include <vector> #include <vector>
class ILogBackend; #include "common/interfaces/ILogBackend.h"
class Log class Log
{ {
public: public:
enum Level { static inline Log* i() { if (!m_self) { defaultInit(); } return m_self; }
ERR,
WARNING,
NOTICE,
INFO,
DEBUG
};
constexpr static const char* kCL_N = "\x1B[0m";
constexpr static const char* kCL_RED = "\x1B[31m";
constexpr static const char* kCL_YELLOW = "\x1B[33m";
constexpr static const char* kCL_WHITE = "\x1B[01;37m";
# ifdef WIN32
constexpr static const char* kCL_GRAY = "\x1B[01;30m";
# else
constexpr static const char* kCL_GRAY = "\x1B[90m";
# endif
static inline Log* i() { assert(m_self != nullptr); return m_self; }
static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); } static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); }
static inline void init() { if (!m_self) { new Log(); } } static inline void init() { if (!m_self) { new Log(); } }
static inline void release() { assert(m_self != nullptr); delete m_self; } static inline void release() { assert(m_self != nullptr); delete m_self; }
void message(Level level, const char* fmt, ...); void message(ILogBackend::Level level, const char* fmt, ...);
void text(const char* fmt, ...); void text(const char* fmt, ...);
static const char *colorByLevel(ILogBackend::Level level, bool isColors = true);
static const char *endl(bool isColors = true);
static void defaultInit();
private: private:
inline Log() { inline Log() {
assert(m_self == nullptr); assert(m_self == nullptr);
@ -80,32 +65,34 @@ private:
}; };
#define RED_BOLD(x) "\e[1;31m" x "\e[0m" #define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m"
#define RED(x) "\e[0;31m" x "\e[0m" #define RED(x) "\x1B[0;31m" x "\x1B[0m"
#define GREEN_BOLD(x) "\e[1;32m" x "\e[0m" #define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m"
#define GREEN(x) "\e[0;32m" x "\e[0m" #define GREEN(x) "\x1B[0;32m" x "\x1B[0m"
#define MAGENTA_BOLD(x) "\e[1;35m" x "\e[0m" #define YELLOW(x) "\x1B[0;33m" x "\x1B[0m"
#define MAGENTA(x) "\e[0;35m" x "\e[0m" #define YELLOW_BOLD(x) "\x1B[1;33m" x "\x1B[0m"
#define CYAN_BOLD(x) "\e[1;36m" x "\e[0m" #define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m"
#define CYAN(x) "\e[0;36m" x "\e[0m" #define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m"
#define WHITE_BOLD(x) "\e[1;37m" x "\e[0m" #define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m"
#define WHITE(x) "\e[0;37m" x "\e[0m" #define CYAN(x) "\x1B[0;36m" x "\x1B[0m"
#define WHITE_BOLD(x) "\x1B[1;37m" x "\x1B[0m"
#define WHITE(x) "\x1B[0;37m" x "\x1B[0m"
#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) #define LOG_ERR(x, ...) Log::i()->message(ILogBackend::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) #define LOG_WARN(x, ...) Log::i()->message(ILogBackend::WARNING, x, ##__VA_ARGS__)
#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__) #define LOG_NOTICE(x, ...) Log::i()->message(ILogBackend::NOTICE, x, ##__VA_ARGS__)
#define LOG_INFO(x, ...) Log::i()->message(Log::INFO, x, ##__VA_ARGS__) #define LOG_INFO(x, ...) Log::i()->message(ILogBackend::INFO, x, ##__VA_ARGS__)
#ifdef APP_DEBUG #ifdef APP_DEBUG
# define LOG_DEBUG(x, ...) Log::i()->message(Log::DEBUG, x, ##__VA_ARGS__) # define LOG_DEBUG(x, ...) Log::i()->message(ILogBackend::DEBUG, x, ##__VA_ARGS__)
#else #else
# define LOG_DEBUG(x, ...) # define LOG_DEBUG(x, ...)
#endif #endif
#if defined(APP_DEBUG) || defined(APP_DEVEL) #if defined(APP_DEBUG) || defined(APP_DEVEL)
# define LOG_DEBUG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) # define LOG_DEBUG_ERR(x, ...) Log::i()->message(ILogBackend::ERR, x, ##__VA_ARGS__)
# define LOG_DEBUG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) # define LOG_DEBUG_WARN(x, ...) Log::i()->message(ILogBackend::WARNING, x, ##__VA_ARGS__)
#else #else
# define LOG_DEBUG_ERR(x, ...) # define LOG_DEBUG_ERR(x, ...)
# define LOG_DEBUG_WARN(x, ...) # define LOG_DEBUG_WARN(x, ...)

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -35,13 +35,13 @@ SysLog::SysLog()
} }
void SysLog::message(int level, const char *fmt, va_list args) void SysLog::message(Level level, const char *fmt, va_list args)
{ {
vsyslog(level, fmt, args); vsyslog(static_cast<int>(level), fmt, args);
} }
void SysLog::text(const char *fmt, va_list args) void SysLog::text(const char *fmt, va_list args)
{ {
message(LOG_INFO, fmt, args); vsyslog(LOG_INFO, fmt, args);
} }

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -25,7 +25,7 @@
#define __SYSLOG_H__ #define __SYSLOG_H__
#include "interfaces/ILogBackend.h" #include "common/interfaces/ILogBackend.h"
class SysLog : public ILogBackend class SysLog : public ILogBackend
@ -33,7 +33,7 @@ class SysLog : public ILogBackend
public: public:
SysLog(); SysLog();
void message(int level, const char *fmt, va_list args) override; void message(Level level, const char *fmt, va_list args) override;
void text(const char *fmt, va_list args) override; void text(const char *fmt, va_list args) override;
}; };

View file

@ -29,9 +29,16 @@
#include <utility> #include <utility>
#ifndef XMRIG_NO_TLS
# include <openssl/ssl.h>
# include <openssl/err.h>
# include "common/net/Tls.h"
#endif
#include "common/interfaces/IClientListener.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Client.h" #include "common/net/Client.h"
#include "interfaces/IClientListener.h"
#include "net/JobResult.h" #include "net/JobResult.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/error/en.h" #include "rapidjson/error/en.h"
@ -48,6 +55,17 @@ int64_t Client::m_sequence = 1;
xmrig::Storage<Client> Client::m_storage; xmrig::Storage<Client> 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) : Client::Client(int id, const char *agent, IClientListener *listener) :
m_ipv6(false), m_ipv6(false),
m_nicehash(false), m_nicehash(false),
@ -61,6 +79,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_failures(0), m_failures(0),
m_recvBufPos(0), m_recvBufPos(0),
m_state(UnconnectedState), m_state(UnconnectedState),
m_tls(nullptr),
m_expire(0), m_expire(0),
m_jobs(0), m_jobs(0),
m_keepAlive(0), m_keepAlive(0),
@ -92,6 +111,12 @@ Client::~Client()
void Client::connect() void Client::connect()
{ {
# ifndef XMRIG_NO_TLS
if (m_pool.isTLS()) {
m_tls = new Tls(this);
}
# endif
resolve(m_pool.host()); resolve(m_pool.host());
} }
@ -122,6 +147,7 @@ void Client::deleteLater()
} }
void Client::setPool(const Pool &pool) void Client::setPool(const Pool &pool)
{ {
if (!pool.isValid()) { 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) int64_t Client::submit(const JobResult &result)
{ {
using namespace rapidjson; using namespace rapidjson;
@ -209,7 +259,11 @@ int64_t Client::submit(const JobResult &result)
bool Client::close() bool Client::close()
{ {
if (m_state == UnconnectedState || m_state == ClosingState || !m_socket) { if (m_state == ClosingState) {
return m_socket != nullptr;
}
if (m_state == UnconnectedState || m_socket == nullptr) {
return false; return false;
} }
@ -245,6 +299,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 &params, int *code) bool Client::parseJob(const rapidjson::Value &params, int *code)
{ {
if (!params.IsObject()) { if (!params.IsObject()) {
@ -270,17 +334,17 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
} }
if (params.HasMember("algo")) { if (params.HasMember("algo")) {
job.algorithm().parseAlgorithm(params["algo"].GetString()); job.setAlgorithm(params["algo"].GetString());
} }
if (params.HasMember("variant")) { if (params.HasMember("variant")) {
const rapidjson::Value &variant = params["variant"]; const rapidjson::Value &variant = params["variant"];
if (variant.IsInt()) { if (variant.IsInt()) {
job.algorithm().parseVariant(variant.GetInt()); job.setVariant(variant.GetInt());
} }
else if (variant.IsString()){ else if (variant.IsString()){
job.algorithm().parseVariant(variant.GetString()); job.setVariant(variant.GetString());
} }
} }
@ -330,8 +394,47 @@ 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<int>(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 bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const
{ {
# ifdef XMRIG_PROXY_PROJECT
if (m_pool.algorithm().variant() == xmrig::VARIANT_AUTO || m_id == -1) {
return true;
}
# endif
if (m_pool.isCompatible(algorithm)) { if (m_pool.isCompatible(algorithm)) {
return true; return true;
} }
@ -383,7 +486,9 @@ int64_t Client::send(const rapidjson::Document &doc)
doc.Accept(writer); doc.Accept(writer);
const size_t size = buffer.GetSize(); 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; return -1;
} }
@ -398,16 +503,27 @@ int64_t Client::send(const rapidjson::Document &doc)
int64_t Client::send(size_t size) int64_t Client::send(size_t size)
{ {
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); 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); # ifndef XMRIG_NO_TLS
return -1; 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) { if (uv_try_write(m_stream, &buf, 1) < 0) {
close(); close();
return -1; return -1;
}
} }
m_expire = uv_now(uv_default_loop()) + kResponseTimeout; m_expire = uv_now(uv_default_loop()) + kResponseTimeout;
@ -438,7 +554,6 @@ void Client::connect(sockaddr *addr)
setState(ConnectingState); setState(ConnectingState);
reinterpret_cast<sockaddr_in*>(addr)->sin_port = htons(m_pool.port()); reinterpret_cast<sockaddr_in*>(addr)->sin_port = htons(m_pool.port());
delete m_socket;
uv_connect_t *req = new uv_connect_t; uv_connect_t *req = new uv_connect_t;
req->data = m_storage.ptr(m_key); req->data = m_storage.ptr(m_key);
@ -457,6 +572,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() void Client::login()
{ {
using namespace rapidjson; using namespace rapidjson;
@ -478,13 +609,19 @@ void Client::login()
params.AddMember("rigid", StringRef(m_pool.rigId()), allocator); params.AddMember("rigid", StringRef(m_pool.rigId()), allocator);
} }
Value algo(kArrayType); # ifdef XMRIG_PROXY_PROJECT
if (m_pool.algorithm().variant() != xmrig::VARIANT_AUTO)
# endif
{
Value algo(kArrayType);
for (const auto &a : m_pool.algorithms()) { for (const auto &a : m_pool.algorithms()) {
algo.PushBack(StringRef(a.shortName()), allocator); algo.PushBack(StringRef(a.shortName()), allocator);
}
params.AddMember("algo", algo, allocator);
} }
params.AddMember("algo", algo, allocator);
doc.AddMember("params", params, allocator); doc.AddMember("params", params, allocator);
send(doc); send(doc);
@ -499,6 +636,13 @@ void Client::onClose()
m_socket = nullptr; m_socket = nullptr;
setState(UnconnectedState); setState(UnconnectedState);
# ifndef XMRIG_NO_TLS
if (m_tls) {
delete m_tls;
m_tls = nullptr;
}
# endif
reconnect(); reconnect();
} }
@ -653,6 +797,35 @@ void Client::ping()
} }
void Client::read()
{
char* end;
char* start = m_recvBuf.base;
size_t remaining = m_recvBufPos;
while ((end = static_cast<char*>(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() void Client::reconnect()
{ {
if (!m_listener) { if (!m_listener) {
@ -661,13 +834,14 @@ void Client::reconnect()
return; return;
} }
setState(ConnectingState);
m_keepAlive = 0; m_keepAlive = 0;
if (m_failures == -1) { if (m_failures == -1) {
return m_listener->onClose(this, -1); return m_listener->onClose(this, -1);
} }
setState(ConnectingState);
m_failures++; m_failures++;
m_listener->onClose(this, (int) m_failures); m_listener->onClose(this, (int) m_failures);
@ -677,7 +851,7 @@ void Client::reconnect()
void Client::setState(SocketState state) 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) { if (m_state == state) {
return; return;
@ -745,7 +919,7 @@ void Client::onConnect(uv_connect_t *req, int status)
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead); uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
delete req; delete req;
client->login(); client->handshake();
} }
@ -757,7 +931,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
} }
if (nread < 0) { if (nread < 0) {
if (nread != UV_EOF && !client->isQuiet()) { if (!client->isQuiet()) {
LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread)); LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread));
} }
@ -777,30 +951,18 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
client->m_recvBufPos += nread; client->m_recvBufPos += nread;
char* end; # ifndef XMRIG_NO_TLS
char* start = client->m_recvBuf.base; if (client->isTLS()) {
size_t remaining = client->m_recvBufPos; LOG_DEBUG("[%s] TLS received (%d bytes)", client->m_pool.url(), static_cast<int>(nread));
while ((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr) { client->m_tls->read(client->m_recvBuf.base, client->m_recvBufPos);
end++;
size_t len = end - start;
client->parse(start, len);
remaining -= len;
start = end;
}
if (remaining == 0) {
client->m_recvBufPos = 0; client->m_recvBufPos = 0;
return;
} }
else
if (start == client->m_recvBuf.base) { # endif
return; {
client->read();
} }
memcpy(client->m_recvBuf.base, start, remaining);
client->m_recvBufPos = remaining;
} }

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CLIENT_H__ #ifndef XMRIG_CLIENT_H
#define __CLIENT_H__ #define XMRIG_CLIENT_H
#include <map> #include <map>
@ -30,6 +30,7 @@
#include <vector> #include <vector>
#include "common/crypto/Algorithm.h"
#include "common/net/Id.h" #include "common/net/Id.h"
#include "common/net/Job.h" #include "common/net/Job.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
@ -42,6 +43,9 @@ class IClientListener;
class JobResult; class JobResult;
typedef struct bio_st BIO;
class Client class Client
{ {
public: public:
@ -53,12 +57,20 @@ public:
ClosingState ClosingState
}; };
constexpr static int kResponseTimeout = 20 * 1000; constexpr static int kResponseTimeout = 20 * 1000;
# ifndef XMRIG_NO_TLS
constexpr static int kInputBufferSize = 1024 * 16;
# else
constexpr static int kInputBufferSize = 1024 * 2;
# endif
Client(int id, const char *agent, IClientListener *listener); Client(int id, const char *agent, IClientListener *listener);
~Client(); ~Client();
bool disconnect(); bool disconnect();
const char *tlsFingerprint() const;
const char *tlsVersion() const;
int64_t submit(const JobResult &result); int64_t submit(const JobResult &result);
void connect(); void connect();
void connect(const Pool &pool); void connect(const Pool &pool);
@ -66,18 +78,22 @@ public:
void setPool(const Pool &pool); void setPool(const Pool &pool);
void tick(uint64_t now); void tick(uint64_t now);
inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; }
inline const char *host() const { return m_pool.host(); } inline const char *host() const { return m_pool.host(); }
inline const char *ip() const { return m_ip; } inline const char *ip() const { return m_ip; }
inline const Job &job() const { return m_job; } inline const Job &job() const { return m_job; }
inline int id() const { return m_id; } inline int id() const { return m_id; }
inline SocketState state() const { return m_state; } inline SocketState state() const { return m_state; }
inline uint16_t port() const { return m_pool.port(); } inline uint16_t port() const { return m_pool.port(); }
inline void setQuiet(bool quiet) { m_quiet = quiet; } inline void setAlgo(const xmrig::Algorithm &algo) { m_pool.setAlgo(algo); }
inline void setRetries(int retries) { m_retries = retries; } inline void setQuiet(bool quiet) { m_quiet = quiet; }
inline void setRetryPause(int ms) { m_retryPause = ms; } inline void setRetries(int retries) { m_retries = retries; }
inline void setRetryPause(int ms) { m_retryPause = ms; }
private: private:
class Tls;
enum Extensions { enum Extensions {
NicehashExt = 1, NicehashExt = 1,
AlgoExt = 2 AlgoExt = 2
@ -85,14 +101,17 @@ private:
bool close(); bool close();
bool isCriticalError(const char *message); bool isCriticalError(const char *message);
bool isTLS() const;
bool parseJob(const rapidjson::Value &params, int *code); bool parseJob(const rapidjson::Value &params, int *code);
bool parseLogin(const rapidjson::Value &result, int *code); bool parseLogin(const rapidjson::Value &result, int *code);
bool send(BIO *bio);
bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const; bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const;
int resolve(const char *host); int resolve(const char *host);
int64_t send(const rapidjson::Document &doc); int64_t send(const rapidjson::Document &doc);
int64_t send(size_t size); int64_t send(size_t size);
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6); void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
void connect(sockaddr *addr); void connect(sockaddr *addr);
void handshake();
void login(); void login();
void onClose(); void onClose();
void parse(char *line, size_t len); void parse(char *line, size_t len);
@ -100,6 +119,7 @@ private:
void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error); void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error);
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
void ping(); void ping();
void read();
void reconnect(); void reconnect();
void setState(SocketState state); void setState(SocketState state);
void startTimeout(); void startTimeout();
@ -118,9 +138,9 @@ private:
bool m_ipv6; bool m_ipv6;
bool m_nicehash; bool m_nicehash;
bool m_quiet; bool m_quiet;
char m_buf[2048]; char m_buf[kInputBufferSize];
char m_ip[46]; char m_ip[46];
char m_sendBuf[768]; char m_sendBuf[2048];
const char *m_agent; const char *m_agent;
IClientListener *m_listener; IClientListener *m_listener;
int m_extensions; int m_extensions;
@ -133,6 +153,7 @@ private:
size_t m_recvBufPos; size_t m_recvBufPos;
SocketState m_state; SocketState m_state;
std::map<int64_t, SubmitResult> m_results; std::map<int64_t, SubmitResult> m_results;
Tls *m_tls;
uint64_t m_expire; uint64_t m_expire;
uint64_t m_jobs; uint64_t m_jobs;
uint64_t m_keepAlive; uint64_t m_keepAlive;
@ -148,4 +169,4 @@ private:
}; };
#endif /* __CLIENT_H__ */ #endif /* XMRIG_CLIENT_H */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -58,6 +59,7 @@ static inline char hf_bin2hex(unsigned char c)
Job::Job() : Job::Job() :
m_autoVariant(false),
m_nicehash(false), m_nicehash(false),
m_poolId(-2), m_poolId(-2),
m_threadId(-1), m_threadId(-1),
@ -69,7 +71,8 @@ Job::Job() :
} }
Job::Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId) : Job::Job(int poolId, bool nicehash, const xmrig::Algorithm &algorithm, const xmrig::Id &clientId) :
m_autoVariant(algorithm.variant() == xmrig::VARIANT_AUTO),
m_nicehash(nicehash), m_nicehash(nicehash),
m_poolId(poolId), m_poolId(poolId),
m_threadId(-1), m_threadId(-1),
@ -112,6 +115,10 @@ bool Job::setBlob(const char *blob)
m_nicehash = true; m_nicehash = true;
} }
if (m_autoVariant) {
m_algorithm.setVariant(variant());
}
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
memset(m_rawBlob, 0, sizeof(m_rawBlob)); memset(m_rawBlob, 0, sizeof(m_rawBlob));
memcpy(m_rawBlob, blob, m_size * 2); memcpy(m_rawBlob, blob, m_size * 2);
@ -163,6 +170,16 @@ bool Job::setTarget(const char *target)
} }
void Job::setAlgorithm(const char *algo)
{
m_algorithm.parseAlgorithm(algo);
if (m_algorithm.variant() == xmrig::VARIANT_AUTO) {
m_algorithm.setVariant(variant());
}
}
bool Job::fromHex(const char* in, unsigned int len, unsigned char* out) bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
{ {
bool error = false; bool error = false;
@ -207,3 +224,25 @@ bool Job::operator!=(const Job &other) const
{ {
return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0; return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0;
} }
xmrig::Variant Job::variant() const
{
using namespace xmrig;
switch (m_algorithm.algo()) {
case CRYPTONIGHT:
return (m_blob[0] >= 8) ? VARIANT_2 : VARIANT_1;
case CRYPTONIGHT_LITE:
return VARIANT_1;
case CRYPTONIGHT_HEAVY:
return VARIANT_0;
default:
break;
}
return m_algorithm.variant();
}

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,8 +23,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __JOB_H__ #ifndef XMRIG_JOB_H
#define __JOB_H__ #define XMRIG_JOB_H
#include <stddef.h> #include <stddef.h>
@ -38,11 +39,12 @@ class Job
{ {
public: public:
Job(); Job();
Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId); Job(int poolId, bool nicehash, const xmrig::Algorithm &algorithm, const xmrig::Id &clientId);
~Job(); ~Job();
bool setBlob(const char *blob); bool setBlob(const char *blob);
bool setTarget(const char *target); bool setTarget(const char *target);
void setAlgorithm(const char *algo);
inline bool isNicehash() const { return m_nicehash; } inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return m_size > 0 && m_diff > 0; } inline bool isValid() const { return m_size > 0 && m_diff > 0; }
@ -62,12 +64,8 @@ public:
inline void setClientId(const xmrig::Id &id) { m_clientId = id; } inline void setClientId(const xmrig::Id &id) { m_clientId = id; }
inline void setPoolId(int poolId) { m_poolId = poolId; } inline void setPoolId(int poolId) { m_poolId = poolId; }
inline void setThreadId(int threadId) { m_threadId = threadId; } inline void setThreadId(int threadId) { m_threadId = threadId; }
inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); }
inline void setVariant(int variant) { m_algorithm.parseVariant(variant); }
inline xmrig::Variant variant() const
{
return (m_algorithm.variant() == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_1 : xmrig::VARIANT_0) : m_algorithm.variant());
}
# ifdef XMRIG_PROXY_PROJECT # ifdef XMRIG_PROXY_PROJECT
inline char *rawBlob() { return m_rawBlob; } inline char *rawBlob() { return m_rawBlob; }
@ -87,6 +85,9 @@ public:
bool operator!=(const Job &other) const; bool operator!=(const Job &other) const;
private: private:
xmrig::Variant variant() const;
bool m_autoVariant;
bool m_nicehash; bool m_nicehash;
int m_poolId; int m_poolId;
int m_threadId; int m_threadId;
@ -104,4 +105,4 @@ private:
# endif # endif
}; };
#endif /* __JOB_H__ */ #endif /* XMRIG_JOB_H */

View file

@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -45,6 +46,7 @@
Pool::Pool() : Pool::Pool() :
m_nicehash(false), m_nicehash(false),
m_tls(false),
m_keepAlive(0), m_keepAlive(0),
m_port(kDefaultPort) m_port(kDefaultPort)
{ {
@ -64,6 +66,7 @@ Pool::Pool() :
*/ */
Pool::Pool(const char *url) : Pool::Pool(const char *url) :
m_nicehash(false), m_nicehash(false),
m_tls(false),
m_keepAlive(0), m_keepAlive(0),
m_port(kDefaultPort) m_port(kDefaultPort)
{ {
@ -71,8 +74,9 @@ Pool::Pool(const char *url) :
} }
Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash) : Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) :
m_nicehash(nicehash), m_nicehash(nicehash),
m_tls(tls),
m_keepAlive(keepAlive), m_keepAlive(keepAlive),
m_port(port), m_port(port),
m_host(host), m_host(host),
@ -91,27 +95,39 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo
bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const
{ {
if (m_algorithms.empty()) {
return true;
}
for (const auto &a : m_algorithms) { for (const auto &a : m_algorithms) {
if (algorithm == a) { if (algorithm == a) {
return true; return true;
} }
} }
# ifdef XMRIG_PROXY_PROJECT
if (m_algorithm.algo() == xmrig::CRYPTONIGHT && algorithm.algo() == xmrig::CRYPTONIGHT && m_algorithm.variant() == xmrig::VARIANT_XTL) {
return true;
}
# endif
return false; return false;
} }
bool Pool::isEqual(const Pool &other) const bool Pool::isEqual(const Pool &other) const
{ {
return (m_nicehash == other.m_nicehash return (m_nicehash == other.m_nicehash
&& m_keepAlive == other.m_keepAlive && m_tls == other.m_tls
&& m_port == other.m_port && m_keepAlive == other.m_keepAlive
&& m_algorithm == other.m_algorithm && m_port == other.m_port
&& m_host == other.m_host && m_algorithm == other.m_algorithm
&& m_password == other.m_password && m_fingerprint == other.m_fingerprint
&& m_rigId == other.m_rigId && m_host == other.m_host
&& m_url == other.m_url && m_password == other.m_password
&& m_user == other.m_user); && m_rigId == other.m_rigId
&& m_url == other.m_url
&& m_user == other.m_user);
} }
@ -123,7 +139,13 @@ bool Pool::parse(const char *url)
const char *base = url; const char *base = url;
if (p) { if (p) {
if (strncasecmp(url, "stratum+tcp://", 14)) { if (strncasecmp(url, "stratum+tcp://", 14) == 0) {
m_tls = false;
}
else if (strncasecmp(url, "stratum+ssl://", 14) == 0) {
m_tls = true;
}
else {
return false; return false;
} }
@ -201,6 +223,7 @@ rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const
case xmrig::VARIANT_AUTO: case xmrig::VARIANT_AUTO:
case xmrig::VARIANT_0: case xmrig::VARIANT_0:
case xmrig::VARIANT_1: case xmrig::VARIANT_1:
case xmrig::VARIANT_2:
obj.AddMember("variant", m_algorithm.variant(), allocator); obj.AddMember("variant", m_algorithm.variant(), allocator);
break; break;
@ -209,45 +232,33 @@ rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const
break; break;
} }
obj.AddMember("tls", isTLS(), allocator);
obj.AddMember("tls-fingerprint", fingerprint() ? Value(StringRef(fingerprint())).Move() : Value(kNullType).Move(), allocator);
return obj; return obj;
} }
void Pool::adjust(xmrig::Algo algorithm) void Pool::adjust(const xmrig::Algorithm &algorithm)
{ {
if (!isValid()) { if (!isValid()) {
return; return;
} }
if (!m_algorithm.isValid()) { if (!m_algorithm.isValid()) {
m_algorithm.setAlgo(algorithm); m_algorithm.setAlgo(algorithm.algo());
adjustVariant(algorithm.variant());
} }
if (strstr(m_host.data(), ".nicehash.com")) { rebuild();
m_keepAlive = false; }
m_nicehash = true;
if (strstr(m_host.data(), "cryptonightv7.")) {
m_algorithm.setVariant(xmrig::VARIANT_1);
}
}
if (strstr(m_host.data(), ".minergate.com")) { void Pool::setAlgo(const xmrig::Algorithm &algorithm)
m_keepAlive = false; {
m_algorithm.setVariant(xmrig::VARIANT_1); m_algorithm = algorithm;
}
m_algorithms.push_back(m_algorithm); rebuild();
# ifndef XMRIG_PROXY_PROJECT
if (m_algorithm.algo() != xmrig::CRYPTONIGHT_HEAVY) {
addVariant(xmrig::VARIANT_1);
addVariant(xmrig::VARIANT_0);
addVariant(xmrig::VARIANT_XTL);
addVariant(xmrig::VARIANT_IPBC);
addVariant(xmrig::VARIANT_AUTO);
}
# endif
} }
@ -299,3 +310,98 @@ void Pool::addVariant(xmrig::Variant variant)
m_algorithms.push_back(algorithm); m_algorithms.push_back(algorithm);
} }
void Pool::adjustVariant(const xmrig::Variant variantHint)
{
# ifndef XMRIG_PROXY_PROJECT
using namespace xmrig;
if (m_host.contains(".nicehash.com")) {
m_keepAlive = false;
m_nicehash = true;
bool valid = true;
if (m_host.contains("cryptonight.") && m_port == 3355) {
valid = m_algorithm.algo() == CRYPTONIGHT;
m_algorithm.setVariant(VARIANT_0);
}
else if (m_host.contains("cryptonightv7.") && m_port == 3363) {
valid = m_algorithm.algo() == CRYPTONIGHT;
m_algorithm.setVariant(VARIANT_1);
}
else if (m_host.contains("cryptonightheavy.") && m_port == 3364) {
valid = m_algorithm.algo() == CRYPTONIGHT_HEAVY;
m_algorithm.setVariant(VARIANT_0);
}
if (!valid) {
m_algorithm.setAlgo(INVALID_ALGO);
}
return;
}
if (m_host.contains(".minergate.com")) {
m_keepAlive = false;
bool valid = true;
m_algorithm.setVariant(VARIANT_1);
if (m_host.contains("xmr.pool.")) {
valid = m_algorithm.algo() == CRYPTONIGHT;
m_algorithm.setVariant(m_port == 45700 ? VARIANT_1 : VARIANT_0);
}
else if (m_host.contains("aeon.pool.") && m_port == 45690) {
valid = m_algorithm.algo() == CRYPTONIGHT_LITE;
m_algorithm.setVariant(VARIANT_1);
}
if (!valid) {
m_algorithm.setAlgo(INVALID_ALGO);
}
return;
}
if (variantHint != VARIANT_AUTO) {
m_algorithm.setVariant(variantHint);
return;
}
if (m_algorithm.variant() != VARIANT_AUTO) {
return;
}
if (m_algorithm.algo() == CRYPTONIGHT_HEAVY) {
m_algorithm.setVariant(VARIANT_0);
}
else if (m_algorithm.algo() == CRYPTONIGHT_LITE) {
m_algorithm.setVariant(VARIANT_1);
}
# endif
}
void Pool::rebuild()
{
m_algorithms.clear();
if (!m_algorithm.isValid()) {
return;
}
m_algorithms.push_back(m_algorithm);
# ifndef XMRIG_PROXY_PROJECT
addVariant(xmrig::VARIANT_2);
addVariant(xmrig::VARIANT_1);
addVariant(xmrig::VARIANT_0);
addVariant(xmrig::VARIANT_XTL);
addVariant(xmrig::VARIANT_TUBE);
addVariant(xmrig::VARIANT_MSR);
addVariant(xmrig::VARIANT_XHV);
addVariant(xmrig::VARIANT_XAO);
addVariant(xmrig::VARIANT_RTO);
addVariant(xmrig::VARIANT_AUTO);
# endif
}

View file

@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -21,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __POOL_H__ #ifndef XMRIG_POOL_H
#define __POOL_H__ #define XMRIG_POOL_H
#include <vector> #include <vector>
@ -44,30 +45,35 @@ public:
Pool(); Pool();
Pool(const char *url); Pool(const char *url);
Pool(const char *host, Pool(const char *host,
uint16_t port, uint16_t port,
const char *user = nullptr, const char *user = nullptr,
const char *password = nullptr, const char *password = nullptr,
int keepAlive = 0, int keepAlive = 0,
bool nicehash = false bool nicehash = false,
bool tls = false
); );
inline bool isNicehash() const { return m_nicehash; } inline bool isNicehash() const { return m_nicehash; }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline bool isTLS() const { return m_tls; }
inline const char *host() const { return m_host.data(); } inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } inline const char *fingerprint() const { return m_fingerprint.data(); }
inline const char *rigId() const { return m_rigId.data(); } inline const char *host() const { return m_host.data(); }
inline const char *url() const { return m_url.data(); } inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; }
inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } inline const char *rigId() const { return m_rigId.data(); }
inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } inline const char *url() const { return m_url.data(); }
inline const xmrig::Algorithms &algorithms() const { return m_algorithms; } inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; }
inline int keepAlive() const { return m_keepAlive; } inline const xmrig::Algorithm &algorithm() const { return m_algorithm; }
inline uint16_t port() const { return m_port; } inline const xmrig::Algorithms &algorithms() const { return m_algorithms; }
inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } inline int keepAlive() const { return m_keepAlive; }
inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline uint16_t port() const { return m_port; }
inline void setPassword(const char *password) { m_password = password; } inline void setFingerprint(const char *fingerprint) { m_fingerprint = fingerprint; }
inline void setRigId(const char *rigId) { m_rigId = rigId; } inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; }
inline void setUser(const char *user) { m_user = user; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline void setPassword(const char *password) { m_password = password; }
inline void setRigId(const char *rigId) { m_rigId = rigId; }
inline void setTLS(bool tls) { m_tls = tls; }
inline void setUser(const char *user) { m_user = user; }
inline xmrig::Algorithm &algorithm() { return m_algorithm; }
inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator!=(const Pool &other) const { return !isEqual(other); }
inline bool operator==(const Pool &other) const { return isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); }
@ -77,7 +83,8 @@ public:
bool parse(const char *url); bool parse(const char *url);
bool setUserpass(const char *userpass); bool setUserpass(const char *userpass);
rapidjson::Value toJSON(rapidjson::Document &doc) const; rapidjson::Value toJSON(rapidjson::Document &doc) const;
void adjust(xmrig::Algo algorithm); void adjust(const xmrig::Algorithm &algorithm);
void setAlgo(const xmrig::Algorithm &algorithm);
# ifdef APP_DEBUG # ifdef APP_DEBUG
void print() const; void print() const;
@ -86,12 +93,16 @@ public:
private: private:
bool parseIPv6(const char *addr); bool parseIPv6(const char *addr);
void addVariant(xmrig::Variant variant); void addVariant(xmrig::Variant variant);
void adjustVariant(const xmrig::Variant variantHint);
void rebuild();
bool m_nicehash; bool m_nicehash;
bool m_tls;
int m_keepAlive; int m_keepAlive;
uint16_t m_port; uint16_t m_port;
xmrig::Algorithm m_algorithm; xmrig::Algorithm m_algorithm;
xmrig::Algorithms m_algorithms; xmrig::Algorithms m_algorithms;
xmrig::c_str m_fingerprint;
xmrig::c_str m_host; xmrig::c_str m_host;
xmrig::c_str m_password; xmrig::c_str m_password;
xmrig::c_str m_rigId; xmrig::c_str m_rigId;
@ -102,4 +113,4 @@ private:
typedef std::vector<Pool> Pools; typedef std::vector<Pool> Pools;
#endif /* __POOL_H__ */ #endif /* XMRIG_POOL_H */

190
src/common/net/Tls.cpp Normal file
View file

@ -0,0 +1,190 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include "common/net/Client.h"
#include "common/net/Tls.h"
#include "common/log/Log.h"
#ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
Client::Tls::Tls(Client *client) :
m_ready(false),
m_buf(),
m_fingerprint(),
m_client(client),
m_ssl(nullptr)
{
m_ctx = SSL_CTX_new(SSLv23_method());
assert(m_ctx != nullptr);
if (!m_ctx) {
return;
}
m_writeBio = BIO_new(BIO_s_mem());
m_readBio = BIO_new(BIO_s_mem());
SSL_CTX_set_options(m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
}
Client::Tls::~Tls()
{
if (m_ctx) {
SSL_CTX_free(m_ctx);
}
if (m_ssl) {
SSL_free(m_ssl);
}
}
bool Client::Tls::handshake()
{
m_ssl = SSL_new(m_ctx);
assert(m_ssl != nullptr);
if (!m_ssl) {
return false;
}
SSL_set_connect_state(m_ssl);
SSL_set_bio(m_ssl, m_readBio, m_writeBio);
SSL_do_handshake(m_ssl);
return send();
}
bool Client::Tls::send(const char *data, size_t size)
{
SSL_write(m_ssl, data, size);
return send();
}
const char *Client::Tls::fingerprint() const
{
return m_ready ? m_fingerprint : nullptr;
}
const char *Client::Tls::version() const
{
return m_ready ? SSL_get_version(m_ssl) : nullptr;
}
void Client::Tls::read(const char *data, size_t size)
{
BIO_write(m_readBio, data, size);
if (!SSL_is_init_finished(m_ssl)) {
const int rc = SSL_connect(m_ssl);
if (rc < 0 && SSL_get_error(m_ssl, rc) == SSL_ERROR_WANT_READ) {
send();
} else if (rc == 1) {
X509 *cert = SSL_get_peer_certificate(m_ssl);
if (!verify(cert)) {
X509_free(cert);
m_client->close();
return;
}
X509_free(cert);
m_ready = true;
m_client->login();
}
return;
}
int bytes_read = 0;
while ((bytes_read = SSL_read(m_ssl, m_buf, sizeof(m_buf))) > 0) {
m_client->parse(m_buf, bytes_read);
}
}
bool Client::Tls::send()
{
return m_client->send(m_writeBio);
}
bool Client::Tls::verify(X509 *cert)
{
if (cert == nullptr) {
LOG_ERR("[%s] Failed to get server certificate", m_client->m_pool.url());
return false;
}
if (!verifyFingerprint(cert)) {
LOG_ERR("[%s] Failed to verify server certificate fingerprint", m_client->m_pool.url());
const char *fingerprint = m_client->m_pool.fingerprint();
if (strlen(m_fingerprint) == 64 && fingerprint != nullptr) {
LOG_ERR("\"%s\" was given", m_fingerprint);
LOG_ERR("\"%s\" was configured", fingerprint);
}
return false;
}
return true;
}
bool Client::Tls::verifyFingerprint(X509 *cert)
{
const EVP_MD *digest = EVP_get_digestbyname("sha256");
if (digest == nullptr) {
return false;
}
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int dlen;
if (X509_digest(cert, digest, md, &dlen) != 1) {
return false;
}
Job::toHex(md, 32, m_fingerprint);
const char *fingerprint = m_client->m_pool.fingerprint();
return fingerprint == nullptr || strncasecmp(m_fingerprint, fingerprint, 64) == 0;
}

62
src/common/net/Tls.h Normal file
View file

@ -0,0 +1,62 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_TLS_H
#define XMRIG_TLS_H
#include <openssl/ssl.h>
#include "common/net/Client.h"
class Client::Tls
{
public:
Tls(Client *client);
~Tls();
bool handshake();
bool send(const char *data, size_t size);
const char *fingerprint() const;
const char *version() const;
void read(const char *data, size_t size);
private:
bool send();
bool verify(X509 *cert);
bool verifyFingerprint(X509 *cert);
BIO *m_readBio;
BIO *m_writeBio;
bool m_ready;
char m_buf[1024 * 2];
char m_fingerprint[32 * 2 + 8];
Client *m_client;
SSL *m_ssl;
SSL_CTX *m_ctx;
};
#endif /* XMRIG_TLS_H */

View file

@ -22,10 +22,10 @@
*/ */
#include "common/interfaces/IStrategyListener.h"
#include "common/net/Client.h" #include "common/net/Client.h"
#include "common/net/strategies/FailoverStrategy.h" #include "common/net/strategies/FailoverStrategy.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "interfaces/IStrategyListener.h"
FailoverStrategy::FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : FailoverStrategy::FailoverStrategy(const std::vector<Pool> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :

View file

@ -28,9 +28,9 @@
#include <vector> #include <vector>
#include "common/interfaces/IClientListener.h"
#include "common/interfaces/IStrategy.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "interfaces/IClientListener.h"
#include "interfaces/IStrategy.h"
class Client; class Client;

View file

@ -22,10 +22,10 @@
*/ */
#include "common/interfaces/IStrategyListener.h"
#include "common/net/Client.h" #include "common/net/Client.h"
#include "common/net/strategies/SinglePoolStrategy.h" #include "common/net/strategies/SinglePoolStrategy.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "interfaces/IStrategyListener.h"
SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) : SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) :

View file

@ -25,8 +25,8 @@
#define __SINGLEPOOLSTRATEGY_H__ #define __SINGLEPOOLSTRATEGY_H__
#include "interfaces/IClientListener.h" #include "common/interfaces/IClientListener.h"
#include "interfaces/IStrategy.h" #include "common/interfaces/IStrategy.h"
class Client; class Client;

View file

@ -72,6 +72,12 @@ public:
} }
inline bool contains(const char *str) const
{
return strstr(m_data, str) != nullptr;
}
inline bool isNull() const { return m_data == nullptr; } inline bool isNull() const { return m_data == nullptr; }
inline const char *data() const { return m_data; } inline const char *data() const { return m_data; }
inline size_t size() const { return m_data == nullptr ? 0 : strlen(m_data); } inline size_t size() const { return m_data == nullptr ? 0 : strlen(m_data); }

View file

@ -0,0 +1,47 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_TIMESTAMP_H
#define XMRIG_TIMESTAMP_H
#include <chrono>
namespace xmrig {
static inline int64_t currentMSecsSinceEpoch()
{
using namespace std::chrono;
if (high_resolution_clock::is_steady) {
return time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
}
return time_point_cast<milliseconds>(steady_clock::now()).time_since_epoch().count();
}
} /* namespace xmrig */
#endif /* XMRIG_TIMESTAMP_H */

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __XMRIG_H__ #ifndef XMRIG_XMRIG_H
#define __XMRIG_H__ #define XMRIG_XMRIG_H
namespace xmrig namespace xmrig
@ -33,7 +33,7 @@ enum Algo {
INVALID_ALGO = -1, INVALID_ALGO = -1,
CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT, /* CryptoNight (Monero) */
CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */ CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (RYO) */
}; };
@ -61,8 +61,20 @@ enum Variant {
VARIANT_AUTO = -1, // Autodetect VARIANT_AUTO = -1, // Autodetect
VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy
VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7
VARIANT_IPBC = 2, // CryptoNight Lite variant 1 with XOR (IPBC only) VARIANT_TUBE = 2, // Modified CryptoNight-Heavy (TUBE only)
VARIANT_XTL = 3 // CryptoNight variant 1 (Stellite only) VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only)
VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only)
VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only)
VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only)
VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only)
VARIANT_2 = 8, // CryptoNight variant 2
VARIANT_MAX
};
enum AlgoVerify {
VERIFY_HW_AES = 1,
VERIFY_SOFT_AES = 2
}; };
@ -73,7 +85,25 @@ enum AesMode {
}; };
enum OclVendor {
OCL_VENDOR_UNKNOWN = -2,
OCL_VENDOR_MANUAL = -1,
OCL_VENDOR_AMD = 0,
OCL_VENDOR_NVIDIA = 1,
OCL_VENDOR_INTEL = 2
};
enum Assembly {
ASM_NONE,
ASM_AUTO,
ASM_INTEL,
ASM_RYZEN,
ASM_MAX
};
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __XMRIG_H__ */ #endif /* XMRIG_XMRIG_H */

View file

@ -1,34 +1,43 @@
{ {
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite "algo": "cryptonight",
"av": 0, // algorithm variation, 0 auto select
"background": false, // true to run the miner in the background
"colors": true, // false to disable colored output
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
"donate-level": 5, // donate level, mininum 1%
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
"print-time": 60, // print hashrate report every N seconds
"retries": 5, // number of times to retry before switch to backup server
"retry-pause": 5, // time to pause between retries
"safe": false, // true to safe adjust threads and av settings for current CPU
"syslog": false, // use system log for output messages
"threads": null, // number of miner threads
"pools": [
{
"url": "failover.xmrig.com:443", // URL of mining server
"user": "YOUR_WALLET", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false, // enable nicehash/xmrig-proxy support
"variant": -1 // algorithm PoW variant
}
],
"api": { "api": {
"port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API "port": 0,
"access-token": null, // access token for API "access-token": null,
"worker-id": null, // custom worker-id for API "id": null,
"worker-id": null,
"ipv6": false, "ipv6": false,
"restricted": true "restricted": true
} },
"asm": true,
"autosave": true,
"av": 0,
"background": false,
"colors": true,
"cpu-affinity": null,
"cpu-priority": null,
"donate-level": 5,
"huge-pages": true,
"hw-aes": null,
"log-file": null,
"max-cpu-usage": 75,
"pools": [
{
"url": "donate.v2.xmrig.com:3333",
"user": "YOUR_WALLET_ADDRESS",
"pass": "x",
"rig-id": null,
"nicehash": false,
"keepalive": false,
"variant": -1,
"tls": false,
"tls-fingerprint": null
}
],
"print-time": 60,
"retries": 5,
"retry-pause": 5,
"safe": false,
"threads": null,
"user-agent": null,
"watch": false
} }

View file

@ -27,9 +27,10 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/cpu/Cpu.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "Cpu.h" #include "crypto/Asm.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
@ -43,20 +44,16 @@ static char affinity_tmp[20] = { 0 };
xmrig::Config::Config() : xmrig::CommonConfig(), xmrig::Config::Config() : xmrig::CommonConfig(),
m_aesMode(AES_AUTO), m_aesMode(AES_AUTO),
m_algoVariant(AV_AUTO), m_algoVariant(AV_AUTO),
m_dryRun(false), m_assembly(ASM_AUTO),
m_hugePages(true), m_hugePages(true),
m_safe(false), m_safe(false),
m_shouldSave(false),
m_maxCpuUsage(75), m_maxCpuUsage(75),
m_priority(-1) m_priority(-1)
{ {
} }
xmrig::Config::~Config()
{
}
bool xmrig::Config::reload(const char *json) bool xmrig::Config::reload(const char *json)
{ {
return xmrig::ConfigLoader::reload(this, json); return xmrig::ConfigLoader::reload(this, json);
@ -76,11 +73,17 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
Value api(kObjectType); Value api(kObjectType);
api.AddMember("port", apiPort(), allocator); api.AddMember("port", apiPort(), allocator);
api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator); api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator);
api.AddMember("id", apiId() ? Value(StringRef(apiId())).Move() : Value(kNullType).Move(), allocator);
api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator); api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator);
api.AddMember("ipv6", isApiIPv6(), allocator); api.AddMember("ipv6", isApiIPv6(), allocator);
api.AddMember("restricted", isApiRestricted(), allocator); api.AddMember("restricted", isApiRestricted(), allocator);
doc.AddMember("api", api, allocator); doc.AddMember("api", api, allocator);
# ifndef XMRIG_NO_ASM
doc.AddMember("asm", Asm::toJSON(m_assembly), allocator);
# endif
doc.AddMember("autosave", isAutoSave(), allocator);
doc.AddMember("av", algoVariant(), allocator); doc.AddMember("av", algoVariant(), allocator);
doc.AddMember("background", isBackground(), allocator); doc.AddMember("background", isBackground(), allocator);
doc.AddMember("colors", isColors(), allocator); doc.AddMember("colors", isColors(), allocator);
@ -112,17 +115,17 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("retry-pause", retryPause(), allocator);
doc.AddMember("safe", m_safe, allocator); doc.AddMember("safe", m_safe, allocator);
if (threadsMode() == Advanced) { if (threadsMode() != Simple) {
Value threads(kArrayType); Value threads(kArrayType);
for (const IThread *thread : m_threads.list) { for (const IThread *thread : m_threads.list) {
threads.PushBack(thread->toConfig(doc), doc.GetAllocator()); threads.PushBack(thread->toConfig(doc), allocator);
} }
doc.AddMember("threads", threads, allocator); doc.AddMember("threads", threads, allocator);
} }
else { else {
doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator); doc.AddMember("threads", threadsCount(), allocator);
} }
doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator);
@ -153,7 +156,7 @@ bool xmrig::Config::finalize()
if (!m_threads.cpu.empty()) { if (!m_threads.cpu.empty()) {
m_threads.mode = Advanced; m_threads.mode = Advanced;
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
for (size_t i = 0; i < m_threads.cpu.size(); ++i) { for (size_t i = 0; i < m_threads.cpu.size(); ++i) {
m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES));
@ -162,25 +165,26 @@ bool xmrig::Config::finalize()
return true; return true;
} }
m_algoVariant = getAlgoVariant(); const AlgoVariant av = getAlgoVariant();
m_threads.mode = m_threads.count ? Simple : Automatic; m_threads.mode = m_threads.count ? Simple : Automatic;
const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm.algo()) / 1024; const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024;
if (!m_threads.count) { if (!m_threads.count) {
m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage);
} }
else if (m_safe) { else if (m_safe) {
const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage);
if (m_threads.count > count) { if (m_threads.count > count) {
m_threads.count = count; m_threads.count = count;
} }
} }
for (size_t i = 0; i < m_threads.count; ++i) { for (size_t i = 0; i < m_threads.count; ++i) {
m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), m_algoVariant, m_threads.mask, m_priority)); m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly));
} }
m_shouldSave = m_threads.mode == Automatic;
return true; return true;
} }
@ -192,22 +196,24 @@ bool xmrig::Config::parseBoolean(int key, bool enable)
} }
switch (key) { switch (key) {
case IConfig::SafeKey: /* --safe */ case SafeKey: /* --safe */
m_safe = enable; m_safe = enable;
break; break;
case IConfig::HugePagesKey: /* --no-huge-pages */ case HugePagesKey: /* --no-huge-pages */
m_hugePages = enable; m_hugePages = enable;
break; break;
case IConfig::DryRunKey: /* --dry-run */ case HardwareAESKey: /* hw-aes config only */
m_dryRun = enable;
break;
case IConfig::HardwareAESKey: /* hw-aes config only */
m_aesMode = enable ? AES_HW : AES_SOFT; m_aesMode = enable ? AES_HW : AES_SOFT;
break; break;
# ifndef XMRIG_NO_ASM
case AssemblyKey:
m_assembly = Asm::parse(enable);
break;
# endif
default: default:
break; break;
} }
@ -223,32 +229,37 @@ bool xmrig::Config::parseString(int key, const char *arg)
} }
switch (key) { switch (key) {
case xmrig::IConfig::AVKey: /* --av */ case AVKey: /* --av */
case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ case MaxCPUUsageKey: /* --max-cpu-usage */
case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */ case CPUPriorityKey: /* --cpu-priority */
return parseUint64(key, strtol(arg, nullptr, 10)); return parseUint64(key, strtol(arg, nullptr, 10));
case xmrig::IConfig::SafeKey: /* --safe */ case SafeKey: /* --safe */
case xmrig::IConfig::DryRunKey: /* --dry-run */
return parseBoolean(key, true); return parseBoolean(key, true);
case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */ case HugePagesKey: /* --no-huge-pages */
return parseBoolean(key, false); return parseBoolean(key, false);
case xmrig::IConfig::ThreadsKey: /* --threads */ case ThreadsKey: /* --threads */
if (strncmp(arg, "all", 3) == 0) { if (strncmp(arg, "all", 3) == 0) {
m_threads.count = Cpu::threads(); m_threads.count = Cpu::info()->threads();
return true; return true;
} }
return parseUint64(key, strtol(arg, nullptr, 10)); return parseUint64(key, strtol(arg, nullptr, 10));
case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ case CPUAffinityKey: /* --cpu-affinity */
{ {
const char *p = strstr(arg, "0x"); const char *p = strstr(arg, "0x");
return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
} }
# ifndef XMRIG_NO_ASM
case AssemblyKey: /* --asm */
m_assembly = Asm::parse(arg);
break;
# endif
default: default:
break; break;
} }
@ -264,7 +275,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
} }
switch (key) { switch (key) {
case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ case CPUAffinityKey: /* --cpu-affinity */
if (arg) { if (arg) {
m_threads.mask = arg; m_threads.mask = arg;
} }
@ -303,25 +314,25 @@ void xmrig::Config::parseJSON(const rapidjson::Document &doc)
bool xmrig::Config::parseInt(int key, int arg) bool xmrig::Config::parseInt(int key, int arg)
{ {
switch (key) { switch (key) {
case xmrig::IConfig::ThreadsKey: /* --threads */ case ThreadsKey: /* --threads */
if (arg >= 0 && arg < 1024) { if (arg >= 0 && arg < 1024) {
m_threads.count = arg; m_threads.count = arg;
} }
break; break;
case xmrig::IConfig::AVKey: /* --av */ case AVKey: /* --av */
if (arg >= AV_AUTO && arg < AV_MAX) { if (arg >= AV_AUTO && arg < AV_MAX) {
m_algoVariant = static_cast<AlgoVariant>(arg); m_algoVariant = static_cast<AlgoVariant>(arg);
} }
break; break;
case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ case MaxCPUUsageKey: /* --max-cpu-usage */
if (m_maxCpuUsage > 0 && arg <= 100) { if (m_maxCpuUsage > 0 && arg <= 100) {
m_maxCpuUsage = arg; m_maxCpuUsage = arg;
} }
break; break;
case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */ case CPUPriorityKey: /* --cpu-priority */
if (arg >= 0 && arg <= 5) { if (arg >= 0 && arg <= 5) {
m_priority = arg; m_priority = arg;
} }
@ -344,10 +355,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
# endif # endif
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; return Cpu::info()->hasAES() ? AV_SINGLE : AV_SINGLE_SOFT;
} }
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2); return static_cast<AlgoVariant>(m_algoVariant + 2);
} }
@ -359,10 +370,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const
{ {
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) {
return Cpu::hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; return Cpu::info()->hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT;
} }
if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) {
return static_cast<AlgoVariant>(m_algoVariant + 2); return static_cast<AlgoVariant>(m_algoVariant + 2);
} }

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CONFIG_H__ #ifndef XMRIG_CONFIG_H
#define __CONFIG_H__ #define XMRIG_CONFIG_H
#include <stdint.h> #include <stdint.h>
@ -69,7 +69,6 @@ public:
Config(); Config();
~Config();
bool reload(const char *json); bool reload(const char *json);
@ -77,8 +76,9 @@ public:
inline AesMode aesMode() const { return m_aesMode; } inline AesMode aesMode() const { return m_aesMode; }
inline AlgoVariant algoVariant() const { return m_algoVariant; } inline AlgoVariant algoVariant() const { return m_algoVariant; }
inline bool isDryRun() const { return m_dryRun; } inline Assembly assembly() const { return m_assembly; }
inline bool isHugePages() const { return m_hugePages; } inline bool isHugePages() const { return m_hugePages; }
inline bool isShouldSave() const { return m_shouldSave && isAutoSave(); }
inline const std::vector<IThread *> &threads() const { return m_threads.list; } inline const std::vector<IThread *> &threads() const { return m_threads.list; }
inline int priority() const { return m_priority; } inline int priority() const { return m_priority; }
inline int threadsCount() const { return m_threads.list.size(); } inline int threadsCount() const { return m_threads.list.size(); }
@ -117,9 +117,10 @@ private:
AesMode m_aesMode; AesMode m_aesMode;
AlgoVariant m_algoVariant; AlgoVariant m_algoVariant;
bool m_dryRun; Assembly m_assembly;
bool m_hugePages; bool m_hugePages;
bool m_safe; bool m_safe;
bool m_shouldSave;
int m_maxCpuUsage; int m_maxCpuUsage;
int m_priority; int m_priority;
Threads m_threads; Threads m_threads;
@ -128,4 +129,4 @@ private:
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __CONFIG_H__ */ #endif /* XMRIG_CONFIG_H */

View file

@ -24,8 +24,8 @@
#define __CONFIGCREATOR_H__ #define __CONFIGCREATOR_H__
#include "common/interfaces/IConfigCreator.h"
#include "core/Config.h" #include "core/Config.h"
#include "interfaces/IConfigCreator.h"
namespace xmrig { namespace xmrig {

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CONFIGLOADER_PLATFORM_H__ #ifndef XMRIG_CONFIGLOADER_PLATFORM_H
#define __CONFIGLOADER_PLATFORM_H__ #define XMRIG_CONFIGLOADER_PLATFORM_H
#ifdef _MSC_VER #ifdef _MSC_VER
@ -33,8 +33,8 @@
#endif #endif
#include "common/interfaces/IConfig.h"
#include "version.h" #include "version.h"
#include "interfaces/IConfig.h"
namespace xmrig { namespace xmrig {
@ -61,7 +61,10 @@ Options:\n\
--rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\ --rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\
-t, --threads=N number of miner threads\n\ -t, --threads=N number of miner threads\n\
-v, --av=N algorithm variation, 0 auto select\n\ -v, --av=N algorithm variation, 0 auto select\n\
-k, --keepalive send keepalived for prevent timeout (need pool support)\n\ -k, --keepalive send keepalived packet for prevent timeout (needs pool support)\n\
--nicehash enable nicehash.com support\n\
--tls enable SSL/TLS support (needs pool support)\n\
--tls-fingerprint=F pool TLS certificate fingerprint, if set enable strict certificate pinning\n\
-r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ -r, --retries=N number of times to retry before switch to backup server (default: 5)\n\
-R, --retry-pause=N time to pause between retries (default: 5)\n\ -R, --retry-pause=N time to pause between retries (default: 5)\n\
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\
@ -81,13 +84,15 @@ Options:\n\
"\ "\
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\
--safe safe adjust threads and av settings for current CPU\n\ --safe safe adjust threads and av settings for current CPU\n\
--nicehash enable nicehash/xmrig-proxy support\n\ --asm=ASM ASM code for cn/2, possible values: auto, none, intel, ryzen.\n\
--print-time=N print hashrate report every N seconds\n\ --print-time=N print hashrate report every N seconds\n\
--api-port=N port for the miner API\n\ --api-port=N port for the miner API\n\
--api-access-token=T access token for API\n\ --api-access-token=T access token for API\n\
--api-worker-id=ID custom worker-id for API\n\ --api-worker-id=ID custom worker-id for API\n\
--api-id=ID custom instance ID for API\n\
--api-ipv6 enable IPv6 support for API\n\ --api-ipv6 enable IPv6 support for API\n\
--api-no-restricted enable full remote access (only if API token set)\n\ --api-no-restricted enable full remote access (only if API token set)\n\
--dry-run test configuration and exit\n\
-h, --help display this help and exit\n\ -h, --help display this help and exit\n\
-V, --version output version information and exit\n\ -V, --version output version information and exit\n\
"; ";
@ -101,6 +106,7 @@ static struct option const options[] = {
{ "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, { "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey },
{ "api-port", 1, nullptr, xmrig::IConfig::ApiPort }, { "api-port", 1, nullptr, xmrig::IConfig::ApiPort },
{ "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, { "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "api-id", 1, nullptr, xmrig::IConfig::ApiIdKey },
{ "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ "av", 1, nullptr, xmrig::IConfig::AVKey }, { "av", 1, nullptr, xmrig::IConfig::AVKey },
@ -130,8 +136,11 @@ static struct option const options[] = {
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
{ "tls", 0, nullptr, xmrig::IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey },
{ "version", 0, nullptr, xmrig::IConfig::VersionKey }, { "version", 0, nullptr, xmrig::IConfig::VersionKey },
{ 0, 0, 0, 0 } { "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ nullptr, 0, nullptr, 0 }
}; };
@ -155,20 +164,24 @@ static struct option const config_options[] = {
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey }, { "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey },
{ 0, 0, 0, 0 } { "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ "autosave", 0, nullptr, xmrig::IConfig::AutoSaveKey },
{ nullptr, 0, nullptr, 0 }
}; };
static struct option const pool_options[] = { static struct option const pool_options[] = {
{ "url", 1, nullptr, xmrig::IConfig::UrlKey }, { "url", 1, nullptr, xmrig::IConfig::UrlKey },
{ "pass", 1, nullptr, xmrig::IConfig::PasswordKey }, { "pass", 1, nullptr, xmrig::IConfig::PasswordKey },
{ "user", 1, nullptr, xmrig::IConfig::UserKey }, { "user", 1, nullptr, xmrig::IConfig::UserKey },
{ "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey },
{ "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey },
{ "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey },
{ "variant", 1, nullptr, xmrig::IConfig::VariantKey }, { "variant", 1, nullptr, xmrig::IConfig::VariantKey },
{ "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey },
{ 0, 0, 0, 0 } { "tls", 0, nullptr, xmrig::IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey },
{ nullptr, 0, nullptr, 0 }
}; };
@ -178,10 +191,11 @@ static struct option const api_options[] = {
{ "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, { "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey },
{ "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key },
{ "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey },
{ 0, 0, 0, 0 } { "id", 1, nullptr, xmrig::IConfig::ApiIdKey },
{ nullptr, 0, nullptr, 0 }
}; };
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __CONFIGLOADER_PLATFORM_H__ */ #endif /* XMRIG_CONFIGLOADER_PLATFORM_H */

View file

@ -26,14 +26,14 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/cpu/Cpu.h"
#include "common/interfaces/IControllerListener.h"
#include "common/log/ConsoleLog.h" #include "common/log/ConsoleLog.h"
#include "common/log/FileLog.h" #include "common/log/FileLog.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "interfaces/IControllerListener.h"
#include "net/Network.h" #include "net/Network.h"
@ -110,7 +110,7 @@ int xmrig::Controller::init(int argc, char **argv)
} }
if (config()->logFile()) { if (config()->logFile()) {
Log::add(new FileLog(config()->logFile())); Log::add(new FileLog(this, config()->logFile()));
} }
# ifdef HAVE_SYSLOG_H # ifdef HAVE_SYSLOG_H

View file

@ -25,7 +25,7 @@
#define __CONTROLLER_H__ #define __CONTROLLER_H__
#include "interfaces/IWatcherListener.h" #include "common/interfaces/IWatcherListener.h"
class Network; class Network;

View file

@ -21,65 +21,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <libcpuid.h> #include <libcpuid.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <thread>
#include "Cpu.h" #include "core/cpu/AdvancedCpuInfo.h"
bool Cpu::m_l2_exclusive = false; xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
char Cpu::m_brand[64] = { 0 }; m_assembly(ASM_NONE),
int Cpu::m_flags = 0; m_aes(false),
int Cpu::m_l2_cache = 0; m_L2_exclusive(false),
int Cpu::m_l3_cache = 0; m_brand(),
int Cpu::m_sockets = 1; m_cores(0),
int Cpu::m_totalCores = 0; m_L2(0),
size_t Cpu::m_totalThreads = 0; m_L3(0),
m_sockets(1),
m_threads(std::thread::hardware_concurrency())
size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage)
{
if (m_totalThreads == 1) {
return 1;
}
size_t cache = 0;
if (m_l3_cache) {
cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache;
}
else {
cache = m_l2_cache;
}
size_t count = 0;
if (cache) {
count = cache / size;
if (cache % size >= size / 2) {
count++;
}
}
else {
count = m_totalThreads / 2;
}
if (count > m_totalThreads) {
count = m_totalThreads;
}
if (((float) count / m_totalThreads * 100) > maxCpuUsage) {
count = (int) ceil((float) m_totalThreads * (maxCpuUsage / 100.0));
}
return count < 1 ? 1 : count;
}
void Cpu::initCommon()
{ {
struct cpu_raw_data_t raw = { 0 }; struct cpu_raw_data_t raw = { 0 };
struct cpu_id_t data = { 0 }; struct cpu_id_t data = { 0 };
@ -87,42 +47,78 @@ void Cpu::initCommon()
cpuid_get_raw_data(&raw); cpuid_get_raw_data(&raw);
cpu_identify(&raw, &data); cpu_identify(&raw, &data);
strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1); strncpy(m_brand, data.brand_str, sizeof(m_brand));
m_totalThreads = data.total_logical_cpus;
m_sockets = m_totalThreads / data.num_logical_cpus;
m_sockets = threads() / data.num_logical_cpus;
if (m_sockets == 0) { if (m_sockets == 0) {
m_sockets = 1; m_sockets = 1;
} }
m_totalCores = data.num_cores * m_sockets; m_cores = data.num_cores * m_sockets;
m_l3_cache = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0;
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) { if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) {
m_l2_cache = data.l2_cache * (m_totalCores / 2) * m_sockets; m_L2 = data.l2_cache * (cores() / 2) * m_sockets;
m_l2_exclusive = true; m_L2_exclusive = true;
} }
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue // Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue
// These processors have L2 cache shared by 2 cores. // These processors have L2 cache shared by 2 cores.
else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) { else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) {
int l2_count_per_socket = m_totalCores > 1 ? m_totalCores / 2 : 1; int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;
} }
else{ else{
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0; m_L2 = data.l2_cache > 0 ? data.l2_cache * cores() * m_sockets : 0;
} }
# if defined(__x86_64__) || defined(_M_AMD64)
m_flags |= X86_64;
# endif
if (data.flags[CPU_FEATURE_AES]) { if (data.flags[CPU_FEATURE_AES]) {
m_flags |= AES; m_aes = true;
}
if (data.flags[CPU_FEATURE_BMI2]) { if (data.vendor == VENDOR_AMD) {
m_flags |= BMI2; m_assembly = ASM_RYZEN;
}
else if (data.vendor == VENDOR_INTEL) {
m_assembly = ASM_INTEL;
}
} }
} }
size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
if (threads() == 1) {
return 1;
}
size_t cache = 0;
if (m_L3) {
cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3;
}
else {
cache = m_L2;
}
size_t count = 0;
if (cache) {
count = cache / memSize;
if (cache % memSize >= memSize / 2) {
count++;
}
}
else {
count = threads() / 2;
}
if (count > (size_t) threads()) {
count = threads();
}
if (((float) count / threads() * 100) > maxCpuUsage) {
count = (int) ceil((float) threads() * (maxCpuUsage / 100.0));
}
return count < 1 ? 1 : count;
}

View file

@ -0,0 +1,75 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ADVANCEDCPUINFO_H
#define XMRIG_ADVANCEDCPUINFO_H
#include "common/interfaces/ICpuInfo.h"
namespace xmrig {
class AdvancedCpuInfo : public ICpuInfo
{
public:
AdvancedCpuInfo();
protected:
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
inline Assembly assembly() const override { return m_assembly; }
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 m_cores; }
inline int32_t L2() const override { return m_L2; }
inline int32_t L3() const override { return m_L3; }
inline int32_t nodes() const override { return -1; }
inline int32_t sockets() const override { return m_sockets; }
inline int32_t threads() const override { return m_threads; }
# if defined(__x86_64__) || defined(_M_AMD64)
inline bool isX64() const override { return true; }
# else
inline bool isX64() const override { return false; }
# endif
private:
Assembly m_assembly;
bool m_aes;
bool m_L2_exclusive;
char m_brand[64];
int32_t m_cores;
int32_t m_L2;
int32_t m_L3;
int32_t m_sockets;
int32_t m_threads;
};
} /* namespace xmrig */
#endif /* XMRIG_ADVANCEDCPUINFO_H */

View file

@ -22,20 +22,40 @@
*/ */
#include <windows.h> #include <assert.h>
#include "Cpu.h" #include "common/cpu/Cpu.h"
void Cpu::init() #ifndef XMRIG_NO_LIBCPUID
# include "core/cpu/AdvancedCpuInfo.h"
#endif
static xmrig::ICpuInfo *cpuInfo = nullptr;
xmrig::ICpuInfo *xmrig::Cpu::info()
{ {
# ifdef XMRIG_NO_LIBCPUID assert(cpuInfo != nullptr);
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
m_totalThreads = sysinfo.dwNumberOfProcessors; return cpuInfo;
# endif }
initCommon();
void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
cpuInfo = new AdvancedCpuInfo();
}
void xmrig::Cpu::release()
{
assert(cpuInfo != nullptr);
delete cpuInfo;
cpuInfo = nullptr;
} }

100
src/crypto/Asm.cpp Normal file
View file

@ -0,0 +1,100 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <string.h>
#ifdef _MSC_VER
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
#endif
#include "crypto/Asm.h"
#include "rapidjson/document.h"
static const char *asmNames[] = {
"none",
"auto",
"intel",
"ryzen"
};
xmrig::Assembly xmrig::Asm::parse(const char *assembly, Assembly defaultValue)
{
constexpr size_t const size = sizeof(asmNames) / sizeof((asmNames)[0]);
assert(assembly != nullptr);
assert(ASM_MAX == size);
if (assembly == nullptr) {
return defaultValue;
}
for (size_t i = 0; i < size; i++) {
if (strcasecmp(assembly, asmNames[i]) == 0) {
return static_cast<Assembly>(i);
}
}
return defaultValue;
}
xmrig::Assembly xmrig::Asm::parse(const rapidjson::Value &value, Assembly defaultValue)
{
if (value.IsBool()) {
return parse(value.GetBool());
}
if (value.IsString()) {
return parse(value.GetString(), defaultValue);
}
return defaultValue;
}
const char *xmrig::Asm::toString(Assembly assembly)
{
return asmNames[assembly];
}
rapidjson::Value xmrig::Asm::toJSON(Assembly assembly)
{
using namespace rapidjson;
if (assembly == ASM_NONE) {
return Value(false);
}
if (assembly == ASM_AUTO) {
return Value(true);
}
return Value(StringRef(toString(assembly)));
}

50
src/crypto/Asm.h Normal file
View file

@ -0,0 +1,50 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_ASM_H
#define XMRIG_ASM_H
#include "common/xmrig.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Asm
{
public:
static Assembly parse(const char *assembly, Assembly defaultValue = ASM_AUTO);
static Assembly parse(const rapidjson::Value &value, Assembly defaultValue = ASM_AUTO);
static const char *toString(Assembly assembly);
static rapidjson::Value toJSON(Assembly assembly);
inline static Assembly parse(bool enable) { return enable ? ASM_AUTO : ASM_NONE; }
};
} /* namespace xmrig */
#endif /* XMRIG_ASM_H */

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_H__ #ifndef XMRIG_CRYPTONIGHT_H
#define __CRYPTONIGHT_H__ #define XMRIG_CRYPTONIGHT_H
#include <stddef.h> #include <stddef.h>
@ -31,9 +31,9 @@
struct cryptonight_ctx { struct cryptonight_ctx {
alignas(16) uint8_t state[200]; alignas(16) uint8_t state[224];
alignas(16) uint8_t* memory; alignas(16) uint8_t *memory;
}; };
#endif /* __CRYPTONIGHT_H__ */ #endif /* XMRIG_CRYPTONIGHT_H */

View file

@ -7,6 +7,7 @@
* Copyright 2016 Imran Yusuff <https://github.com/imranyusuff> * Copyright 2016 Imran Yusuff <https://github.com/imranyusuff>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -23,10 +24,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_ARM_H__ #ifndef XMRIG_CRYPTONIGHT_ARM_H
#define __CRYPTONIGHT_ARM_H__ #define XMRIG_CRYPTONIGHT_ARM_H
#include "common/crypto/keccak.h"
#include "common/utils/mm_malloc.h" #include "common/utils/mm_malloc.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
@ -36,7 +38,6 @@
extern "C" extern "C"
{ {
#include "crypto/c_keccak.h"
#include "crypto/c_groestl.h" #include "crypto/c_groestl.h"
#include "crypto/c_blake256.h" #include "crypto/c_blake256.h"
#include "crypto/c_jh.h" #include "crypto/c_jh.h"
@ -73,7 +74,7 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64
} }
#ifdef XMRIG_ARMv8 #if __ARM_FEATURE_CRYPTO
static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey)
{ {
alignas(16) const __m128i zero = { 0 }; alignas(16) const __m128i zero = { 0 };
@ -82,6 +83,8 @@ static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v,
#else #else
static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey)
{ {
alignas(16) const __m128i zero = { 0 };
return zero;
} }
#endif #endif
@ -93,10 +96,7 @@ static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i
} }
#define EXTRACT64(X) _mm_cvtsi128_si64(X) #if defined (__arm64__) || defined (__aarch64__)
#if defined(XMRIG_ARMv8)
static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi) static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
{ {
unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b; unsigned __int128 r = (unsigned __int128) a * (unsigned __int128) b;
@ -380,125 +380,190 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
} }
static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key)
{ {
mem_out[0] = EXTRACT64(tmp); alignas(16) uint32_t k[4];
alignas(16) uint32_t x[4];
uint64_t vh = vgetq_lane_u64(tmp, 1); _mm_store_si128((__m128i*) k, key);
_mm_store_si128((__m128i*) x, _mm_xor_si128(in, _mm_set_epi64x(0xffffffffffffffff, 0xffffffffffffffff)));
uint8_t x = vh >> 24; #define BYTE(p, i) ((unsigned char*)&x[p])[i]
static const uint16_t table = 0x7531; k[0] ^= saes_table[0][BYTE(0, 0)] ^ saes_table[1][BYTE(1, 1)] ^ saes_table[2][BYTE(2, 2)] ^ saes_table[3][BYTE(3, 3)];
const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1; x[0] ^= k[0];
vh ^= ((table >> index) & 0x3) << 28; k[1] ^= saes_table[0][BYTE(1, 0)] ^ saes_table[1][BYTE(2, 1)] ^ saes_table[2][BYTE(3, 2)] ^ saes_table[3][BYTE(0, 3)];
x[1] ^= k[1];
k[2] ^= saes_table[0][BYTE(2, 0)] ^ saes_table[1][BYTE(3, 1)] ^ saes_table[2][BYTE(0, 2)] ^ saes_table[3][BYTE(1, 3)];
x[2] ^= k[2];
k[3] ^= saes_table[0][BYTE(3, 0)] ^ saes_table[1][BYTE(0, 1)] ^ saes_table[2][BYTE(1, 2)] ^ saes_table[3][BYTE(2, 3)];
#undef BYTE
mem_out[1] = vh; return _mm_load_si128((__m128i*)k);
} }
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT> template<xmrig::Variant VARIANT>
static inline void cryptonight_monero_tweak(const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i cx)
{
uint64_t* mem_out = (uint64_t*)&l[idx];
if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1);
_mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx));
} else {
__m128i tmp = _mm_xor_si128(bx0, cx);
mem_out[0] = _mm_cvtsi128_si64(tmp);
uint64_t vh = vgetq_lane_u64(tmp, 1);
uint8_t x = vh >> 24;
static const uint16_t table = 0x7531;
const uint8_t index = (((x >> (VARIANT == xmrig::VARIANT_XTL ? 4 : 3)) & 6) | (x & 1)) << 1;
vh ^= ((table >> index) & 0x3) << 28;
mem_out[1] = vh;
}
}
template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx)
{ {
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (VARIANT > 0 && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 32); memset(output, 0, 32);
return; return;
} }
keccak(input, (int) size, ctx[0]->state, 200); xmrig::keccak(input, size, ctx[0]->state);
VARIANT1_INIT(0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory);
const uint8_t* l0 = ctx[0]->memory; const uint8_t* l0 = ctx[0]->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state); uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
VARIANT1_INIT(0);
VARIANT2_INIT(0);
uint64_t al0 = h0[0] ^ h0[4]; uint64_t al0 = h0[0] ^ h0[4];
uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah0 = h0[1] ^ h0[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]);
uint64_t idx0 = h0[0] ^ h0[4]; uint64_t idx0 = al0;
for (size_t i = 0; i < ITERATIONS; i++) { for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx; __m128i cx;
if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) {
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
}
if (SOFT_AES) { const __m128i ax0 = _mm_set_epi64x(ah0, al0);
cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0)); if (VARIANT == xmrig::VARIANT_TUBE) {
cx = aes_round_tweak_div(cx, ax0);
}
else if (SOFT_AES) {
cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0);
} }
else { else {
cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx = _mm_aesenc_si128(cx, ax0);
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));
} }
if (VARIANT > 0) { if (IS_V1 || VARIANT == xmrig::VARIANT_2) {
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); cryptonight_monero_tweak<VARIANT>(l0, idx0 & MASK, ax0, bx0, bx1, cx);
} else { } else {
_mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
} }
idx0 = EXTRACT64(cx); idx0 = _mm_cvtsi128_si64(cx);
bx0 = cx;
uint64_t hi, lo, cl, ch; uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0]; cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1]; ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(0, cl, cx);
lo = __umul128(idx0, cl, &hi);
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo);
}
else {
lo = __umul128(idx0, cl, &hi);
}
al0 += hi; al0 += hi;
ah0 += lo; ah0 += lo;
VARIANT1_2(ah0, 0);
((uint64_t*)&l0[idx0 & MASK])[0] = al0; ((uint64_t*)&l0[idx0 & MASK])[0] = al0;
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
VARIANT1_2(ah0, 0);
ah0 ^= ch; if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
} else if (IS_V1) {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
} else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
}
al0 ^= cl; al0 ^= cl;
ah0 ^= ch;
idx0 = al0; idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; const int64x2_t x = vld1q_s64(reinterpret_cast<const int64_t *>(&l0[idx0 & MASK]));
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; const int64_t n = vgetq_lane_s64(x, 0);
int64_t q = n / (d | 0x5); const int32_t d = vgetq_lane_s32(x, 2);
const int64_t q = n / (d | 0x5);
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
idx0 = d ^ q;
if (VARIANT == xmrig::VARIANT_XHV) {
idx0 = (~d) ^ q;
}
else {
idx0 = d ^ q;
}
} }
if (VARIANT == xmrig::VARIANT_2) {
bx1 = bx0;
}
bx0 = cx;
} }
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state);
keccakf(h0, 24); xmrig::keccakf(h0, 24);
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
} }
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
{ {
constexpr size_t MASK = xmrig::cn_select_mask<ALGO>(); constexpr size_t MASK = xmrig::cn_select_mask<ALGO>();
constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO>(); constexpr size_t ITERATIONS = xmrig::cn_select_iter<ALGO, VARIANT>();
constexpr size_t MEM = xmrig::cn_select_memory<ALGO>(); constexpr size_t MEM = xmrig::cn_select_memory<ALGO>();
constexpr bool IS_V1 = xmrig::cn_base_variant<VARIANT>() == xmrig::VARIANT_1;
if (VARIANT > 0 && size < 43) { if (IS_V1 && size < 43) {
memset(output, 0, 64); memset(output, 0, 64);
return; return;
} }
keccak(input, (int) size, ctx[0]->state, 200); xmrig::keccak(input, size, ctx[0]->state);
keccak(input + size, (int) size, ctx[1]->state, 200); xmrig::keccak(input + size, size, ctx[1]->state);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
const uint8_t* l0 = ctx[0]->memory; const uint8_t* l0 = ctx[0]->memory;
const uint8_t* l1 = ctx[1]->memory; const uint8_t* l1 = ctx[1]->memory;
uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state); uint64_t* h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state); uint64_t* h1 = reinterpret_cast<uint64_t*>(ctx[1]->state);
VARIANT1_INIT(0);
VARIANT1_INIT(1);
VARIANT2_INIT(0);
VARIANT2_INIT(1);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h0, (__m128i*) l0);
cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1); cn_explode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) h1, (__m128i*) l1);
@ -507,116 +572,165 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
uint64_t ah0 = h0[1] ^ h0[5]; uint64_t ah0 = h0[1] ^ h0[5];
uint64_t ah1 = h1[1] ^ h1[5]; uint64_t ah1 = h1[1] ^ h1[5];
__m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx00 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]);
__m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); __m128i bx01 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]);
__m128i bx10 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]);
__m128i bx11 = _mm_set_epi64x(h1[9] ^ h1[11], h1[8] ^ h1[10]);
uint64_t idx0 = h0[0] ^ h0[4]; uint64_t idx0 = al0;
uint64_t idx1 = h1[0] ^ h1[4]; uint64_t idx1 = al1;
for (size_t i = 0; i < ITERATIONS; i++) { for (size_t i = 0; i < ITERATIONS; i++) {
__m128i cx0, cx1; __m128i cx0, cx1;
if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) {
if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], _mm_set_epi64x(ah0, al0));
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], _mm_set_epi64x(ah1, al1));
}
else {
cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]);
cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]);
cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0));
cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1));
} }
if (VARIANT > 0) { const __m128i ax0 = _mm_set_epi64x(ah0, al0);
cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); const __m128i ax1 = _mm_set_epi64x(ah1, al1);
cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); if (VARIANT == xmrig::VARIANT_TUBE) {
cx0 = aes_round_tweak_div(cx0, ax0);
cx1 = aes_round_tweak_div(cx1, ax1);
}
else if (SOFT_AES) {
cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0);
cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1);
}
else {
cx0 = _mm_aesenc_si128(cx0, ax0);
cx1 = _mm_aesenc_si128(cx1, ax1);
}
if (IS_V1 || (VARIANT == xmrig::VARIANT_2)) {
cryptonight_monero_tweak<VARIANT>(l0, idx0 & MASK, ax0, bx00, bx01, cx0);
cryptonight_monero_tweak<VARIANT>(l1, idx1 & MASK, ax1, bx10, bx11, cx1);
} else { } else {
_mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx00, cx0));
_mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx10, cx1));
}; }
idx0 = EXTRACT64(cx0); idx0 = _mm_cvtsi128_si64(cx0);
idx1 = EXTRACT64(cx1); idx1 = _mm_cvtsi128_si64(cx1);
bx0 = cx0;
bx1 = cx1;
uint64_t hi, lo, cl, ch; uint64_t hi, lo, cl, ch;
cl = ((uint64_t*) &l0[idx0 & MASK])[0]; cl = ((uint64_t*) &l0[idx0 & MASK])[0];
ch = ((uint64_t*) &l0[idx0 & MASK])[1]; ch = ((uint64_t*) &l0[idx0 & MASK])[1];
lo = __umul128(idx0, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(0, cl, cx0);
lo = __umul128(idx0, cl, &hi);
VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo);
} else {
lo = __umul128(idx0, cl, &hi);
}
al0 += hi; al0 += hi;
ah0 += lo; ah0 += lo;
VARIANT1_2(ah0, 0); ((uint64_t*)&l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[0] = al0;
((uint64_t*) &l0[idx0 & MASK])[1] = ah0; if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
VARIANT1_2(ah0, 0); ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
} else if (IS_V1) {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
} else {
((uint64_t*)&l0[idx0 & MASK])[1] = ah0;
}
ah0 ^= ch;
al0 ^= cl; al0 ^= cl;
ah0 ^= ch;
idx0 = al0; idx0 = al0;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; const int64x2_t x = vld1q_s64(reinterpret_cast<const int64_t *>(&l0[idx0 & MASK]));
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; const int64_t n = vgetq_lane_s64(x, 0);
int64_t q = n / (d | 0x5); const int32_t d = vgetq_lane_s32(x, 2);
const int64_t q = n / (d | 0x5);
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
idx0 = d ^ q;
if (VARIANT == xmrig::VARIANT_XHV) {
idx0 = (~d) ^ q;
}
else {
idx0 = d ^ q;
}
} }
cl = ((uint64_t*) &l1[idx1 & MASK])[0]; cl = ((uint64_t*) &l1[idx1 & MASK])[0];
ch = ((uint64_t*) &l1[idx1 & MASK])[1]; ch = ((uint64_t*) &l1[idx1 & MASK])[1];
lo = __umul128(idx1, cl, &hi); if (VARIANT == xmrig::VARIANT_2) {
VARIANT2_INTEGER_MATH(1, cl, cx1);
lo = __umul128(idx1, cl, &hi);
VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo);
} else {
lo = __umul128(idx1, cl, &hi);
}
al1 += hi; al1 += hi;
ah1 += lo; ah1 += lo;
VARIANT1_2(ah1, 1); ((uint64_t*)&l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[0] = al1;
((uint64_t*) &l1[idx1 & MASK])[1] = ah1; if (IS_V1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) {
VARIANT1_2(ah1, 1); ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1;
} else if (IS_V1) {
((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1;
} else {
((uint64_t*)&l1[idx1 & MASK])[1] = ah1;
}
ah1 ^= ch;
al1 ^= cl; al1 ^= cl;
ah1 ^= ch;
idx1 = al1; idx1 = al1;
if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { if (ALGO == xmrig::CRYPTONIGHT_HEAVY) {
int64_t n = ((int64_t*)&l1[idx1 & MASK])[0]; const int64x2_t x = vld1q_s64(reinterpret_cast<const int64_t *>(&l1[idx1 & MASK]));
int32_t d = ((int32_t*)&l1[idx1 & MASK])[2]; const int64_t n = vgetq_lane_s64(x, 0);
int64_t q = n / (d | 0x5); const int32_t d = vgetq_lane_s32(x, 2);
const int64_t q = n / (d | 0x5);
((int64_t*)&l1[idx1 & MASK])[0] = n ^ q; ((int64_t*)&l1[idx1 & MASK])[0] = n ^ q;
idx1 = d ^ q;
if (VARIANT == xmrig::VARIANT_XHV) {
idx1 = (~d) ^ q;
}
else {
idx1 = d ^ q;
}
} }
if (VARIANT == xmrig::VARIANT_2) {
bx01 = bx00;
bx11 = bx10;
}
bx00 = cx0;
bx10 = cx1;
} }
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l0, (__m128i*) h0);
cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1); cn_implode_scratchpad<ALGO, MEM, SOFT_AES>((__m128i*) l1, (__m128i*) h1);
keccakf(h0, 24); xmrig::keccakf(h0, 24);
keccakf(h1, 24); xmrig::keccakf(h1, 24);
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32);
} }
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
{ {
} }
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
{ {
} }
template<xmrig::Algo ALGO, bool SOFT_AES, int VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>
inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx)
{ {
} }

View file

@ -38,6 +38,8 @@ namespace xmrig
constexpr const size_t CRYPTONIGHT_MEMORY = 2 * 1024 * 1024; constexpr const size_t CRYPTONIGHT_MEMORY = 2 * 1024 * 1024;
constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0; constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0;
constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000; constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000;
constexpr const uint32_t CRYPTONIGHT_MSR_ITER = 0x40000;
constexpr const uint32_t CRYPTONIGHT_XAO_ITER = 0x100000;
constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024; constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024;
constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0; constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0;
@ -102,14 +104,34 @@ inline uint32_t cn_select_mask(Algo algorithm)
} }
template<Algo ALGO> inline constexpr uint32_t cn_select_iter() { return 0; } template<Algo ALGO, Variant variant> inline constexpr uint32_t cn_select_iter() { return 0; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT>() { return CRYPTONIGHT_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_0>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE>() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_1>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY>() { return CRYPTONIGHT_HEAVY_ITER; } template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_2>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XTL>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_MSR>() { return CRYPTONIGHT_MSR_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_XAO>() { return CRYPTONIGHT_XAO_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT, VARIANT_RTO>() { return CRYPTONIGHT_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_0>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_LITE, VARIANT_1>() { return CRYPTONIGHT_LITE_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY, VARIANT_0>() { return CRYPTONIGHT_HEAVY_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY, VARIANT_XHV>() { return CRYPTONIGHT_HEAVY_ITER; }
template<> inline constexpr uint32_t cn_select_iter<CRYPTONIGHT_HEAVY, VARIANT_TUBE>() { return CRYPTONIGHT_HEAVY_ITER; }
inline uint32_t cn_select_iter(Algo algorithm) inline uint32_t cn_select_iter(Algo algorithm, Variant variant)
{ {
switch (variant) {
case VARIANT_MSR:
return CRYPTONIGHT_MSR_ITER;
case VARIANT_RTO:
return CRYPTONIGHT_XAO_ITER;
default:
break;
}
switch(algorithm) switch(algorithm)
{ {
case CRYPTONIGHT: case CRYPTONIGHT:
@ -129,6 +151,18 @@ inline uint32_t cn_select_iter(Algo algorithm)
} }
template<Variant variant> inline constexpr Variant cn_base_variant() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_0>() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_1>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_TUBE>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_XTL>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_MSR>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_XHV>() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_XAO>() { return VARIANT_0; }
template<> inline constexpr Variant cn_base_variant<VARIANT_RTO>() { return VARIANT_1; }
template<> inline constexpr Variant cn_base_variant<VARIANT_2>() { return VARIANT_2; }
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd> * Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -22,30 +23,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CRYPTONIGHT_MONERO_H__ #ifndef XMRIG_CRYPTONIGHT_MONERO_H
#define __CRYPTONIGHT_MONERO_H__ #define XMRIG_CRYPTONIGHT_MONERO_H
#include <fenv.h>
#include <math.h>
// VARIANT ALTERATIONS // VARIANT ALTERATIONS
#ifndef XMRIG_ARM #ifndef XMRIG_ARM
# define VARIANT1_INIT(part) \ # define VARIANT1_INIT(part) \
uint64_t tweak1_2_##part = 0; \ uint64_t tweak1_2_##part = 0; \
if (VARIANT > 0) { \ if (IS_V1) { \
tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \ tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \
*(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24)); \ *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24)); \
} }
#else #else
# define VARIANT1_INIT(part) \ # define VARIANT1_INIT(part) \
uint64_t tweak1_2_##part = 0; \ uint64_t tweak1_2_##part = 0; \
if (VARIANT > 0) { \ if (IS_V1) { \
volatile const uint64_t a = *reinterpret_cast<const uint64_t*>(input + 35 + part * size); \ memcpy(&tweak1_2_##part, input + 35 + part * size, sizeof tweak1_2_##part); \
volatile const uint64_t b = *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24); \ tweak1_2_##part ^= *(reinterpret_cast<const uint64_t*>(ctx[part]->state) + 24); \
tweak1_2_##part = a ^ b; \
} }
#endif #endif
#define VARIANT1_1(p) \ #define VARIANT1_1(p) \
if (VARIANT > 0) { \ if (IS_V1) { \
const uint8_t tmp = reinterpret_cast<const uint8_t*>(p)[11]; \ const uint8_t tmp = reinterpret_cast<const uint8_t*>(p)[11]; \
static const uint32_t table = 0x75310; \ static const uint32_t table = 0x75310; \
const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \
@ -53,9 +55,96 @@
} }
#define VARIANT1_2(p, part) \ #define VARIANT1_2(p, part) \
if (VARIANT > 0) { \ if (IS_V1) { \
(p) ^= tweak1_2_##part; \ (p) ^= tweak1_2_##part; \
} }
#endif /* __CRYPTONIGHT_MONERO_H__ */ #ifndef XMRIG_ARM
# define VARIANT2_INIT(part) \
__m128i division_result_xmm_##part = _mm_cvtsi64_si128(h##part[12]); \
__m128i sqrt_result_xmm_##part = _mm_cvtsi64_si128(h##part[13]);
#ifdef _MSC_VER
# define VARIANT2_SET_ROUNDING_MODE() if (VARIANT == xmrig::VARIANT_2) { _control87(RC_DOWN, MCW_RC); }
#else
# define VARIANT2_SET_ROUNDING_MODE() if (VARIANT == xmrig::VARIANT_2) { fesetround(FE_DOWNWARD); }
#endif
# define VARIANT2_INTEGER_MATH(part, cl, cx) \
do { \
const uint64_t sqrt_result = static_cast<uint64_t>(_mm_cvtsi128_si64(sqrt_result_xmm_##part)); \
const uint64_t cx_0 = _mm_cvtsi128_si64(cx); \
cl ^= static_cast<uint64_t>(_mm_cvtsi128_si64(division_result_xmm_##part)) ^ (sqrt_result << 32); \
const uint32_t d = static_cast<uint32_t>(cx_0 + (sqrt_result << 1)) | 0x80000001UL; \
const uint64_t cx_1 = _mm_cvtsi128_si64(_mm_srli_si128(cx, 8)); \
const uint64_t division_result = static_cast<uint32_t>(cx_1 / d) + ((cx_1 % d) << 32); \
division_result_xmm_##part = _mm_cvtsi64_si128(static_cast<int64_t>(division_result)); \
sqrt_result_xmm_##part = int_sqrt_v2(cx_0 + division_result); \
} while (0)
# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1) \
do { \
const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
} while (0)
# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \
do { \
const __m128i chunk1 = _mm_xor_si128(_mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))), _mm_set_epi64x(lo, hi)); \
const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \
hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \
lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \
const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \
_mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \
} while (0)
#else
# define VARIANT2_INIT(part) \
uint64_t division_result_##part = h##part[12]; \
uint64_t sqrt_result_##part = h##part[13];
# define VARIANT2_INTEGER_MATH(part, cl, cx) \
do { \
const uint64_t cx_0 = _mm_cvtsi128_si64(cx); \
cl ^= division_result_##part ^ (sqrt_result_##part << 32); \
const uint32_t d = static_cast<uint32_t>(cx_0 + (sqrt_result_##part << 1)) | 0x80000001UL; \
const uint64_t cx_1 = _mm_cvtsi128_si64(_mm_srli_si128(cx, 8)); \
division_result_##part = static_cast<uint32_t>(cx_1 / d) + ((cx_1 % d) << 32); \
const uint64_t sqrt_input = cx_0 + division_result_##part; \
sqrt_result_##part = sqrt(sqrt_input + 18446744073709551616.0) * 2.0 - 8589934592.0; \
const uint64_t s = sqrt_result_##part >> 1; \
const uint64_t b = sqrt_result_##part & 1; \
const uint64_t r2 = (uint64_t)(s) * (s + b) + (sqrt_result_##part << 32); \
sqrt_result_##part += ((r2 + b > sqrt_input) ? -1 : 0) + ((r2 + (1ULL << 32) < sqrt_input - s) ? 1 : 0); \
} while (0)
# define VARIANT2_SHUFFLE(base_ptr, offset, _a, _b, _b1) \
do { \
const uint64x2_t chunk1 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))); \
const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \
const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
} while (0)
# define VARIANT2_SHUFFLE2(base_ptr, offset, _a, _b, _b1, hi, lo) \
do { \
const uint64x2_t chunk1 = veorq_u64(vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10))), vcombine_u64(vcreate_u64(hi), vcreate_u64(lo))); \
const uint64x2_t chunk2 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20))); \
hi ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[0]; \
lo ^= ((uint64_t*)((base_ptr) + ((offset) ^ 0x20)))[1]; \
const uint64x2_t chunk3 = vld1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \
vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \
} while (0)
#endif
#endif /* XMRIG_CRYPTONIGHT_MONERO_H */

View file

@ -69,7 +69,7 @@ const static uint8_t test_output_v0[160] = {
}; };
// Monero v7 // Cryptonight variant 1 (Monero v7)
const static uint8_t test_output_v1[160] = { const static uint8_t test_output_v1[160] = {
0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9, 0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9,
0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9,
@ -84,6 +84,21 @@ const static uint8_t test_output_v1[160] = {
}; };
// Cryptonight variant 2 (Monero v8)
const static uint8_t test_output_v2[160] = {
0x97, 0x37, 0x82, 0x82, 0xCF, 0x10, 0xE7, 0xAD, 0x03, 0x3F, 0x7B, 0x80, 0x74, 0xC4, 0x0E, 0x14,
0xD0, 0x6E, 0x7F, 0x60, 0x9D, 0xDD, 0xDA, 0x78, 0x76, 0x80, 0xB5, 0x8C, 0x05, 0xF4, 0x3D, 0x21,
0x87, 0x1F, 0xCD, 0x68, 0x23, 0xF6, 0xA8, 0x79, 0xBB, 0x3F, 0x33, 0x95, 0x1C, 0x8E, 0x8E, 0x89,
0x1D, 0x40, 0x43, 0x88, 0x0B, 0x02, 0xDF, 0xA1, 0xBB, 0x3B, 0xE4, 0x98, 0xB5, 0x0E, 0x75, 0x78,
0xE6, 0x0D, 0x24, 0x0F, 0x65, 0x85, 0x60, 0x3A, 0x4A, 0xE5, 0x5F, 0x54, 0x9B, 0xC8, 0x79, 0x93,
0xEB, 0x3D, 0x98, 0x2C, 0xFE, 0x9B, 0xFB, 0x15, 0xB6, 0x88, 0x21, 0x94, 0xB0, 0x05, 0x86, 0x5C,
0x59, 0x8B, 0x93, 0x7A, 0xDA, 0xD2, 0xA2, 0x14, 0xED, 0xB7, 0xC4, 0x5D, 0xA1, 0xEF, 0x26, 0xF3,
0xC7, 0x73, 0x29, 0x4D, 0xF1, 0xC8, 0x2C, 0xE0, 0xD0, 0xE9, 0xED, 0x0C, 0x70, 0x75, 0x05, 0x3E,
0x5B, 0xF6, 0xA0, 0x6E, 0xEA, 0xDE, 0x87, 0x0B, 0x06, 0x29, 0x03, 0xBF, 0xB4, 0x85, 0x9D, 0x04,
0x75, 0x1A, 0xCD, 0x1E, 0xD6, 0xAA, 0x1B, 0x05, 0x24, 0x6A, 0x2C, 0x80, 0x69, 0x68, 0xDC, 0x97
};
// Stellite (XTL) // Stellite (XTL)
const static uint8_t test_output_xtl[160] = { const static uint8_t test_output_xtl[160] = {
0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3, 0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3,
@ -99,6 +114,51 @@ const static uint8_t test_output_xtl[160] = {
}; };
// Masari (MSR)
const static uint8_t test_output_msr[160] = {
0x3C, 0x7A, 0x61, 0x08, 0x4C, 0x5E, 0xB8, 0x65, 0xB4, 0x98, 0xAB, 0x2F, 0x5A, 0x1A, 0xC5, 0x2C,
0x49, 0xC1, 0x77, 0xC2, 0xD0, 0x13, 0x34, 0x42, 0xD6, 0x5E, 0xD5, 0x14, 0x33, 0x5C, 0x82, 0xC5,
0x69, 0xDF, 0x38, 0x51, 0x1B, 0xB3, 0xEB, 0x7D, 0xE7, 0x6B, 0x08, 0x8E, 0xB6, 0x7E, 0xB7, 0x1C,
0x5F, 0x3C, 0x81, 0xC9, 0xF7, 0xCE, 0xAE, 0x28, 0xC0, 0xFE, 0xEB, 0xBA, 0x0B, 0x40, 0x38, 0x1D,
0x44, 0xD0, 0xD5, 0xD3, 0x98, 0x1F, 0xA3, 0x0E, 0xE9, 0x89, 0x1A, 0xD7, 0x88, 0xCC, 0x25, 0x76,
0x9C, 0xFF, 0x4D, 0x7F, 0x9C, 0xCF, 0x48, 0x07, 0x91, 0xF9, 0x82, 0xF5, 0x4C, 0xE9, 0xBD, 0x82,
0x36, 0x36, 0x64, 0x14, 0xED, 0xB8, 0x54, 0xEE, 0x22, 0xA1, 0x66, 0xA3, 0x87, 0x10, 0x76, 0x1F,
0x5A, 0xCD, 0x4C, 0x31, 0x4C, 0xBA, 0x41, 0xD2, 0xDB, 0x6C, 0x31, 0x2E, 0x7A, 0x64, 0x15, 0xFF,
0xA6, 0xD9, 0xB9, 0x7D, 0x1C, 0x3C, 0x98, 0xDD, 0x16, 0xE6, 0xD3, 0xAA, 0xEF, 0xB6, 0xB3, 0x53,
0x74, 0xD1, 0xAC, 0x5C, 0x04, 0x26, 0x7D, 0x71, 0xDE, 0xAB, 0x66, 0x28, 0x91, 0x3A, 0x6F, 0x4F
};
// Alloy (XAO)
const static uint8_t test_output_xao[160] = {
0x9A, 0x29, 0xD0, 0xC4, 0xAF, 0xDC, 0x63, 0x9B, 0x65, 0x53, 0xB1, 0xC8, 0x37, 0x35, 0x11, 0x4C,
0x5D, 0x77, 0x16, 0x21, 0x42, 0x97, 0x5C, 0xB8, 0x50, 0xC0, 0xA5, 0x1F, 0x64, 0x07, 0xBD, 0x33,
0xF1, 0xC9, 0x98, 0x40, 0x42, 0xDE, 0x39, 0xD1, 0xBA, 0x2D, 0xAD, 0xEC, 0xFE, 0xEA, 0xD8, 0x46,
0x56, 0x1C, 0x32, 0x90, 0x42, 0x63, 0x10, 0x80, 0xD7, 0x01, 0xE4, 0xE6, 0x20, 0xB3, 0x60, 0x45,
0x05, 0xE5, 0xC2, 0x18, 0xCD, 0x07, 0xA4, 0x40, 0x42, 0x91, 0xE2, 0xA4, 0x52, 0x54, 0x79, 0xBA,
0xCD, 0x7E, 0x61, 0x2D, 0x7F, 0x7E, 0x69, 0x5E, 0xD7, 0xC0, 0x06, 0x65, 0xD7, 0xA1, 0xB8, 0xB8,
0x1E, 0x31, 0x1C, 0xD3, 0xB7, 0xBC, 0x78, 0x3C, 0x01, 0xAF, 0x77, 0xAA, 0xF3, 0x0F, 0x4C, 0xF2,
0xD1, 0x8B, 0x58, 0xC7, 0xEB, 0x99, 0x91, 0x53, 0x43, 0x71, 0x47, 0x99, 0x9E, 0x04, 0xA4, 0xEA,
0xB8, 0xA3, 0xB0, 0x9E, 0x09, 0xF5, 0x57, 0x5C, 0xCF, 0x8A, 0xC6, 0xCA, 0x88, 0x51, 0x9A, 0x01,
0x31, 0xCC, 0x0C, 0xA6, 0x53, 0xB5, 0x5F, 0xFD, 0x7D, 0x29, 0x3A, 0x35, 0xE9, 0x0E, 0x25, 0x6C
};
// Arto (RTO)
const static uint8_t test_output_rto[160] = {
0x82, 0x66, 0x1E, 0x1C, 0x6E, 0x64, 0x36, 0x66, 0x84, 0x06, 0x32, 0x7A, 0x9B, 0xB1, 0x13, 0x19,
0xA5, 0x56, 0x16, 0x15, 0xDF, 0xEC, 0x1C, 0x9E, 0xE3, 0x88, 0x4A, 0x6C, 0x1C, 0xEB, 0x76, 0xA5,
0xB3, 0xFB, 0xF4, 0x3F, 0x2B, 0x6A, 0x3A, 0x39, 0xA3, 0x6E, 0x08, 0x33, 0x67, 0x90, 0x31, 0xB9,
0x3F, 0x27, 0xE4, 0x79, 0x32, 0x61, 0x6B, 0x5C, 0x8A, 0xF8, 0xAF, 0xC0, 0x60, 0xFD, 0x83, 0xB7,
0x11, 0x11, 0x89, 0xB4, 0xDC, 0xAE, 0x40, 0xC8, 0x64, 0xAA, 0x4D, 0x19, 0x23, 0x7B, 0xD3, 0x27,
0xB2, 0x0F, 0xA7, 0x50, 0x7D, 0xCA, 0xF5, 0x03, 0x06, 0xB2, 0x26, 0x62, 0xF3, 0x68, 0x2D, 0x30,
0x6F, 0x93, 0x1E, 0xFF, 0xCD, 0x85, 0x40, 0x28, 0x5F, 0xC3, 0x8C, 0x76, 0x51, 0x9E, 0xD5, 0x06,
0x32, 0xD6, 0x35, 0x83, 0xF6, 0x3B, 0x54, 0x4F, 0xA1, 0x9C, 0x13, 0xD8, 0xC4, 0x0E, 0x01, 0x2F,
0x29, 0xDB, 0x8C, 0x1C, 0xB7, 0x06, 0x86, 0x79, 0x6D, 0xFF, 0x9F, 0x89, 0x3B, 0x3A, 0xA5, 0x79,
0xE7, 0x81, 0x4E, 0x2A, 0xBD, 0x62, 0xC1, 0x1B, 0x7C, 0xB9, 0x33, 0x7B, 0xEE, 0x95, 0x80, 0xB3
};
#ifndef XMRIG_NO_AEON #ifndef XMRIG_NO_AEON
const static uint8_t test_output_v0_lite[160] = { const static uint8_t test_output_v0_lite[160] = {
0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E,
@ -127,26 +187,11 @@ const static uint8_t test_output_v1_lite[160] = {
0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9, 0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9,
0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6 0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6
}; };
// IPBC
const static uint8_t test_output_ipbc_lite[160] = {
0xE4, 0x93, 0x8C, 0xAA, 0x59, 0x8D, 0x02, 0x8A, 0xB8, 0x6F, 0x25, 0xD2, 0xB1, 0x23, 0xD0, 0xD5,
0x33, 0xE3, 0x9F, 0x37, 0xAC, 0xE5, 0xF8, 0xEB, 0x7A, 0xE8, 0x40, 0xEB, 0x5D, 0xB1, 0x35, 0x5F,
0xB2, 0x47, 0x86, 0xF0, 0x7F, 0x6F, 0x4B, 0x55, 0x3E, 0xA1, 0xBB, 0xE8, 0xA1, 0x75, 0x00, 0x2D,
0x07, 0x9A, 0x21, 0x0E, 0xBD, 0x06, 0x6A, 0xB0, 0xFD, 0x96, 0x9E, 0xE6, 0xE4, 0x69, 0x67, 0xBB,
0x88, 0x45, 0x0B, 0x91, 0x0B, 0x7B, 0xCB, 0x21, 0x3C, 0x3C, 0x09, 0x30, 0x07, 0x71, 0x07, 0xD5,
0xB8, 0x2D, 0x83, 0x09, 0xAF, 0x7E, 0xB2, 0xA8, 0xAC, 0x25, 0xDC, 0x10, 0xF8, 0x63, 0x6A, 0xBC,
0x73, 0x01, 0x4E, 0xA8, 0x1C, 0xDA, 0x9A, 0x86, 0x17, 0xEC, 0xA8, 0xFB, 0xAA, 0x23, 0x23, 0x17,
0xE1, 0x32, 0x68, 0x9C, 0x4C, 0xF4, 0x08, 0xED, 0xB0, 0x15, 0xC3, 0xA9, 0x0F, 0xF0, 0xA2, 0x7E,
0xD9, 0xE4, 0x23, 0xA7, 0x9E, 0x91, 0xD8, 0x73, 0x94, 0xD6, 0x6C, 0x70, 0x9B, 0x8B, 0x72, 0x92,
0xA3, 0xA4, 0x0A, 0xE2, 0x3C, 0x0A, 0x34, 0x88, 0xA1, 0x6D, 0xFE, 0x02, 0x44, 0x60, 0x7B, 0x3D
};
#endif #endif
#ifndef XMRIG_NO_SUMO #ifndef XMRIG_NO_SUMO
const static uint8_t test_output_heavy[160] = { const static uint8_t test_output_v0_heavy[160] = {
0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64, 0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64,
0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2, 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2,
0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A,
@ -158,6 +203,34 @@ const static uint8_t test_output_heavy[160] = {
0x53, 0x62, 0x0A, 0x54, 0x7D, 0x43, 0xEA, 0x18, 0x94, 0xED, 0xD8, 0x92, 0x06, 0x6A, 0xA1, 0x51, 0x53, 0x62, 0x0A, 0x54, 0x7D, 0x43, 0xEA, 0x18, 0x94, 0xED, 0xD8, 0x92, 0x06, 0x6A, 0xA1, 0x51,
0xAD, 0xB1, 0xFD, 0x89, 0xFB, 0x5C, 0xB4, 0x25, 0x6A, 0xDD, 0xB0, 0x09, 0xC5, 0x72, 0x87, 0xEB 0xAD, 0xB1, 0xFD, 0x89, 0xFB, 0x5C, 0xB4, 0x25, 0x6A, 0xDD, 0xB0, 0x09, 0xC5, 0x72, 0x87, 0xEB
}; };
const static uint8_t test_output_xhv_heavy[160] = {
0x5A, 0xC3, 0xF7, 0x85, 0xC4, 0x90, 0xC5, 0x85, 0x50, 0xEC, 0x95, 0xD2, 0x72, 0x65, 0x63, 0x57,
0x7E, 0x7C, 0x1C, 0x21, 0x2D, 0x0C, 0xDE, 0x59, 0x12, 0x73, 0x20, 0x1E, 0x44, 0xFD, 0xD5, 0xB6,
0x1F, 0x4E, 0xB2, 0x0A, 0x36, 0x51, 0x4B, 0xF5, 0x4D, 0xC9, 0xE0, 0x90, 0x2C, 0x16, 0x47, 0x3F,
0xDE, 0x18, 0x29, 0x8E, 0xBB, 0x34, 0x2B, 0xEF, 0x7A, 0x04, 0x22, 0xD1, 0xB1, 0xF2, 0x48, 0xDA,
0xE3, 0x7F, 0x4B, 0x4C, 0xB4, 0xDF, 0xE8, 0xD3, 0x70, 0xE2, 0xE7, 0x44, 0x25, 0x87, 0x12, 0xF9,
0x8F, 0x28, 0x0B, 0xCE, 0x2C, 0xEE, 0xDD, 0x88, 0x94, 0x35, 0x48, 0x51, 0xAE, 0xC8, 0x9C, 0x0B,
0xED, 0x2F, 0xE6, 0x0F, 0x39, 0x05, 0xB4, 0x4A, 0x8F, 0x38, 0x44, 0x2D, 0x4B, 0xE9, 0x7B, 0x81,
0xC6, 0xB0, 0xE0, 0x0A, 0x39, 0x8C, 0x38, 0xFE, 0x63, 0x31, 0x47, 0x65, 0x0D, 0x2B, 0xF4, 0x96,
0x13, 0x91, 0x89, 0xB4, 0x5B, 0xA9, 0x2A, 0x7A, 0x09, 0x65, 0x14, 0x20, 0x76, 0x24, 0x6C, 0x80,
0x1D, 0x3F, 0x9F, 0xCD, 0x68, 0x39, 0xA9, 0x42, 0x27, 0xC1, 0x0C, 0x53, 0x98, 0x35, 0x60, 0x7A
};
// TUBE
const static uint8_t test_output_tube_heavy[160] = {
0xFE, 0x53, 0x35, 0x20, 0x76, 0xEA, 0xE6, 0x89, 0xFA, 0x3B, 0x4F, 0xDA, 0x61, 0x46, 0x34, 0xCF,
0xC3, 0x12, 0xEE, 0x0C, 0x38, 0x7D, 0xF2, 0xB8, 0xB7, 0x4D, 0xA2, 0xA1, 0x59, 0x74, 0x12, 0x35,
0xCD, 0x3F, 0x29, 0xDF, 0x07, 0x4A, 0x14, 0xAD, 0x0B, 0x98, 0x99, 0x37, 0xCA, 0x14, 0x68, 0xA3,
0x8D, 0xAE, 0x86, 0xC1, 0xA3, 0x54, 0x05, 0xBE, 0xEA, 0x6D, 0x29, 0x24, 0x0C, 0x82, 0x97, 0x74,
0xA0, 0x64, 0x77, 0xCD, 0x8D, 0x8A, 0xC3, 0x10, 0xB4, 0x89, 0x0E, 0xBB, 0x7D, 0xE6, 0x32, 0x8F,
0xF4, 0x2D, 0xB6, 0x9E, 0x8A, 0xF9, 0xF8, 0xEE, 0x2C, 0xD0, 0x74, 0xED, 0xA9, 0xAA, 0xA1, 0xFB,
0xE2, 0xC9, 0x89, 0x66, 0xD6, 0x66, 0x52, 0xA2, 0x16, 0xDA, 0x36, 0xA0, 0x10, 0x62, 0xD2, 0xB1,
0x76, 0xD1, 0x31, 0xE9, 0x1C, 0x08, 0xB6, 0xCA, 0xAF, 0x89, 0xB9, 0x3D, 0x2C, 0xFA, 0x9A, 0x30,
0x74, 0x6A, 0x96, 0xA1, 0x95, 0x6C, 0xBB, 0x46, 0x4D, 0xE0, 0xEB, 0x28, 0xBE, 0x2A, 0x8C, 0x34,
0x57, 0x79, 0xBE, 0x52, 0xFB, 0xBC, 0x68, 0x43, 0x45, 0xF4, 0xDF, 0xA5, 0xA8, 0xFD, 0x55, 0xA6
};
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,410 @@
mov rax, rsp
push rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 184
stmxcsr DWORD PTR [rsp+272]
mov DWORD PTR [rsp+276], 24448
ldmxcsr DWORD PTR [rsp+276]
mov r13, QWORD PTR [rcx+224]
mov r9, rdx
mov r10, QWORD PTR [rcx+32]
mov r8, rcx
xor r10, QWORD PTR [rcx]
mov r14d, 524288
mov r11, QWORD PTR [rcx+40]
xor r11, QWORD PTR [rcx+8]
mov rsi, QWORD PTR [rdx+224]
mov rdx, QWORD PTR [rcx+56]
xor rdx, QWORD PTR [rcx+24]
mov rdi, QWORD PTR [r9+32]
xor rdi, QWORD PTR [r9]
mov rbp, QWORD PTR [r9+40]
xor rbp, QWORD PTR [r9+8]
movq xmm0, rdx
movaps XMMWORD PTR [rax-88], xmm6
movaps XMMWORD PTR [rax-104], xmm7
movaps XMMWORD PTR [rax-120], xmm8
movaps XMMWORD PTR [rsp+112], xmm9
movaps XMMWORD PTR [rsp+96], xmm10
movaps XMMWORD PTR [rsp+80], xmm11
movaps XMMWORD PTR [rsp+64], xmm12
movaps XMMWORD PTR [rsp+48], xmm13
movaps XMMWORD PTR [rsp+32], xmm14
movaps XMMWORD PTR [rsp+16], xmm15
mov rdx, r10
movq xmm4, QWORD PTR [r8+96]
and edx, 2097136
mov rax, QWORD PTR [rcx+48]
xorps xmm13, xmm13
xor rax, QWORD PTR [rcx+16]
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r8+72]
movq xmm5, QWORD PTR [r8+104]
movq xmm7, rax
mov eax, 1
shl rax, 52
movq xmm14, rax
punpcklqdq xmm14, xmm14
mov eax, 1023
shl rax, 52
movq xmm12, rax
punpcklqdq xmm12, xmm12
mov rax, QWORD PTR [r8+80]
xor rax, QWORD PTR [r8+64]
punpcklqdq xmm7, xmm0
movq xmm0, rcx
mov rcx, QWORD PTR [r9+56]
xor rcx, QWORD PTR [r9+24]
movq xmm3, rax
mov rax, QWORD PTR [r9+48]
xor rax, QWORD PTR [r9+16]
punpcklqdq xmm3, xmm0
movq xmm0, rcx
mov QWORD PTR [rsp], r13
mov rcx, QWORD PTR [r9+88]
xor rcx, QWORD PTR [r9+72]
movq xmm6, rax
mov rax, QWORD PTR [r9+80]
xor rax, QWORD PTR [r9+64]
punpcklqdq xmm6, xmm0
movq xmm0, rcx
mov QWORD PTR [rsp+256], r10
mov rcx, rdi
mov QWORD PTR [rsp+264], r11
movq xmm8, rax
and ecx, 2097136
punpcklqdq xmm8, xmm0
movq xmm0, QWORD PTR [r9+96]
punpcklqdq xmm4, xmm0
movq xmm0, QWORD PTR [r9+104]
lea r8, QWORD PTR [rcx+rsi]
movdqu xmm11, XMMWORD PTR [r8]
punpcklqdq xmm5, xmm0
lea r9, QWORD PTR [rdx+r13]
movdqu xmm15, XMMWORD PTR [r9]
ALIGN 16
main_loop_double_sandybridge:
movdqu xmm9, xmm15
mov eax, edx
mov ebx, edx
xor eax, 16
xor ebx, 32
xor edx, 48
movq xmm0, r11
movq xmm2, r10
punpcklqdq xmm2, xmm0
aesenc xmm9, xmm2
movdqu xmm0, XMMWORD PTR [rax+r13]
movdqu xmm1, XMMWORD PTR [rbx+r13]
paddq xmm0, xmm7
paddq xmm1, xmm2
movdqu XMMWORD PTR [rbx+r13], xmm0
movdqu xmm0, XMMWORD PTR [rdx+r13]
movdqu XMMWORD PTR [rdx+r13], xmm1
paddq xmm0, xmm3
movdqu XMMWORD PTR [rax+r13], xmm0
movq r11, xmm9
mov edx, r11d
and edx, 2097136
movdqa xmm0, xmm9
pxor xmm0, xmm7
movdqu XMMWORD PTR [r9], xmm0
lea rbx, QWORD PTR [rdx+r13]
mov r10, QWORD PTR [rdx+r13]
movdqu xmm10, xmm11
movq xmm0, rbp
movq xmm11, rdi
punpcklqdq xmm11, xmm0
aesenc xmm10, xmm11
mov eax, ecx
mov r12d, ecx
xor eax, 16
xor r12d, 32
xor ecx, 48
movdqu xmm0, XMMWORD PTR [rax+rsi]
paddq xmm0, xmm6
movdqu xmm1, XMMWORD PTR [r12+rsi]
movdqu XMMWORD PTR [r12+rsi], xmm0
paddq xmm1, xmm11
movdqu xmm0, XMMWORD PTR [rcx+rsi]
movdqu XMMWORD PTR [rcx+rsi], xmm1
paddq xmm0, xmm8
movdqu XMMWORD PTR [rax+rsi], xmm0
movq rcx, xmm10
and ecx, 2097136
movdqa xmm0, xmm10
pxor xmm0, xmm6
movdqu XMMWORD PTR [r8], xmm0
mov r12, QWORD PTR [rcx+rsi]
mov r9, QWORD PTR [rbx+8]
xor edx, 16
mov r8d, edx
mov r15d, edx
movq rdx, xmm5
shl rdx, 32
movq rax, xmm4
xor rdx, rax
xor r10, rdx
mov rax, r10
mul r11
mov r11d, r8d
xor r11d, 48
movq xmm0, rdx
xor rdx, [r11+r13]
movq xmm1, rax
xor rax, [r11+r13+8]
punpcklqdq xmm0, xmm1
pxor xmm0, XMMWORD PTR [r8+r13]
xor r8d, 32
movdqu xmm1, XMMWORD PTR [r11+r13]
paddq xmm0, xmm7
paddq xmm1, xmm2
movdqu XMMWORD PTR [r11+r13], xmm0
movdqu xmm0, XMMWORD PTR [r8+r13]
movdqu XMMWORD PTR [r8+r13], xmm1
paddq xmm0, xmm3
movdqu XMMWORD PTR [r15+r13], xmm0
mov r11, QWORD PTR [rsp+256]
add r11, rdx
mov rdx, QWORD PTR [rsp+264]
add rdx, rax
mov QWORD PTR [rbx], r11
xor r11, r10
mov QWORD PTR [rbx+8], rdx
xor rdx, r9
mov QWORD PTR [rsp+256], r11
and r11d, 2097136
mov QWORD PTR [rsp+264], rdx
mov QWORD PTR [rsp+8], r11
lea r15, QWORD PTR [r11+r13]
movdqu xmm15, XMMWORD PTR [r11+r13]
lea r13, QWORD PTR [rsi+rcx]
movdqa xmm0, xmm5
psrldq xmm0, 8
movaps xmm2, xmm13
movq r10, xmm0
psllq xmm5, 1
shl r10, 32
movdqa xmm0, xmm9
psrldq xmm0, 8
movdqa xmm1, xmm10
movq r11, xmm0
psrldq xmm1, 8
movq r8, xmm1
psrldq xmm4, 8
movaps xmm0, xmm13
movq rax, xmm4
xor r10, rax
movaps xmm1, xmm13
xor r10, r12
lea rax, QWORD PTR [r11+1]
shr rax, 1
movdqa xmm3, xmm9
punpcklqdq xmm3, xmm10
paddq xmm5, xmm3
movq rdx, xmm5
psrldq xmm5, 8
cvtsi2sd xmm2, rax
or edx, -2147483647
lea rax, QWORD PTR [r8+1]
shr rax, 1
movq r9, xmm5
cvtsi2sd xmm0, rax
or r9d, -2147483647
cvtsi2sd xmm1, rdx
unpcklpd xmm2, xmm0
movaps xmm0, xmm13
cvtsi2sd xmm0, r9
unpcklpd xmm1, xmm0
divpd xmm2, xmm1
paddq xmm2, xmm14
cvttsd2si rax, xmm2
psrldq xmm2, 8
mov rbx, rax
imul rax, rdx
sub r11, rax
js div_fix_1_sandybridge
div_fix_1_ret_sandybridge:
cvttsd2si rdx, xmm2
mov rax, rdx
imul rax, r9
movd xmm2, r11d
movd xmm4, ebx
sub r8, rax
js div_fix_2_sandybridge
div_fix_2_ret_sandybridge:
movd xmm1, r8d
movd xmm0, edx
punpckldq xmm2, xmm1
punpckldq xmm4, xmm0
punpckldq xmm4, xmm2
paddq xmm3, xmm4
movdqa xmm0, xmm3
psrlq xmm0, 12
paddq xmm0, xmm12
sqrtpd xmm1, xmm0
movq r9, xmm1
movdqa xmm5, xmm1
psrlq xmm5, 19
test r9, 524287
je sqrt_fix_1_sandybridge
sqrt_fix_1_ret_sandybridge:
movq r9, xmm10
psrldq xmm1, 8
movq r8, xmm1
test r8, 524287
je sqrt_fix_2_sandybridge
sqrt_fix_2_ret_sandybridge:
mov r12d, ecx
mov r8d, ecx
xor r12d, 16
xor r8d, 32
xor ecx, 48
mov rax, r10
mul r9
movq xmm0, rax
movq xmm3, rdx
punpcklqdq xmm3, xmm0
movdqu xmm0, XMMWORD PTR [r12+rsi]
pxor xmm0, xmm3
movdqu xmm1, XMMWORD PTR [r8+rsi]
xor rdx, [r8+rsi]
xor rax, [r8+rsi+8]
movdqu xmm3, XMMWORD PTR [rcx+rsi]
paddq xmm0, xmm6
paddq xmm1, xmm11
paddq xmm3, xmm8
movdqu XMMWORD PTR [r8+rsi], xmm0
movdqu XMMWORD PTR [rcx+rsi], xmm1
movdqu XMMWORD PTR [r12+rsi], xmm3
add rdi, rdx
mov QWORD PTR [r13], rdi
xor rdi, r10
mov ecx, edi
and ecx, 2097136
lea r8, QWORD PTR [rcx+rsi]
mov rdx, QWORD PTR [r13+8]
add rbp, rax
mov QWORD PTR [r13+8], rbp
movdqu xmm11, XMMWORD PTR [rcx+rsi]
xor rbp, rdx
mov r13, QWORD PTR [rsp]
movdqa xmm3, xmm7
mov rdx, QWORD PTR [rsp+8]
movdqa xmm8, xmm6
mov r10, QWORD PTR [rsp+256]
movdqa xmm7, xmm9
mov r11, QWORD PTR [rsp+264]
movdqa xmm6, xmm10
mov r9, r15
dec r14d
jne main_loop_double_sandybridge
ldmxcsr DWORD PTR [rsp+272]
movaps xmm13, XMMWORD PTR [rsp+48]
lea r11, QWORD PTR [rsp+184]
movaps xmm6, XMMWORD PTR [r11-24]
movaps xmm7, XMMWORD PTR [r11-40]
movaps xmm8, XMMWORD PTR [r11-56]
movaps xmm9, XMMWORD PTR [r11-72]
movaps xmm10, XMMWORD PTR [r11-88]
movaps xmm11, XMMWORD PTR [r11-104]
movaps xmm12, XMMWORD PTR [r11-120]
movaps xmm14, XMMWORD PTR [rsp+32]
movaps xmm15, XMMWORD PTR [rsp+16]
mov rsp, r11
pop r15
pop r14
pop r13
pop r12
pop rdi
pop rsi
pop rbp
pop rbx
jmp cnv2_double_mainloop_asm_sandybridge_endp
div_fix_1_sandybridge:
dec rbx
add r11, rdx
jmp div_fix_1_ret_sandybridge
div_fix_2_sandybridge:
dec rdx
add r8, r9
jmp div_fix_2_ret_sandybridge
sqrt_fix_1_sandybridge:
movq r8, xmm3
movdqa xmm0, xmm5
psrldq xmm0, 8
dec r9
mov r11d, -1022
shl r11, 32
mov rax, r9
shr r9, 19
shr rax, 20
mov rdx, r9
sub rdx, rax
lea rdx, [rdx+r11+1]
add rax, r11
imul rdx, rax
sub rdx, r8
adc r9, 0
movq xmm5, r9
punpcklqdq xmm5, xmm0
jmp sqrt_fix_1_ret_sandybridge
sqrt_fix_2_sandybridge:
psrldq xmm3, 8
movq r11, xmm3
dec r8
mov ebx, -1022
shl rbx, 32
mov rax, r8
shr r8, 19
shr rax, 20
mov rdx, r8
sub rdx, rax
lea rdx, [rdx+rbx+1]
add rax, rbx
imul rdx, rax
sub rdx, r11
adc r8, 0
movq xmm0, r8
punpcklqdq xmm5, xmm0
jmp sqrt_fix_2_ret_sandybridge
cnv2_double_mainloop_asm_sandybridge_endp:

View file

@ -0,0 +1,37 @@
#define ALIGN .align
.intel_syntax noprefix
#ifdef __APPLE__
# define FN_PREFIX(fn) _ ## fn
.text
#else
# define FN_PREFIX(fn) fn
.section .text
#endif
.global FN_PREFIX(cnv2_mainloop_ivybridge_asm)
.global FN_PREFIX(cnv2_mainloop_ryzen_asm)
.global FN_PREFIX(cnv2_double_mainloop_sandybridge_asm)
ALIGN 16
FN_PREFIX(cnv2_mainloop_ivybridge_asm):
sub rsp, 48
mov rcx, rdi
#include "cnv2_main_loop_ivybridge.inc"
add rsp, 48
ret 0
ALIGN 16
FN_PREFIX(cnv2_mainloop_ryzen_asm):
sub rsp, 48
mov rcx, rdi
#include "cnv2_main_loop_ryzen.inc"
add rsp, 48
ret 0
ALIGN 16
FN_PREFIX(cnv2_double_mainloop_sandybridge_asm):
sub rsp, 48
mov rcx, rdi
mov rdx, rsi
#include "cnv2_double_main_loop_sandybridge.inc"
add rsp, 48
ret 0

View file

@ -0,0 +1,25 @@
_TEXT_CNV2_MAINLOOP SEGMENT PAGE READ EXECUTE
PUBLIC cnv2_mainloop_ivybridge_asm
PUBLIC cnv2_mainloop_ryzen_asm
PUBLIC cnv2_double_mainloop_sandybridge_asm
ALIGN 64
cnv2_mainloop_ivybridge_asm PROC
INCLUDE cnv2_main_loop_ivybridge.inc
ret 0
cnv2_mainloop_ivybridge_asm ENDP
ALIGN 64
cnv2_mainloop_ryzen_asm PROC
INCLUDE cnv2_main_loop_ryzen.inc
ret 0
cnv2_mainloop_ryzen_asm ENDP
ALIGN 64
cnv2_double_mainloop_sandybridge_asm PROC
INCLUDE cnv2_double_main_loop_sandybridge.inc
ret 0
cnv2_double_mainloop_sandybridge_asm ENDP
_TEXT_CNV2_MAINLOOP ENDS
END

View file

@ -0,0 +1,186 @@
mov QWORD PTR [rsp+24], rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 80
stmxcsr DWORD PTR [rsp]
mov DWORD PTR [rsp+4], 24448
ldmxcsr DWORD PTR [rsp+4]
mov rax, QWORD PTR [rcx+48]
mov r9, rcx
xor rax, QWORD PTR [rcx+16]
mov esi, 524288
mov r8, QWORD PTR [rcx+32]
mov r13d, -2147483647
xor r8, QWORD PTR [rcx]
mov r11, QWORD PTR [rcx+40]
mov r10, r8
mov rdx, QWORD PTR [rcx+56]
movq xmm4, rax
xor rdx, QWORD PTR [rcx+24]
xor r11, QWORD PTR [rcx+8]
mov rbx, QWORD PTR [rcx+224]
mov rax, QWORD PTR [r9+80]
xor rax, QWORD PTR [r9+64]
movq xmm0, rdx
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r9+72]
movq xmm3, QWORD PTR [r9+104]
movaps XMMWORD PTR [rsp+64], xmm6
movaps XMMWORD PTR [rsp+48], xmm7
movaps XMMWORD PTR [rsp+32], xmm8
and r10d, 2097136
movq xmm5, rax
xor eax, eax
mov QWORD PTR [rsp+16], rax
mov ax, 1023
shl rax, 52
movq xmm8, rax
mov r15, QWORD PTR [r9+96]
punpcklqdq xmm4, xmm0
movq xmm0, rcx
punpcklqdq xmm5, xmm0
movdqu xmm6, XMMWORD PTR [r10+rbx]
ALIGN 16
main_loop_ivybridge:
lea rdx, QWORD PTR [r10+rbx]
mov ecx, r10d
mov eax, r10d
mov rdi, r15
xor ecx, 16
xor eax, 32
xor r10d, 48
movq xmm0, r11
movq xmm7, r8
punpcklqdq xmm7, xmm0
aesenc xmm6, xmm7
movq rbp, xmm6
mov r9, rbp
and r9d, 2097136
movdqu xmm2, XMMWORD PTR [rcx+rbx]
movdqu xmm1, XMMWORD PTR [rax+rbx]
movdqu xmm0, XMMWORD PTR [r10+rbx]
paddq xmm1, xmm7
paddq xmm0, xmm5
paddq xmm2, xmm4
movdqu XMMWORD PTR [rcx+rbx], xmm0
movdqu XMMWORD PTR [rax+rbx], xmm2
movdqu XMMWORD PTR [r10+rbx], xmm1
mov r10, r9
xor r10d, 32
movq rcx, xmm3
mov rax, rcx
shl rax, 32
xor rdi, rax
movdqa xmm0, xmm6
pxor xmm0, xmm4
movdqu XMMWORD PTR [rdx], xmm0
xor rdi, QWORD PTR [r9+rbx]
lea r14, QWORD PTR [r9+rbx]
mov r12, QWORD PTR [r14+8]
xor edx, edx
lea r9d, DWORD PTR [ecx+ecx]
add r9d, ebp
movdqa xmm0, xmm6
psrldq xmm0, 8
or r9d, r13d
movq rax, xmm0
div r9
xorps xmm3, xmm3
mov eax, eax
shl rdx, 32
add rdx, rax
lea r9, QWORD PTR [rdx+rbp]
mov r15, rdx
mov rax, r9
shr rax, 12
movq xmm0, rax
paddq xmm0, xmm8
sqrtsd xmm3, xmm0
psubq xmm3, XMMWORD PTR [rsp+16]
movq rdx, xmm3
test edx, 524287
je sqrt_fixup_ivybridge
psrlq xmm3, 19
sqrt_fixup_ivybridge_ret:
mov ecx, r10d
mov rax, rdi
mul rbp
movq xmm2, rdx
xor rdx, [rcx+rbx]
add r8, rdx
mov QWORD PTR [r14], r8
xor r8, rdi
mov edi, r8d
and edi, 2097136
movq xmm0, rax
xor rax, [rcx+rbx+8]
add r11, rax
mov QWORD PTR [r14+8], r11
punpcklqdq xmm2, xmm0
mov r9d, r10d
xor r9d, 48
xor r10d, 16
pxor xmm2, XMMWORD PTR [r9+rbx]
movdqu xmm0, XMMWORD PTR [r10+rbx]
paddq xmm0, xmm5
movdqu xmm1, XMMWORD PTR [rcx+rbx]
paddq xmm2, xmm4
paddq xmm1, xmm7
movdqa xmm5, xmm4
movdqu XMMWORD PTR [r9+rbx], xmm0
movdqa xmm4, xmm6
movdqu XMMWORD PTR [rcx+rbx], xmm2
movdqu XMMWORD PTR [r10+rbx], xmm1
movdqu xmm6, [rdi+rbx]
mov r10d, edi
xor r11, r12
dec rsi
jne main_loop_ivybridge
ldmxcsr DWORD PTR [rsp]
mov rbx, QWORD PTR [rsp+160]
movaps xmm6, XMMWORD PTR [rsp+64]
movaps xmm7, XMMWORD PTR [rsp+48]
movaps xmm8, XMMWORD PTR [rsp+32]
add rsp, 80
pop r15
pop r14
pop r13
pop r12
pop rdi
pop rsi
pop rbp
jmp cnv2_main_loop_ivybridge_endp
sqrt_fixup_ivybridge:
dec rdx
mov r13d, -1022
shl r13, 32
mov rax, rdx
shr rdx, 19
shr rax, 20
mov rcx, rdx
sub rcx, rax
add rax, r13
not r13
sub rcx, r13
mov r13d, -2147483647
imul rcx, rax
sub rcx, r9
adc rdx, 0
movq xmm3, rdx
jmp sqrt_fixup_ivybridge_ret
cnv2_main_loop_ivybridge_endp:

View file

@ -0,0 +1,179 @@
mov QWORD PTR [rsp+16], rbx
mov QWORD PTR [rsp+24], rbp
mov QWORD PTR [rsp+32], rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 64
stmxcsr DWORD PTR [rsp]
mov DWORD PTR [rsp+4], 24448
ldmxcsr DWORD PTR [rsp+4]
mov rax, QWORD PTR [rcx+48]
mov r9, rcx
xor rax, QWORD PTR [rcx+16]
mov ebp, 524288
mov r8, QWORD PTR [rcx+32]
xor r8, QWORD PTR [rcx]
mov r11, QWORD PTR [rcx+40]
mov r10, r8
mov rdx, QWORD PTR [rcx+56]
movq xmm3, rax
xor rdx, QWORD PTR [rcx+24]
xor r11, QWORD PTR [rcx+8]
mov rbx, QWORD PTR [rcx+224]
mov rax, QWORD PTR [r9+80]
xor rax, QWORD PTR [r9+64]
movq xmm0, rdx
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r9+72]
mov rdi, QWORD PTR [r9+104]
and r10d, 2097136
movaps XMMWORD PTR [rsp+48], xmm6
movq xmm4, rax
movaps XMMWORD PTR [rsp+32], xmm7
movaps XMMWORD PTR [rsp+16], xmm8
xorps xmm8, xmm8
mov ax, 1023
shl rax, 52
movq xmm7, rax
mov r15, QWORD PTR [r9+96]
punpcklqdq xmm3, xmm0
movq xmm0, rcx
punpcklqdq xmm4, xmm0
ALIGN 16
main_loop_ryzen:
movdqa xmm5, XMMWORD PTR [r10+rbx]
movq xmm0, r11
movq xmm6, r8
punpcklqdq xmm6, xmm0
lea rdx, QWORD PTR [r10+rbx]
lea r9, QWORD PTR [rdi+rdi]
shl rdi, 32
mov ecx, r10d
mov eax, r10d
xor ecx, 16
xor eax, 32
xor r10d, 48
aesenc xmm5, xmm6
movdqa xmm2, XMMWORD PTR [rcx+rbx]
movdqa xmm1, XMMWORD PTR [rax+rbx]
movdqa xmm0, XMMWORD PTR [r10+rbx]
paddq xmm2, xmm3
paddq xmm1, xmm6
paddq xmm0, xmm4
movdqa XMMWORD PTR [rcx+rbx], xmm0
movdqa XMMWORD PTR [rax+rbx], xmm2
movdqa XMMWORD PTR [r10+rbx], xmm1
movaps xmm1, xmm8
mov rsi, r15
xor rsi, rdi
movq r14, xmm5
movdqa xmm0, xmm5
pxor xmm0, xmm3
mov r10, r14
and r10d, 2097136
movdqa XMMWORD PTR [rdx], xmm0
xor rsi, QWORD PTR [r10+rbx]
lea r12, QWORD PTR [r10+rbx]
mov r13, QWORD PTR [r10+rbx+8]
add r9d, r14d
or r9d, -2147483647
xor edx, edx
movdqa xmm0, xmm5
psrldq xmm0, 8
movq rax, xmm0
div r9
movq xmm0, rax
movq xmm1, rdx
punpckldq xmm0, xmm1
movq r15, xmm0
paddq xmm0, xmm5
movdqa xmm2, xmm0
psrlq xmm0, 12
paddq xmm0, xmm7
sqrtsd xmm1, xmm0
movq rdi, xmm1
test rdi, 524287
je sqrt_fixup_ryzen
shr rdi, 19
sqrt_fixup_ryzen_ret:
mov rax, rsi
mul r14
movq xmm1, rax
movq xmm0, rdx
punpcklqdq xmm0, xmm1
mov r9d, r10d
mov ecx, r10d
xor r9d, 16
xor ecx, 32
xor r10d, 48
movdqa xmm1, XMMWORD PTR [rcx+rbx]
xor rdx, [rcx+rbx]
xor rax, [rcx+rbx+8]
movdqa xmm2, XMMWORD PTR [r9+rbx]
pxor xmm2, xmm0
paddq xmm4, XMMWORD PTR [r10+rbx]
paddq xmm2, xmm3
paddq xmm1, xmm6
movdqa XMMWORD PTR [r9+rbx], xmm4
movdqa XMMWORD PTR [rcx+rbx], xmm2
movdqa XMMWORD PTR [r10+rbx], xmm1
movdqa xmm4, xmm3
add r8, rdx
add r11, rax
mov QWORD PTR [r12], r8
xor r8, rsi
mov QWORD PTR [r12+8], r11
mov r10, r8
xor r11, r13
and r10d, 2097136
movdqa xmm3, xmm5
dec ebp
jne main_loop_ryzen
ldmxcsr DWORD PTR [rsp]
movaps xmm6, XMMWORD PTR [rsp+48]
lea r11, QWORD PTR [rsp+64]
mov rbx, QWORD PTR [r11+56]
mov rbp, QWORD PTR [r11+64]
mov rsi, QWORD PTR [r11+72]
movaps xmm8, XMMWORD PTR [r11-48]
movaps xmm7, XMMWORD PTR [rsp+32]
mov rsp, r11
pop r15
pop r14
pop r13
pop r12
pop rdi
jmp cnv2_main_loop_ryzen_endp
sqrt_fixup_ryzen:
movq r9, xmm2
dec rdi
mov edx, -1022
shl rdx, 32
mov rax, rdi
shr rdi, 19
shr rax, 20
mov rcx, rdi
sub rcx, rax
lea rcx, [rcx+rdx+1]
add rax, rdx
imul rcx, rax
sub rcx, r9
adc rdi, 0
jmp sqrt_fixup_ryzen_ret
cnv2_main_loop_ryzen_endp:

View file

@ -0,0 +1,410 @@
mov rax, rsp
push rbx
push rbp
push rsi
push rdi
push r12
push r13
push r14
push r15
sub rsp, 184
stmxcsr DWORD PTR [rsp+272]
mov DWORD PTR [rsp+276], 24448
ldmxcsr DWORD PTR [rsp+276]
mov r13, QWORD PTR [rcx+224]
mov r9, rdx
mov r10, QWORD PTR [rcx+32]
mov r8, rcx
xor r10, QWORD PTR [rcx]
mov r14d, 524288
mov r11, QWORD PTR [rcx+40]
xor r11, QWORD PTR [rcx+8]
mov rsi, QWORD PTR [rdx+224]
mov rdx, QWORD PTR [rcx+56]
xor rdx, QWORD PTR [rcx+24]
mov rdi, QWORD PTR [r9+32]
xor rdi, QWORD PTR [r9]
mov rbp, QWORD PTR [r9+40]
xor rbp, QWORD PTR [r9+8]
movd xmm0, rdx
movaps XMMWORD PTR [rax-88], xmm6
movaps XMMWORD PTR [rax-104], xmm7
movaps XMMWORD PTR [rax-120], xmm8
movaps XMMWORD PTR [rsp+112], xmm9
movaps XMMWORD PTR [rsp+96], xmm10
movaps XMMWORD PTR [rsp+80], xmm11
movaps XMMWORD PTR [rsp+64], xmm12
movaps XMMWORD PTR [rsp+48], xmm13
movaps XMMWORD PTR [rsp+32], xmm14
movaps XMMWORD PTR [rsp+16], xmm15
mov rdx, r10
movd xmm4, QWORD PTR [r8+96]
and edx, 2097136
mov rax, QWORD PTR [rcx+48]
xorps xmm13, xmm13
xor rax, QWORD PTR [rcx+16]
mov rcx, QWORD PTR [rcx+88]
xor rcx, QWORD PTR [r8+72]
movd xmm5, QWORD PTR [r8+104]
movd xmm7, rax
mov eax, 1
shl rax, 52
movd xmm14, rax
punpcklqdq xmm14, xmm14
mov eax, 1023
shl rax, 52
movd xmm12, rax
punpcklqdq xmm12, xmm12
mov rax, QWORD PTR [r8+80]
xor rax, QWORD PTR [r8+64]
punpcklqdq xmm7, xmm0
movd xmm0, rcx
mov rcx, QWORD PTR [r9+56]
xor rcx, QWORD PTR [r9+24]
movd xmm3, rax
mov rax, QWORD PTR [r9+48]
xor rax, QWORD PTR [r9+16]
punpcklqdq xmm3, xmm0
movd xmm0, rcx
mov QWORD PTR [rsp], r13
mov rcx, QWORD PTR [r9+88]
xor rcx, QWORD PTR [r9+72]
movd xmm6, rax
mov rax, QWORD PTR [r9+80]
xor rax, QWORD PTR [r9+64]
punpcklqdq xmm6, xmm0
movd xmm0, rcx
mov QWORD PTR [rsp+256], r10
mov rcx, rdi
mov QWORD PTR [rsp+264], r11
movd xmm8, rax
and ecx, 2097136
punpcklqdq xmm8, xmm0
movd xmm0, QWORD PTR [r9+96]
punpcklqdq xmm4, xmm0
movd xmm0, QWORD PTR [r9+104]
lea r8, QWORD PTR [rcx+rsi]
movdqu xmm11, XMMWORD PTR [r8]
punpcklqdq xmm5, xmm0
lea r9, QWORD PTR [rdx+r13]
movdqu xmm15, XMMWORD PTR [r9]
ALIGN 16
main_loop_double_sandybridge:
movdqu xmm9, xmm15
mov eax, edx
mov ebx, edx
xor eax, 16
xor ebx, 32
xor edx, 48
movd xmm0, r11
movd xmm2, r10
punpcklqdq xmm2, xmm0
aesenc xmm9, xmm2
movdqu xmm0, XMMWORD PTR [rax+r13]
movdqu xmm1, XMMWORD PTR [rbx+r13]
paddq xmm0, xmm7
paddq xmm1, xmm2
movdqu XMMWORD PTR [rbx+r13], xmm0
movdqu xmm0, XMMWORD PTR [rdx+r13]
movdqu XMMWORD PTR [rdx+r13], xmm1
paddq xmm0, xmm3
movdqu XMMWORD PTR [rax+r13], xmm0
movd r11, xmm9
mov edx, r11d
and edx, 2097136
movdqa xmm0, xmm9
pxor xmm0, xmm7
movdqu XMMWORD PTR [r9], xmm0
lea rbx, QWORD PTR [rdx+r13]
mov r10, QWORD PTR [rdx+r13]
movdqu xmm10, xmm11
movd xmm0, rbp
movd xmm11, rdi
punpcklqdq xmm11, xmm0
aesenc xmm10, xmm11
mov eax, ecx
mov r12d, ecx
xor eax, 16
xor r12d, 32
xor ecx, 48
movdqu xmm0, XMMWORD PTR [rax+rsi]
paddq xmm0, xmm6
movdqu xmm1, XMMWORD PTR [r12+rsi]
movdqu XMMWORD PTR [r12+rsi], xmm0
paddq xmm1, xmm11
movdqu xmm0, XMMWORD PTR [rcx+rsi]
movdqu XMMWORD PTR [rcx+rsi], xmm1
paddq xmm0, xmm8
movdqu XMMWORD PTR [rax+rsi], xmm0
movd rcx, xmm10
and ecx, 2097136
movdqa xmm0, xmm10
pxor xmm0, xmm6
movdqu XMMWORD PTR [r8], xmm0
mov r12, QWORD PTR [rcx+rsi]
mov r9, QWORD PTR [rbx+8]
xor edx, 16
mov r8d, edx
mov r15d, edx
movd rdx, xmm5
shl rdx, 32
movd rax, xmm4
xor rdx, rax
xor r10, rdx
mov rax, r10
mul r11
mov r11d, r8d
xor r11d, 48
movd xmm0, rdx
xor rdx, [r11+r13]
movd xmm1, rax
xor rax, [r11+r13+8]
punpcklqdq xmm0, xmm1
pxor xmm0, XMMWORD PTR [r8+r13]
xor r8d, 32
movdqu xmm1, XMMWORD PTR [r11+r13]
paddq xmm0, xmm7
paddq xmm1, xmm2
movdqu XMMWORD PTR [r11+r13], xmm0
movdqu xmm0, XMMWORD PTR [r8+r13]
movdqu XMMWORD PTR [r8+r13], xmm1
paddq xmm0, xmm3
movdqu XMMWORD PTR [r15+r13], xmm0
mov r11, QWORD PTR [rsp+256]
add r11, rdx
mov rdx, QWORD PTR [rsp+264]
add rdx, rax
mov QWORD PTR [rbx], r11
xor r11, r10
mov QWORD PTR [rbx+8], rdx
xor rdx, r9
mov QWORD PTR [rsp+256], r11
and r11d, 2097136
mov QWORD PTR [rsp+264], rdx
mov QWORD PTR [rsp+8], r11
lea r15, QWORD PTR [r11+r13]
movdqu xmm15, XMMWORD PTR [r11+r13]
lea r13, QWORD PTR [rsi+rcx]
movdqa xmm0, xmm5
psrldq xmm0, 8
movaps xmm2, xmm13
movd r10, xmm0
psllq xmm5, 1
shl r10, 32
movdqa xmm0, xmm9
psrldq xmm0, 8
movdqa xmm1, xmm10
movd r11, xmm0
psrldq xmm1, 8
movd r8, xmm1
psrldq xmm4, 8
movaps xmm0, xmm13
movd rax, xmm4
xor r10, rax
movaps xmm1, xmm13
xor r10, r12
lea rax, QWORD PTR [r11+1]
shr rax, 1
movdqa xmm3, xmm9
punpcklqdq xmm3, xmm10
paddq xmm5, xmm3
movd rdx, xmm5
psrldq xmm5, 8
cvtsi2sd xmm2, rax
or edx, -2147483647
lea rax, QWORD PTR [r8+1]
shr rax, 1
movd r9, xmm5
cvtsi2sd xmm0, rax
or r9d, -2147483647
cvtsi2sd xmm1, rdx
unpcklpd xmm2, xmm0
movaps xmm0, xmm13
cvtsi2sd xmm0, r9
unpcklpd xmm1, xmm0
divpd xmm2, xmm1
paddq xmm2, xmm14
cvttsd2si rax, xmm2
psrldq xmm2, 8
mov rbx, rax
imul rax, rdx
sub r11, rax
js div_fix_1_sandybridge
div_fix_1_ret_sandybridge:
cvttsd2si rdx, xmm2
mov rax, rdx
imul rax, r9
movd xmm2, r11d
movd xmm4, ebx
sub r8, rax
js div_fix_2_sandybridge
div_fix_2_ret_sandybridge:
movd xmm1, r8d
movd xmm0, edx
punpckldq xmm2, xmm1
punpckldq xmm4, xmm0
punpckldq xmm4, xmm2
paddq xmm3, xmm4
movdqa xmm0, xmm3
psrlq xmm0, 12
paddq xmm0, xmm12
sqrtpd xmm1, xmm0
movd r9, xmm1
movdqa xmm5, xmm1
psrlq xmm5, 19
test r9, 524287
je sqrt_fix_1_sandybridge
sqrt_fix_1_ret_sandybridge:
movd r9, xmm10
psrldq xmm1, 8
movd r8, xmm1
test r8, 524287
je sqrt_fix_2_sandybridge
sqrt_fix_2_ret_sandybridge:
mov r12d, ecx
mov r8d, ecx
xor r12d, 16
xor r8d, 32
xor ecx, 48
mov rax, r10
mul r9
movd xmm0, rax
movd xmm3, rdx
punpcklqdq xmm3, xmm0
movdqu xmm0, XMMWORD PTR [r12+rsi]
pxor xmm0, xmm3
movdqu xmm1, XMMWORD PTR [r8+rsi]
xor rdx, [r8+rsi]
xor rax, [r8+rsi+8]
movdqu xmm3, XMMWORD PTR [rcx+rsi]
paddq xmm0, xmm6
paddq xmm1, xmm11
paddq xmm3, xmm8
movdqu XMMWORD PTR [r8+rsi], xmm0
movdqu XMMWORD PTR [rcx+rsi], xmm1
movdqu XMMWORD PTR [r12+rsi], xmm3
add rdi, rdx
mov QWORD PTR [r13], rdi
xor rdi, r10
mov ecx, edi
and ecx, 2097136
lea r8, QWORD PTR [rcx+rsi]
mov rdx, QWORD PTR [r13+8]
add rbp, rax
mov QWORD PTR [r13+8], rbp
movdqu xmm11, XMMWORD PTR [rcx+rsi]
xor rbp, rdx
mov r13, QWORD PTR [rsp]
movdqa xmm3, xmm7
mov rdx, QWORD PTR [rsp+8]
movdqa xmm8, xmm6
mov r10, QWORD PTR [rsp+256]
movdqa xmm7, xmm9
mov r11, QWORD PTR [rsp+264]
movdqa xmm6, xmm10
mov r9, r15
dec r14d
jne main_loop_double_sandybridge
ldmxcsr DWORD PTR [rsp+272]
movaps xmm13, XMMWORD PTR [rsp+48]
lea r11, QWORD PTR [rsp+184]
movaps xmm6, XMMWORD PTR [r11-24]
movaps xmm7, XMMWORD PTR [r11-40]
movaps xmm8, XMMWORD PTR [r11-56]
movaps xmm9, XMMWORD PTR [r11-72]
movaps xmm10, XMMWORD PTR [r11-88]
movaps xmm11, XMMWORD PTR [r11-104]
movaps xmm12, XMMWORD PTR [r11-120]
movaps xmm14, XMMWORD PTR [rsp+32]
movaps xmm15, XMMWORD PTR [rsp+16]
mov rsp, r11
pop r15
pop r14
pop r13
pop r12
pop rdi
pop rsi
pop rbp
pop rbx
jmp cnv2_double_mainloop_asm_sandybridge_endp
div_fix_1_sandybridge:
dec rbx
add r11, rdx
jmp div_fix_1_ret_sandybridge
div_fix_2_sandybridge:
dec rdx
add r8, r9
jmp div_fix_2_ret_sandybridge
sqrt_fix_1_sandybridge:
movd r8, xmm3
movdqa xmm0, xmm5
psrldq xmm0, 8
dec r9
mov r11d, -1022
shl r11, 32
mov rax, r9
shr r9, 19
shr rax, 20
mov rdx, r9
sub rdx, rax
lea rdx, [rdx+r11+1]
add rax, r11
imul rdx, rax
sub rdx, r8
adc r9, 0
movd xmm5, r9
punpcklqdq xmm5, xmm0
jmp sqrt_fix_1_ret_sandybridge
sqrt_fix_2_sandybridge:
psrldq xmm3, 8
movd r11, xmm3
dec r8
mov ebx, -1022
shl rbx, 32
mov rax, r8
shr r8, 19
shr rax, 20
mov rdx, r8
sub rdx, rax
lea rdx, [rdx+rbx+1]
add rax, rbx
imul rdx, rax
sub rdx, r11
adc r8, 0
movd xmm0, r8
punpcklqdq xmm5, xmm0
jmp sqrt_fix_2_ret_sandybridge
cnv2_double_mainloop_asm_sandybridge_endp:

View file

@ -0,0 +1,21 @@
#define ALIGN .align
.intel_syntax noprefix
.section .text
.global cnv2_mainloop_ivybridge_asm
.global cnv2_mainloop_ryzen_asm
.global cnv2_double_mainloop_sandybridge_asm
ALIGN 16
cnv2_mainloop_ivybridge_asm:
#include "../cnv2_main_loop_ivybridge.inc"
ret 0
ALIGN 16
cnv2_mainloop_ryzen_asm:
#include "../cnv2_main_loop_ryzen.inc"
ret 0
ALIGN 16
cnv2_double_mainloop_sandybridge_asm:
#include "../cnv2_double_main_loop_sandybridge.inc"
ret 0

View file

@ -0,0 +1,25 @@
_TEXT_CNV2_MAINLOOP SEGMENT PAGE READ EXECUTE
PUBLIC cnv2_mainloop_ivybridge_asm
PUBLIC cnv2_mainloop_ryzen_asm
PUBLIC cnv2_double_mainloop_sandybridge_asm
ALIGN 64
cnv2_mainloop_ivybridge_asm PROC
INCLUDE cnv2_main_loop_ivybridge.inc
ret 0
cnv2_mainloop_ivybridge_asm ENDP
ALIGN 64
cnv2_mainloop_ryzen_asm PROC
INCLUDE cnv2_main_loop_ryzen.inc
ret 0
cnv2_mainloop_ryzen_asm ENDP
ALIGN 64
cnv2_double_mainloop_sandybridge_asm PROC
INCLUDE cnv2_double_main_loop_sandybridge.inc
ret 0
cnv2_double_mainloop_sandybridge_asm ENDP
_TEXT_CNV2_MAINLOOP ENDS
END

Some files were not shown because too many files have changed in this diff Show more