mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-07 16:05:05 -05:00
Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
072881e1a1 | ||
|
|
0c4a3cfc30 | ||
|
|
cffd0f50a4 | ||
|
|
4b1857114e | ||
|
|
b49fb27e84 | ||
|
|
ee341118ce | ||
|
|
f599807bbb | ||
|
|
a2ad626012 | ||
|
|
e8a99809b6 | ||
|
|
0fe20fe88c | ||
|
|
d1d1517b4f | ||
|
|
5980675876 | ||
|
|
3b87cd97ce | ||
|
|
d2f01cfa86 | ||
|
|
82830e359a | ||
|
|
8e3fec5768 | ||
|
|
4fd23a1bf4 | ||
|
|
8bfaddd3fc | ||
|
|
dabafaaadb | ||
|
|
5cda714254 | ||
|
|
91151ce4a1 | ||
|
|
dc1443f3b8 | ||
|
|
8af8df25aa | ||
|
|
b1e14dc1d3 | ||
|
|
f460d76f8d | ||
|
|
1c63e9efba | ||
|
|
21abbe4e84 | ||
|
|
3080f47cd6 | ||
|
|
f4ebdaa8e5 | ||
|
|
1bcfd0cdea | ||
|
|
9396ecf93d | ||
|
|
a4af964696 | ||
|
|
2c8d8ee2ab | ||
|
|
631a8ca802 | ||
|
|
346892e170 | ||
|
|
db03573804 | ||
|
|
e74573f81f | ||
|
|
0e70974d7d | ||
|
|
3a3ee91324 | ||
|
|
4108428872 | ||
|
|
4c3425a958 | ||
|
|
09624c4f9b | ||
|
|
8faef28e7d | ||
|
|
62450f4ed8 | ||
|
|
2c52a5a352 | ||
|
|
7d52bd7454 | ||
|
|
f68b105bd9 | ||
|
|
9ca1a6129b | ||
|
|
7a3df1c0bb | ||
|
|
22a1b8d82d | ||
|
|
0a462fbef5 | ||
|
|
f302b4b0ef | ||
|
|
65fe26dc6c | ||
|
|
e6d4921e21 | ||
|
|
f82d67e76e | ||
|
|
4e671a945d | ||
|
|
e38d277143 | ||
|
|
8eb9b4d37a | ||
|
|
2d45cc64c1 | ||
|
|
b9081e992b | ||
|
|
1424b2975f | ||
|
|
0fa5db8fa3 | ||
|
|
5999dccd57 | ||
|
|
78922a0772 | ||
|
|
bc3914883a | ||
|
|
86dae9e149 | ||
|
|
05b2260393 | ||
|
|
672f6df6c1 | ||
|
|
9dae559b73 | ||
|
|
b9d813c403 | ||
|
|
c48e2e6af8 | ||
|
|
76fba819fe | ||
|
|
6bab624885 | ||
|
|
3730bcd434 | ||
|
|
3b7d30a91d | ||
|
|
c8588903e3 | ||
|
|
0b4fec15dd | ||
|
|
ef8cc28f3f | ||
|
|
8471f7fad3 | ||
|
|
b99dc440af | ||
|
|
9a02007900 | ||
|
|
efc5e5d811 | ||
|
|
dea5be0a57 | ||
|
|
24c290963a | ||
|
|
9dffcdaddd | ||
|
|
3df47052ed | ||
|
|
3b8d081c8c | ||
|
|
05e6f66169 | ||
|
|
11e0d3de3a | ||
|
|
ea367da064 | ||
|
|
a999a56775 | ||
|
|
590252bd5e | ||
|
|
cc2de4f768 | ||
|
|
aeea0e0a6c | ||
|
|
82d698a1e5 | ||
|
|
95b2b5e028 | ||
|
|
eae84d47e7 | ||
|
|
45d12314f4 | ||
|
|
fa11cb623d | ||
|
|
7da04c6a2c | ||
|
|
5c449913af | ||
|
|
af019fed8e | ||
|
|
8872630c46 | ||
|
|
d3ec21cbf5 | ||
|
|
395dd4086b | ||
|
|
a7f9808621 | ||
|
|
88862b617f | ||
|
|
39bfa0c420 | ||
|
|
f62f4e6108 | ||
|
|
9f128d1182 | ||
|
|
2f2b33c82b | ||
|
|
56280cb1d5 | ||
|
|
07127c6e87 | ||
|
|
3dabc77a09 | ||
|
|
66349e3d23 | ||
|
|
85a78ce537 | ||
|
|
0d9f17670e | ||
|
|
deb561a410 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,4 +1,6 @@
|
|||||||
/build
|
/build
|
||||||
|
scripts/build
|
||||||
|
scripts/deps
|
||||||
/CMakeLists.txt.user
|
/CMakeLists.txt.user
|
||||||
/.idea
|
/.idea
|
||||||
/src/backend/opencl/cl/cn/cryptonight_gen.cl
|
/src/backend/opencl/cl/cn/cryptonight_gen.cl
|
||||||
|
|||||||
34
CHANGELOG.md
34
CHANGELOG.md
@@ -1,3 +1,37 @@
|
|||||||
|
# v6.9.0
|
||||||
|
- [#2104](https://github.com/xmrig/xmrig/pull/2104) Added [pause-on-active](https://xmrig.com/docs/miner/config/misc#pause-on-active) config option and `--pause-on-active=N` command line option.
|
||||||
|
- [#2112](https://github.com/xmrig/xmrig/pull/2112) Added support for [Tari merge mining](https://github.com/tari-project/tari/blob/development/README.md#tari-merge-mining).
|
||||||
|
- [#2117](https://github.com/xmrig/xmrig/pull/2117) Fixed crash when GPU mining `cn-heavy` on Zen3 system.
|
||||||
|
|
||||||
|
# v6.8.2
|
||||||
|
- [#2080](https://github.com/xmrig/xmrig/pull/2080) Fixed compile error in Termux.
|
||||||
|
- [#2089](https://github.com/xmrig/xmrig/pull/2089) Optimized CryptoNight-Heavy for Zen3, 7-8% speedup.
|
||||||
|
|
||||||
|
# v6.8.1
|
||||||
|
- [#2064](https://github.com/xmrig/xmrig/pull/2064) Added documentation for config.json CPU options.
|
||||||
|
- [#2066](https://github.com/xmrig/xmrig/issues/2066) Fixed AMD GPUs health data readings on Linux.
|
||||||
|
- [#2067](https://github.com/xmrig/xmrig/pull/2067) Fixed compilation error when RandomX and Argon2 are disabled.
|
||||||
|
- [#2076](https://github.com/xmrig/xmrig/pull/2076) Added support for flexible huge page sizes on Linux.
|
||||||
|
- [#2077](https://github.com/xmrig/xmrig/pull/2077) Fixed `illegal instruction` crash on ARM.
|
||||||
|
|
||||||
|
# v6.8.0
|
||||||
|
- [#2052](https://github.com/xmrig/xmrig/pull/2052) Added DMI/SMBIOS reader.
|
||||||
|
- Added information about memory modules on the miner startup and for online benchmark.
|
||||||
|
- Added new HTTP API endpoint: `GET /2/dmi`.
|
||||||
|
- Added new command line option `--no-dmi` or config option `"dmi"`.
|
||||||
|
- Added new CMake option `-DWITH_DMI=OFF`.
|
||||||
|
- [#2057](https://github.com/xmrig/xmrig/pull/2057) Improved MSR subsystem code quality.
|
||||||
|
- [#2058](https://github.com/xmrig/xmrig/pull/2058) RandomX JIT x86: removed unnecessary instructions.
|
||||||
|
|
||||||
|
# v6.7.2
|
||||||
|
- [#2039](https://github.com/xmrig/xmrig/pull/2039) Fixed solo mining.
|
||||||
|
|
||||||
|
# v6.7.1
|
||||||
|
- [#1995](https://github.com/xmrig/xmrig/issues/1995) Fixed log initialization.
|
||||||
|
- [#1998](https://github.com/xmrig/xmrig/pull/1998) Added hashrate in the benchmark finished message.
|
||||||
|
- [#2009](https://github.com/xmrig/xmrig/pull/2009) AstroBWT OpenCL fixes.
|
||||||
|
- [#2028](https://github.com/xmrig/xmrig/pull/2028) RandomX x86 JIT: removed redundant `CFROUND`.
|
||||||
|
|
||||||
# v6.7.0
|
# v6.7.0
|
||||||
- **[#1991](https://github.com/xmrig/xmrig/issues/1991) Added Apple M1 processor support.**
|
- **[#1991](https://github.com/xmrig/xmrig/issues/1991) Added Apple M1 processor support.**
|
||||||
- **[#1986](https://github.com/xmrig/xmrig/pull/1986) Up to 20-30% faster RandomX dataset initialization with AVX2 on some CPUs.**
|
- **[#1986](https://github.com/xmrig/xmrig/pull/1986) Up to 20-30% faster RandomX dataset initialization with AVX2 on some CPUs.**
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ option(WITH_PROFILING "Enable profiling for developers" OFF)
|
|||||||
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
|
option(WITH_SSE4_1 "Enable SSE 4.1 for Blake2" ON)
|
||||||
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
|
option(WITH_BENCHMARK "Enable builtin RandomX benchmark and stress test" ON)
|
||||||
option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF)
|
option(WITH_SECURE_JIT "Enable secure access to JIT memory" OFF)
|
||||||
|
option(WITH_DMI "Enable DMI/SMBIOS reader" ON)
|
||||||
|
|
||||||
option(BUILD_STATIC "Build static binary" OFF)
|
option(BUILD_STATIC "Build static binary" OFF)
|
||||||
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
|
option(ARM_TARGET "Force use specific ARM target 8 or 7" 0)
|
||||||
@@ -146,8 +147,10 @@ elseif (XMRIG_OS_APPLE)
|
|||||||
src/App_unix.cpp
|
src/App_unix.cpp
|
||||||
src/crypto/common/VirtualMemory_unix.cpp
|
src/crypto/common/VirtualMemory_unix.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
find_library(IOKIT_LIBRARY IOKit)
|
find_library(IOKIT_LIBRARY IOKit)
|
||||||
set(EXTRA_LIBS ${IOKIT_LIBRARY})
|
find_library(CORESERVICES_LIBRARY CoreServices)
|
||||||
|
set(EXTRA_LIBS ${IOKIT_LIBRARY} ${CORESERVICES_LIBRARY})
|
||||||
else()
|
else()
|
||||||
list(APPEND SOURCES_OS
|
list(APPEND SOURCES_OS
|
||||||
src/App_unix.cpp
|
src/App_unix.cpp
|
||||||
@@ -169,7 +172,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(-DXMRIG_MINER_PROJECT -DXMRIG_JSON_SINGLE_LINE_ARRAY)
|
add_definitions(-DXMRIG_MINER_PROJECT -DXMRIG_JSON_SINGLE_LINE_ARRAY)
|
||||||
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE)
|
add_definitions(-D__STDC_FORMAT_MACROS -DUNICODE -D_FILE_OFFSET_BITS=64)
|
||||||
|
|
||||||
find_package(UV REQUIRED)
|
find_package(UV REQUIRED)
|
||||||
|
|
||||||
@@ -197,6 +200,9 @@ if (WITH_EMBEDDED_CONFIG)
|
|||||||
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
|
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(src/hw/api/api.cmake)
|
||||||
|
include(src/hw/dmi/dmi.cmake)
|
||||||
|
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
include_directories(src/3rdparty)
|
include_directories(src/3rdparty)
|
||||||
include_directories(${UV_INCLUDE_DIR})
|
include_directories(${UV_INCLUDE_DIR})
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ XMRig is a high performance, open source, cross platform RandomX, KawPow, Crypto
|
|||||||
* **[Build from source](https://xmrig.com/docs/miner/build)**
|
* **[Build from source](https://xmrig.com/docs/miner/build)**
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
The preferred way to configure the miner is the [JSON config file](src/config.json) as it is more flexible and human friendly. The [command line interface](https://xmrig.com/docs/miner/command-line-options) does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing API calls.
|
The preferred way to configure the miner is the [JSON config file](https://xmrig.com/docs/miner/config) as it is more flexible and human friendly. The [command line interface](https://xmrig.com/docs/miner/command-line-options) does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing [API](https://xmrig.com/docs/miner/api) calls.
|
||||||
|
|
||||||
* **[Wizard](https://xmrig.com/wizard)** helps you create initial configuration for the miner.
|
* **[Wizard](https://xmrig.com/wizard)** helps you create initial configuration for the miner.
|
||||||
* **[Workers](http://workers.xmrig.info)** helps manage your miners via HTTP API.
|
* **[Workers](http://workers.xmrig.info)** helps manage your miners via HTTP API.
|
||||||
|
|||||||
@@ -100,13 +100,29 @@ if (WITH_RANDOMX)
|
|||||||
message("-- WITH_MSR=ON")
|
message("-- WITH_MSR=ON")
|
||||||
|
|
||||||
if (XMRIG_OS_WIN)
|
if (XMRIG_OS_WIN)
|
||||||
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_win.cpp)
|
list(APPEND SOURCES_CRYPTO
|
||||||
|
src/crypto/rx/RxFix_win.cpp
|
||||||
|
src/hw/msr/Msr_win.cpp
|
||||||
|
)
|
||||||
elseif (XMRIG_OS_LINUX)
|
elseif (XMRIG_OS_LINUX)
|
||||||
list(APPEND SOURCES_CRYPTO src/crypto/rx/Rx_linux.cpp)
|
list(APPEND SOURCES_CRYPTO
|
||||||
|
src/crypto/rx/RxFix_linux.cpp
|
||||||
|
src/hw/msr/Msr_linux.cpp
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND HEADERS_CRYPTO src/crypto/rx/msr/MsrItem.h)
|
list(APPEND HEADERS_CRYPTO
|
||||||
list(APPEND SOURCES_CRYPTO src/crypto/rx/msr/MsrItem.cpp)
|
src/crypto/rx/RxFix.h
|
||||||
|
src/crypto/rx/RxMsr.h
|
||||||
|
src/hw/msr/Msr.h
|
||||||
|
src/hw/msr/MsrItem.h
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND SOURCES_CRYPTO
|
||||||
|
src/crypto/rx/RxMsr.cpp
|
||||||
|
src/hw/msr/Msr.cpp
|
||||||
|
src/hw/msr/MsrItem.cpp
|
||||||
|
)
|
||||||
else()
|
else()
|
||||||
remove_definitions(/DXMRIG_FEATURE_MSR)
|
remove_definitions(/DXMRIG_FEATURE_MSR)
|
||||||
remove_definitions(/DXMRIG_FIX_RYZEN)
|
remove_definitions(/DXMRIG_FIX_RYZEN)
|
||||||
|
|||||||
56
doc/CPU.md
56
doc/CPU.md
@@ -1,3 +1,5 @@
|
|||||||
|
**:warning: Recent version of this page https://xmrig.com/docs/miner/config/cpu.**
|
||||||
|
|
||||||
# CPU backend
|
# CPU backend
|
||||||
|
|
||||||
All CPU related settings contains in one `cpu` object in config file, CPU backend allow specify multiple profiles and allow switch between them without restrictions by pool request or config change. Default auto-configuration create reasonable minimum of profiles which cover all supported algorithms.
|
All CPU related settings contains in one `cpu` object in config file, CPU backend allow specify multiple profiles and allow switch between them without restrictions by pool request or config change. Default auto-configuration create reasonable minimum of profiles which cover all supported algorithms.
|
||||||
@@ -75,6 +77,35 @@ Each number represent one thread and means CPU affinity, this is default format
|
|||||||
```
|
```
|
||||||
Internal format, but can be user defined.
|
Internal format, but can be user defined.
|
||||||
|
|
||||||
|
## RandomX options
|
||||||
|
|
||||||
|
#### `init`
|
||||||
|
Thread count to initialize RandomX dataset. Auto-detect (`-1`) or any number greater than 0 to use that many threads.
|
||||||
|
|
||||||
|
#### `init-avx2`
|
||||||
|
Use AVX2 for dataset initialization. Faster on some CPUs. Auto-detect (`-1`), disabled (`0`), always enabled on CPUs that support AVX2 (`1`).
|
||||||
|
|
||||||
|
#### `mode`
|
||||||
|
RandomX mining mode: `auto`, `fast` (2 GB memory), `light` (256 MB memory).
|
||||||
|
|
||||||
|
#### `1gb-pages`
|
||||||
|
Use 1GB hugepages for RandomX dataset (Linux only). Enabled (`true`) or disabled (`false`). It gives 1-3% speedup.
|
||||||
|
|
||||||
|
#### `rdmsr`
|
||||||
|
Restore MSR register values to their original values on exit. Used together with `wrmsr`. Enabled (`true`) or disabled (`false`).
|
||||||
|
|
||||||
|
#### `wrmsr`
|
||||||
|
[MSR mod](https://xmrig.com/docs/miner/randomx-optimization-guide/msr). Enabled (`true`) or disabled (`false`). It gives up to 15% speedup depending on your system.
|
||||||
|
|
||||||
|
#### `cache_qos`
|
||||||
|
[Cache QoS](https://xmrig.com/docs/miner/randomx-optimization-guide/qos). Enabled (`true`) or disabled (`false`). It's useful when you can't or don't want to mine on all CPU cores to make mining hashrate more stable.
|
||||||
|
|
||||||
|
#### `numa`
|
||||||
|
NUMA support (better hashrate on multi-CPU servers and Ryzen Threadripper 1xxx/2xxx). Enabled (`true`) or disabled (`false`).
|
||||||
|
|
||||||
|
#### `scratchpad_prefetch_mode`
|
||||||
|
Which instruction to use in RandomX loop to prefetch data from scratchpad. `1` is default and fastest in most cases. Can be off (`0`), `prefetcht0` instruction (`1`), `prefetchnta` instruction (`2`, a bit faster on Coffee Lake and a few other CPUs), `mov` instruction (`3`).
|
||||||
|
|
||||||
## Shared options
|
## Shared options
|
||||||
|
|
||||||
#### `enabled`
|
#### `enabled`
|
||||||
@@ -83,23 +114,32 @@ Enable (`true`) or disable (`false`) CPU backend, by default `true`.
|
|||||||
#### `huge-pages`
|
#### `huge-pages`
|
||||||
Enable (`true`) or disable (`false`) huge pages support, by default `true`.
|
Enable (`true`) or disable (`false`) huge pages support, by default `true`.
|
||||||
|
|
||||||
|
#### `huge-pages-jit`
|
||||||
|
Enable (`true`) or disable (`false`) huge pages support for RandomX JIT code, by default `false`. It gives a very small boost on Ryzen CPUs, but hashrate is unstable between launches. Use with caution.
|
||||||
|
|
||||||
#### `hw-aes`
|
#### `hw-aes`
|
||||||
Force enable (`true`) or disable (`false`) hardware AES support. Default value `null` means miner autodetect this feature. Usually don't need change this option, this option useful for some rare cases when miner can't detect hardware AES, but it available. If you force enable this option, but your hardware not support it, miner will crash.
|
Force enable (`true`) or disable (`false`) hardware AES support. Default value `null` means miner autodetect this feature. Usually don't need change this option, this option useful for some rare cases when miner can't detect hardware AES, but it available. If you force enable this option, but your hardware not support it, miner will crash.
|
||||||
|
|
||||||
#### `priority`
|
#### `priority`
|
||||||
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all.
|
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. Setting priority higher than 2 can make your PC unresponsive.
|
||||||
|
|
||||||
|
#### `memory-pool` (since v4.3.0)
|
||||||
|
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. It helps to avoid loosing huge pages for scratchpads when RandomX dataset is updated and mining threads restart after a 2-3 days of mining.
|
||||||
|
|
||||||
|
#### `yield` (since v5.1.1)
|
||||||
|
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.
|
||||||
|
|
||||||
#### `asm`
|
#### `asm`
|
||||||
Enable/configure or disable ASM optimizations. Possible values: `true`, `false`, `"intel"`, `"ryzen"`, `"bulldozer"`.
|
Enable/configure or disable ASM optimizations. Possible values: `true`, `false`, `"intel"`, `"ryzen"`, `"bulldozer"`.
|
||||||
|
|
||||||
#### `argon2-impl` (since v3.1.0)
|
#### `argon2-impl` (since v3.1.0)
|
||||||
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash.
|
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. This is used in RandomX dataset initialization and also in some other mining algorithms. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards - if your CPU doesn't support required instuctions, miner will crash.
|
||||||
|
|
||||||
|
#### `astrobwt-max-size`
|
||||||
|
AstroBWT algorithm: skip hashes with large stage 2 size, default: `550`, min: `400`, max: `1200`. Optimal value depends on your CPU/GPU
|
||||||
|
|
||||||
|
#### `astrobwt-avx2`
|
||||||
|
AstroBWT algorithm: use AVX2 code. It's faster on some CPUs and slower on other
|
||||||
|
|
||||||
#### `max-threads-hint` (since v4.2.0)
|
#### `max-threads-hint` (since v4.2.0)
|
||||||
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md)
|
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md)
|
||||||
|
|
||||||
#### `memory-pool` (since v4.3.0)
|
|
||||||
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages.
|
|
||||||
|
|
||||||
#### `yield` (since v5.1.1)
|
|
||||||
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
6bb1a2e3a0fbca5195be6022f2a9fbff8a353c37c7542e7ab89420cb45b64505 xmrig-5.0.1-gcc-win32.zip
|
|
||||||
24dba9ec281acfb2ea2c401ebd0e4e2d1f1ee5fd557da5ff3c7049020c1f78b6 xmrig-5.0.1-gcc-win64.zip
|
|
||||||
86d65c6693ec9e35cd7547329580638b85c9eb0cf8383892a1c15199de5b556f xmrig-5.0.1-msvc-cuda10_1-win64.zip
|
|
||||||
0fbfe518b1c4b6993b0f66ff01302626375b15620ccf8f64d6fb97845068ffca xmrig-5.0.1-msvc-win64.zip
|
|
||||||
aa34890738a3494de2fa0e44db346937fea7339852f5f10b5d4655f95e2d8f1f xmrig-5.0.1-xenial-x64.tar.gz
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQEzBAABCgAdFiEEmsTOqOZuNaXHzdwbRGpTY4vpRAkFAl3VcsoACgkQRGpTY4vp
|
|
||||||
RAm9vQgA1MyTUU2jley2TCYLUzQy2Fffc8fbXYv64r44jbWOjC/6qo2iIlRgPhIc
|
|
||||||
oVyPKr5TYS3QjDzCEm8IvozS0YudS6soESbPzqDonboK8pd0K4bsML9TQY2feV7A
|
|
||||||
NL5vln0rfVHp1wxLLrQpfBqAgvJUXEyaHece6gFQN79JOGhEo2bHL2NyrOl+FViS
|
|
||||||
b2BaMtXq410Fh+XT6ShnOaG/2EuO8ZqSGdCO6A/2LHQw1UY+mZiCvue6P6B06HmB
|
|
||||||
WD/urOv38V389v+V+Sp4UlEW6VpBOOjvtChoVWtLt+tKzydrnt2EmoWWWg475pka
|
|
||||||
4G6whHuMWS8CTt5/PDhJpvVXNQTIOw==
|
|
||||||
=C764
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2020 XMRig <support@xmrig.com>
|
* Copyright 2016-2021 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
|
||||||
@@ -39,6 +39,11 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_DMI
|
||||||
|
# include "hw/dmi/DmiReader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_RANDOMX
|
#ifdef XMRIG_ALGO_RANDOMX
|
||||||
# include "crypto/rx/RxConfig.h"
|
# include "crypto/rx/RxConfig.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -71,7 +76,7 @@ inline static const char *asmName(Assembly::Id assembly)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void print_memory(Config *config)
|
static void print_pages(const Config *config)
|
||||||
{
|
{
|
||||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
|
||||||
"HUGE PAGES", config->cpu().isHugePages() ? (VirtualMemory::isHugepagesAvailable() ? kHugepagesSupported : RED_BOLD("unavailable")) : RED_BOLD("disabled"));
|
"HUGE PAGES", config->cpu().isHugePages() ? (VirtualMemory::isHugepagesAvailable() ? kHugepagesSupported : RED_BOLD("unavailable")) : RED_BOLD("disabled"));
|
||||||
@@ -87,7 +92,7 @@ static void print_memory(Config *config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_cpu(Config *)
|
static void print_cpu(const Config *)
|
||||||
{
|
{
|
||||||
const auto info = Cpu::info();
|
const auto info = Cpu::info();
|
||||||
|
|
||||||
@@ -116,7 +121,7 @@ static void print_cpu(Config *)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_memory()
|
static void print_memory(const Config *config)
|
||||||
{
|
{
|
||||||
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
||||||
const auto freeMem = static_cast<double>(uv_get_free_memory());
|
const auto freeMem = static_cast<double>(uv_get_free_memory());
|
||||||
@@ -124,16 +129,49 @@ static void print_memory()
|
|||||||
|
|
||||||
const double percent = freeMem > 0 ? ((totalMem - freeMem) / totalMem * 100.0) : 100.0;
|
const double percent = freeMem > 0 ? ((totalMem - freeMem) / totalMem * 100.0) : 100.0;
|
||||||
|
|
||||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%.1f/%.1f GB") BLACK_BOLD(" (%.0f%%)"),
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%.1f/%.1f") CYAN(" GB") BLACK_BOLD(" (%.0f%%)"),
|
||||||
"MEMORY",
|
"MEMORY",
|
||||||
(totalMem - freeMem) / oneGiB,
|
(totalMem - freeMem) / oneGiB,
|
||||||
totalMem / oneGiB,
|
totalMem / oneGiB,
|
||||||
percent
|
percent
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
if (!config->isDMI()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DmiReader reader;
|
||||||
|
if (!reader.read()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool printEmpty = reader.memory().size() <= 8;
|
||||||
|
|
||||||
|
for (const auto &memory : reader.memory()) {
|
||||||
|
if (!memory.isValid()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memory.size()) {
|
||||||
|
Log::print(WHITE_BOLD(" %-13s") "%s: " CYAN_BOLD("%" PRIu64) CYAN(" GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"),
|
||||||
|
"", memory.id().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data());
|
||||||
|
}
|
||||||
|
else if (printEmpty) {
|
||||||
|
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &board = Cpu::info()->isVM() ? reader.system() : reader.board();
|
||||||
|
|
||||||
|
if (board.isValid()) {
|
||||||
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", board.vendor().data(), board.product().data());
|
||||||
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_threads(Config *config)
|
static void print_threads(const Config *config)
|
||||||
{
|
{
|
||||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s%d%%"),
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s%d%%"),
|
||||||
"DONATE",
|
"DONATE",
|
||||||
@@ -175,14 +213,16 @@ static void print_commands(Config *)
|
|||||||
|
|
||||||
void xmrig::Summary::print(Controller *controller)
|
void xmrig::Summary::print(Controller *controller)
|
||||||
{
|
{
|
||||||
controller->config()->printVersions();
|
const auto config = controller->config();
|
||||||
print_memory(controller->config());
|
|
||||||
print_cpu(controller->config());
|
|
||||||
print_memory();
|
|
||||||
print_threads(controller->config());
|
|
||||||
controller->config()->pools().print();
|
|
||||||
|
|
||||||
print_commands(controller->config());
|
config->printVersions();
|
||||||
|
print_pages(config);
|
||||||
|
print_cpu(config);
|
||||||
|
print_memory(config);
|
||||||
|
print_threads(config);
|
||||||
|
config->pools().print();
|
||||||
|
|
||||||
|
print_commands(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2021 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
|
||||||
|
|||||||
@@ -1,13 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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
|
||||||
@@ -42,10 +35,15 @@ public:
|
|||||||
PciTopology() = default;
|
PciTopology() = default;
|
||||||
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
|
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
|
||||||
|
|
||||||
inline bool isValid() const { return m_valid; }
|
inline bool isEqual(const PciTopology &other) const { return m_valid == other.m_valid && toUint32() == other.toUint32(); }
|
||||||
inline uint8_t bus() const { return m_bus; }
|
inline bool isValid() const { return m_valid; }
|
||||||
inline uint8_t device() const { return m_device; }
|
inline uint8_t bus() const { return m_bus; }
|
||||||
inline uint8_t function() const { return m_function; }
|
inline uint8_t device() const { return m_device; }
|
||||||
|
inline uint8_t function() const { return m_function; }
|
||||||
|
|
||||||
|
inline bool operator!=(const PciTopology &other) const { return !isEqual(other); }
|
||||||
|
inline bool operator<(const PciTopology &other) const { return toUint32() < other.toUint32(); }
|
||||||
|
inline bool operator==(const PciTopology &other) const { return isEqual(other); }
|
||||||
|
|
||||||
String toString() const
|
String toString() const
|
||||||
{
|
{
|
||||||
@@ -60,6 +58,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline uint32_t toUint32() const { return m_bus << 16 | m_device << 8 | m_function; }
|
||||||
|
|
||||||
bool m_valid = false;
|
bool m_valid = false;
|
||||||
uint8_t m_bus = 0;
|
uint8_t m_bus = 0;
|
||||||
uint8_t m_device = 0;
|
uint8_t m_device = 0;
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ public:
|
|||||||
|
|
||||||
inline void start(const std::vector<CpuLaunchData> &threads, size_t memory)
|
inline void start(const std::vector<CpuLaunchData> &threads, size_t memory)
|
||||||
{
|
{
|
||||||
|
m_workersMemory.clear();
|
||||||
m_hugePages.reset();
|
m_hugePages.reset();
|
||||||
m_memory = memory;
|
m_memory = memory;
|
||||||
m_started = 0;
|
m_started = 0;
|
||||||
@@ -95,8 +96,10 @@ public:
|
|||||||
if (ready) {
|
if (ready) {
|
||||||
m_started++;
|
m_started++;
|
||||||
|
|
||||||
m_hugePages += worker->memory()->hugePages();
|
if (m_workersMemory.insert(worker->memory()).second) {
|
||||||
m_ways += worker->intensity();
|
m_hugePages += worker->memory()->hugePages();
|
||||||
|
}
|
||||||
|
m_ways += worker->intensity();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_errors++;
|
m_errors++;
|
||||||
@@ -126,6 +129,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::set<const VirtualMemory*> m_workersMemory;
|
||||||
HugePagesInfo m_hugePages;
|
HugePagesInfo m_hugePages;
|
||||||
size_t m_errors = 0;
|
size_t m_errors = 0;
|
||||||
size_t m_memory = 0;
|
size_t m_memory = 0;
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -77,7 +71,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
|
|||||||
Value obj(kObjectType);
|
Value obj(kObjectType);
|
||||||
|
|
||||||
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
||||||
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
|
obj.AddMember(StringRef(kHugePages), m_hugePageSize == 0 || m_hugePageSize == kDefaultHugePageSizeKb ? Value(isHugePages()) : Value(static_cast<uint32_t>(m_hugePageSize)), allocator);
|
||||||
obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator);
|
obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator);
|
||||||
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
|
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
|
||||||
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
||||||
@@ -109,12 +103,16 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
|
|||||||
|
|
||||||
size_t xmrig::CpuConfig::memPoolSize() const
|
size_t xmrig::CpuConfig::memPoolSize() const
|
||||||
{
|
{
|
||||||
return m_memoryPool < 0 ? Cpu::info()->threads() : m_memoryPool;
|
return m_memoryPool < 0 ? std::max(Cpu::info()->threads(), Cpu::info()->L3() >> 21) : m_memoryPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
|
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
|
||||||
{
|
{
|
||||||
|
if (algorithm.family() == Algorithm::KAWPOW) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<CpuLaunchData> out;
|
std::vector<CpuLaunchData> out;
|
||||||
const auto &threads = m_threads.get(algorithm);
|
const auto &threads = m_threads.get(algorithm);
|
||||||
|
|
||||||
@@ -137,14 +135,14 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
|
|||||||
{
|
{
|
||||||
if (value.IsObject()) {
|
if (value.IsObject()) {
|
||||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||||
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
|
|
||||||
m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit);
|
m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit);
|
||||||
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
|
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
|
||||||
m_yield = Json::getBool(value, kYield, m_yield);
|
m_yield = Json::getBool(value, kYield, m_yield);
|
||||||
|
|
||||||
setAesMode(Json::getValue(value, kHwAes));
|
setAesMode(Json::getValue(value, kHwAes));
|
||||||
setPriority(Json::getInt(value, kPriority, -1));
|
setHugePages(Json::getValue(value, kHugePages));
|
||||||
setMemoryPool(Json::getValue(value, kMemoryPool));
|
setMemoryPool(Json::getValue(value, kMemoryPool));
|
||||||
|
setPriority(Json::getInt(value, kPriority, -1));
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_ASM
|
# ifdef XMRIG_FEATURE_ASM
|
||||||
m_assembly = Json::getValue(value, kAsm);
|
m_assembly = Json::getValue(value, kAsm);
|
||||||
@@ -218,6 +216,19 @@ void xmrig::CpuConfig::setAesMode(const rapidjson::Value &value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::CpuConfig::setHugePages(const rapidjson::Value &value)
|
||||||
|
{
|
||||||
|
if (value.IsBool()) {
|
||||||
|
m_hugePageSize = value.GetBool() ? kDefaultHugePageSizeKb : 0U;
|
||||||
|
}
|
||||||
|
else if (value.IsUint()) {
|
||||||
|
const uint32_t size = value.GetUint();
|
||||||
|
|
||||||
|
m_hugePageSize = size < kOneGbPageSizeKb ? size : kDefaultHugePageSizeKb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value)
|
void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value)
|
||||||
{
|
{
|
||||||
if (value.IsBool()) {
|
if (value.IsBool()) {
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -75,8 +69,9 @@ public:
|
|||||||
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
||||||
void read(const rapidjson::Value &value);
|
void read(const rapidjson::Value &value);
|
||||||
|
|
||||||
|
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
|
||||||
inline bool isEnabled() const { return m_enabled; }
|
inline bool isEnabled() const { return m_enabled; }
|
||||||
inline bool isHugePages() const { return m_hugePages; }
|
inline bool isHugePages() const { return m_hugePageSize > 0; }
|
||||||
inline bool isHugePagesJit() const { return m_hugePagesJit; }
|
inline bool isHugePagesJit() const { return m_hugePagesJit; }
|
||||||
inline bool isShouldSave() const { return m_shouldSave; }
|
inline bool isShouldSave() const { return m_shouldSave; }
|
||||||
inline bool isYield() const { return m_yield; }
|
inline bool isYield() const { return m_yield; }
|
||||||
@@ -84,13 +79,17 @@ public:
|
|||||||
inline const String &argon2Impl() const { return m_argon2Impl; }
|
inline const String &argon2Impl() const { return m_argon2Impl; }
|
||||||
inline const Threads<CpuThreads> &threads() const { return m_threads; }
|
inline const Threads<CpuThreads> &threads() const { return m_threads; }
|
||||||
inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; }
|
inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; }
|
||||||
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
|
|
||||||
inline int priority() const { return m_priority; }
|
inline int priority() const { return m_priority; }
|
||||||
|
inline size_t hugePageSize() const { return m_hugePageSize * 1024U; }
|
||||||
inline uint32_t limit() const { return m_limit; }
|
inline uint32_t limit() const { return m_limit; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
constexpr static size_t kDefaultHugePageSizeKb = 2048U;
|
||||||
|
constexpr static size_t kOneGbPageSizeKb = 1048576U;
|
||||||
|
|
||||||
void generate();
|
void generate();
|
||||||
void setAesMode(const rapidjson::Value &value);
|
void setAesMode(const rapidjson::Value &value);
|
||||||
|
void setHugePages(const rapidjson::Value &value);
|
||||||
void setMemoryPool(const rapidjson::Value &value);
|
void setMemoryPool(const rapidjson::Value &value);
|
||||||
|
|
||||||
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
|
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
|
||||||
@@ -99,13 +98,13 @@ private:
|
|||||||
Assembly m_assembly;
|
Assembly m_assembly;
|
||||||
bool m_astrobwtAVX2 = false;
|
bool m_astrobwtAVX2 = false;
|
||||||
bool m_enabled = true;
|
bool m_enabled = true;
|
||||||
bool m_hugePages = true;
|
|
||||||
bool m_hugePagesJit = false;
|
bool m_hugePagesJit = false;
|
||||||
bool m_shouldSave = false;
|
bool m_shouldSave = false;
|
||||||
bool m_yield = true;
|
bool m_yield = true;
|
||||||
int m_astrobwtMaxSize = 550;
|
int m_astrobwtMaxSize = 550;
|
||||||
int m_memoryPool = 0;
|
int m_memoryPool = 0;
|
||||||
int m_priority = -1;
|
int m_priority = -1;
|
||||||
|
size_t m_hugePageSize = kDefaultHugePageSizeKb;
|
||||||
String m_argon2Impl;
|
String m_argon2Impl;
|
||||||
Threads<CpuThreads> m_threads;
|
Threads<CpuThreads> m_threads;
|
||||||
uint32_t m_limit = 100;
|
uint32_t m_limit = 100;
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
|
#include "backend/cpu/Cpu.h"
|
||||||
#include "backend/cpu/CpuWorker.h"
|
#include "backend/cpu/CpuWorker.h"
|
||||||
#include "base/tools/Chrono.h"
|
#include "base/tools/Chrono.h"
|
||||||
#include "core/config/Config.h"
|
#include "core/config/Config.h"
|
||||||
@@ -55,6 +57,12 @@ namespace xmrig {
|
|||||||
|
|
||||||
static constexpr uint32_t kReserveCount = 32768;
|
static constexpr uint32_t kReserveCount = 32768;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
|
static std::mutex cn_heavyZen3MemoryMutex;
|
||||||
|
VirtualMemory* cn_heavyZen3Memory = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace xmrig
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
@@ -73,7 +81,20 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
|
|||||||
m_threads(data.threads),
|
m_threads(data.threads),
|
||||||
m_ctx()
|
m_ctx()
|
||||||
{
|
{
|
||||||
m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages, false, true, node());
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
|
// cn-heavy optimization for Zen3 CPUs
|
||||||
|
if ((N == 1) && (m_av == CnHash::AV_SINGLE) && (m_algorithm.family() == Algorithm::CN_HEAVY) && (m_assembly != Assembly::NONE) && (Cpu::info()->arch() == ICpuInfo::ARCH_ZEN3)) {
|
||||||
|
std::lock_guard<std::mutex> lock(cn_heavyZen3MemoryMutex);
|
||||||
|
if (!cn_heavyZen3Memory) {
|
||||||
|
cn_heavyZen3Memory = new VirtualMemory(m_algorithm.l3() * m_threads, data.hugePages, false, false, node());
|
||||||
|
}
|
||||||
|
m_memory = cn_heavyZen3Memory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages, false, true, node());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -85,7 +106,13 @@ xmrig::CpuWorker<N>::~CpuWorker()
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
CnCtx::release(m_ctx, N);
|
CnCtx::release(m_ctx, N);
|
||||||
delete m_memory;
|
|
||||||
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
|
if (m_memory != cn_heavyZen3Memory)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
delete m_memory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -387,7 +414,16 @@ template<size_t N>
|
|||||||
void xmrig::CpuWorker<N>::allocateCnCtx()
|
void xmrig::CpuWorker<N>::allocateCnCtx()
|
||||||
{
|
{
|
||||||
if (m_ctx[0] == nullptr) {
|
if (m_ctx[0] == nullptr) {
|
||||||
CnCtx::create(m_ctx, m_memory->scratchpad(), m_algorithm.l3(), N);
|
int shift = 0;
|
||||||
|
|
||||||
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
|
// cn-heavy optimization for Zen3 CPUs
|
||||||
|
if (m_memory == cn_heavyZen3Memory) {
|
||||||
|
shift = (id() / 8) * m_algorithm.l3() * 8 + (id() % 8) * 64;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
CnCtx::create(m_ctx, m_memory->scratchpad() + shift, m_algorithm.l3(), N);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -86,18 +86,21 @@ public:
|
|||||||
inline constexpr static bool is64bit() { return false; }
|
inline constexpr static bool is64bit() { return false; }
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
virtual Arch arch() const = 0;
|
||||||
virtual Assembly::Id assembly() const = 0;
|
virtual Assembly::Id assembly() const = 0;
|
||||||
virtual bool has(Flag feature) const = 0;
|
virtual bool has(Flag feature) const = 0;
|
||||||
virtual bool hasAES() const = 0;
|
virtual bool hasAES() const = 0;
|
||||||
virtual bool hasAVX() const = 0;
|
virtual bool hasAVX() const = 0;
|
||||||
virtual bool hasAVX2() const = 0;
|
virtual bool hasAVX2() const = 0;
|
||||||
virtual bool hasBMI2() const = 0;
|
virtual bool hasBMI2() const = 0;
|
||||||
|
virtual bool hasCatL3() const = 0;
|
||||||
virtual bool hasOneGbPages() const = 0;
|
virtual bool hasOneGbPages() const = 0;
|
||||||
virtual bool hasXOP() const = 0;
|
virtual bool hasXOP() const = 0;
|
||||||
virtual bool hasCatL3() const = 0;
|
|
||||||
virtual bool isVM() const = 0;
|
virtual bool isVM() const = 0;
|
||||||
|
virtual bool jccErratum() const = 0;
|
||||||
virtual const char *backend() const = 0;
|
virtual const char *backend() const = 0;
|
||||||
virtual const char *brand() const = 0;
|
virtual const char *brand() const = 0;
|
||||||
|
virtual const std::vector<int32_t> &units() const = 0;
|
||||||
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
|
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
|
||||||
virtual MsrMod msrMod() const = 0;
|
virtual MsrMod msrMod() const = 0;
|
||||||
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
|
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
|
||||||
@@ -108,8 +111,6 @@ public:
|
|||||||
virtual size_t packages() const = 0;
|
virtual size_t packages() const = 0;
|
||||||
virtual size_t threads() const = 0;
|
virtual size_t threads() const = 0;
|
||||||
virtual Vendor vendor() const = 0;
|
virtual Vendor vendor() const = 0;
|
||||||
virtual Arch arch() const = 0;
|
|
||||||
virtual bool jccErratum() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -190,6 +190,11 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
|
|||||||
m_flags.set(FLAG_CAT_L3, has_cat_l3());
|
m_flags.set(FLAG_CAT_L3, has_cat_l3());
|
||||||
m_flags.set(FLAG_VM, is_vm());
|
m_flags.set(FLAG_VM, is_vm());
|
||||||
|
|
||||||
|
m_units.resize(m_threads);
|
||||||
|
for (int32_t i = 0; i < static_cast<int32_t>(m_threads); ++i) {
|
||||||
|
m_units[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_ASM
|
# ifdef XMRIG_FEATURE_ASM
|
||||||
if (hasAES()) {
|
if (hasAES()) {
|
||||||
char vendor[13] = { 0 };
|
char vendor[13] = { 0 };
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2016-2021 XMRig <support@xmrig.com>
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -45,34 +40,36 @@ protected:
|
|||||||
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
|
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
|
||||||
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
|
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
|
||||||
|
|
||||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
inline Arch arch() const override { return m_arch; }
|
||||||
inline bool has(Flag flag) const override { return m_flags.test(flag); }
|
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||||
inline bool hasAES() const override { return has(FLAG_AES); }
|
inline bool has(Flag flag) const override { return m_flags.test(flag); }
|
||||||
inline bool hasAVX() const override { return has(FLAG_AVX); }
|
inline bool hasAES() const override { return has(FLAG_AES); }
|
||||||
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
|
inline bool hasAVX() const override { return has(FLAG_AVX); }
|
||||||
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
|
inline bool hasAVX2() const override { return has(FLAG_AVX2); }
|
||||||
inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); }
|
inline bool hasBMI2() const override { return has(FLAG_BMI2); }
|
||||||
inline bool hasXOP() const override { return has(FLAG_XOP); }
|
inline bool hasCatL3() const override { return has(FLAG_CAT_L3); }
|
||||||
inline bool hasCatL3() const override { return has(FLAG_CAT_L3); }
|
inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); }
|
||||||
inline bool isVM() const override { return has(FLAG_VM); }
|
inline bool hasXOP() const override { return has(FLAG_XOP); }
|
||||||
inline const char *brand() const override { return m_brand; }
|
inline bool isVM() const override { return has(FLAG_VM); }
|
||||||
inline MsrMod msrMod() const override { return m_msrMod; }
|
inline bool jccErratum() const override { return m_jccErratum; }
|
||||||
inline size_t cores() const override { return 0; }
|
inline const char *brand() const override { return m_brand; }
|
||||||
inline size_t L2() const override { return 0; }
|
inline const std::vector<int32_t> &units() const override { return m_units; }
|
||||||
inline size_t L3() const override { return 0; }
|
inline MsrMod msrMod() const override { return m_msrMod; }
|
||||||
inline size_t nodes() const override { return 0; }
|
inline size_t cores() const override { return 0; }
|
||||||
inline size_t packages() const override { return 1; }
|
inline size_t L2() const override { return 0; }
|
||||||
inline size_t threads() const override { return m_threads; }
|
inline size_t L3() const override { return 0; }
|
||||||
inline Vendor vendor() const override { return m_vendor; }
|
inline size_t nodes() const override { return 0; }
|
||||||
inline Arch arch() const override { return m_arch; }
|
inline size_t packages() const override { return 1; }
|
||||||
inline bool jccErratum() const override { return m_jccErratum; }
|
inline size_t threads() const override { return m_threads; }
|
||||||
|
inline Vendor vendor() const override { return m_vendor; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char m_brand[64 + 6]{};
|
|
||||||
size_t m_threads;
|
|
||||||
Vendor m_vendor = VENDOR_UNKNOWN;
|
|
||||||
Arch m_arch = ARCH_UNKNOWN;
|
Arch m_arch = ARCH_UNKNOWN;
|
||||||
bool m_jccErratum = false;
|
bool m_jccErratum = false;
|
||||||
|
char m_brand[64 + 6]{};
|
||||||
|
size_t m_threads;
|
||||||
|
std::vector<int32_t> m_units;
|
||||||
|
Vendor m_vendor = VENDOR_UNKNOWN;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
# ifndef XMRIG_ARM
|
# ifndef XMRIG_ARM
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -50,6 +50,11 @@ extern String cpu_name_arm();
|
|||||||
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||||
m_threads(std::thread::hardware_concurrency())
|
m_threads(std::thread::hardware_concurrency())
|
||||||
{
|
{
|
||||||
|
m_units.resize(m_threads);
|
||||||
|
for (int32_t i = 0; i < static_cast<int32_t>(m_threads); ++i) {
|
||||||
|
m_units[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
# ifdef XMRIG_ARMv8
|
# ifdef XMRIG_ARMv8
|
||||||
memcpy(m_brand, "ARMv8", 5);
|
memcpy(m_brand, "ARMv8", 5);
|
||||||
# else
|
# else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -125,8 +125,6 @@ static inline bool isCacheExclusive(hwloc_obj_t obj)
|
|||||||
|
|
||||||
xmrig::HwlocCpuInfo::HwlocCpuInfo()
|
xmrig::HwlocCpuInfo::HwlocCpuInfo()
|
||||||
{
|
{
|
||||||
m_threads = 0;
|
|
||||||
|
|
||||||
hwloc_topology_init(&m_topology);
|
hwloc_topology_init(&m_topology);
|
||||||
hwloc_topology_load(m_topology);
|
hwloc_topology_load(m_topology);
|
||||||
|
|
||||||
@@ -170,7 +168,8 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo()
|
|||||||
|
|
||||||
findCache(root, 2, 3, [this](hwloc_obj_t found) { this->m_cache[found->attr->cache.depth] += found->attr->cache.size; });
|
findCache(root, 2, 3, [this](hwloc_obj_t found) { this->m_cache[found->attr->cache.depth] += found->attr->cache.size; });
|
||||||
|
|
||||||
m_threads = countByType(m_topology, HWLOC_OBJ_PU);
|
setThreads(countByType(m_topology, HWLOC_OBJ_PU));
|
||||||
|
|
||||||
m_cores = countByType(m_topology, HWLOC_OBJ_CORE);
|
m_cores = countByType(m_topology, HWLOC_OBJ_CORE);
|
||||||
m_nodes = std::max(hwloc_bitmap_weight(hwloc_topology_get_complete_nodeset(m_topology)), 1);
|
m_nodes = std::max(hwloc_bitmap_weight(hwloc_topology_get_complete_nodeset(m_topology)), 1);
|
||||||
m_packages = countByType(m_topology, HWLOC_OBJ_PACKAGE);
|
m_packages = countByType(m_topology, HWLOC_OBJ_PACKAGE);
|
||||||
@@ -277,10 +276,8 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::allThreads(const Algorithm &algorithm, ui
|
|||||||
CpuThreads threads;
|
CpuThreads threads;
|
||||||
threads.reserve(m_threads);
|
threads.reserve(m_threads);
|
||||||
|
|
||||||
hwloc_obj_t pu = nullptr;
|
for (const int32_t pu : m_units) {
|
||||||
|
threads.add(pu, 0);
|
||||||
while ((pu = hwloc_get_next_obj_by_type(m_topology, HWLOC_OBJ_PU, pu)) != nullptr) {
|
|
||||||
threads.add(pu->os_index, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (threads.isEmpty()) {
|
if (threads.isEmpty()) {
|
||||||
@@ -366,10 +363,14 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<int64_t, int32_t>> threads_data;
|
||||||
|
threads_data.reserve(cores.size());
|
||||||
|
|
||||||
size_t pu_id = 0;
|
size_t pu_id = 0;
|
||||||
while (cacheHashes > 0 && PUs > 0) {
|
while (cacheHashes > 0 && PUs > 0) {
|
||||||
bool allocated_pu = false;
|
bool allocated_pu = false;
|
||||||
|
|
||||||
|
threads_data.clear();
|
||||||
for (hwloc_obj_t core : cores) {
|
for (hwloc_obj_t core : cores) {
|
||||||
const std::vector<hwloc_obj_t> units = findByType(core, HWLOC_OBJ_PU);
|
const std::vector<hwloc_obj_t> units = findByType(core, HWLOC_OBJ_PU);
|
||||||
if (units.size() <= pu_id) {
|
if (units.size() <= pu_id) {
|
||||||
@@ -380,18 +381,52 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
|
|||||||
PUs--;
|
PUs--;
|
||||||
|
|
||||||
allocated_pu = true;
|
allocated_pu = true;
|
||||||
threads.add(units[pu_id]->os_index, intensity);
|
threads_data.emplace_back(units[pu_id]->os_index, intensity);
|
||||||
|
|
||||||
if (cacheHashes == 0) {
|
if (cacheHashes == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reversing of "threads_data" and "cores" is done to fill in virtual cores starting from the last one, but still in order
|
||||||
|
// For example, cn-heavy threads on 6-core Zen2/Zen3 will have affinity [0,2,4,6,8,10,9,11]
|
||||||
|
// This is important for Zen3 cn-heavy optimization
|
||||||
|
|
||||||
|
if (pu_id & 1) {
|
||||||
|
std::reverse(threads_data.begin(), threads_data.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& t : threads_data) {
|
||||||
|
threads.add(t.first, t.second);
|
||||||
|
}
|
||||||
|
|
||||||
if (!allocated_pu) {
|
if (!allocated_pu) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pu_id++;
|
pu_id++;
|
||||||
|
std::reverse(cores.begin(), cores.end());
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HwlocCpuInfo::setThreads(size_t threads)
|
||||||
|
{
|
||||||
|
if (!threads) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_threads = threads;
|
||||||
|
|
||||||
|
if (m_units.size() != m_threads) {
|
||||||
|
m_units.resize(m_threads);
|
||||||
|
}
|
||||||
|
|
||||||
|
hwloc_obj_t pu = nullptr;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
while ((pu = hwloc_get_next_obj_by_type(m_topology, HWLOC_OBJ_PU, pu)) != nullptr) {
|
||||||
|
m_units[i++] = static_cast<int32_t>(pu->os_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -66,7 +66,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
CpuThreads allThreads(const Algorithm &algorithm, uint32_t limit) const;
|
CpuThreads allThreads(const Algorithm &algorithm, uint32_t limit) const;
|
||||||
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;
|
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;
|
||||||
|
void setThreads(size_t threads);
|
||||||
|
|
||||||
static uint32_t m_features;
|
static uint32_t m_features;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018 Riku Voipio <riku.voipio@iki.fi>
|
* Copyright (c) 2018 Riku Voipio <riku.voipio@iki.fi>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -87,16 +87,22 @@ static const id_part arm_part[] = {
|
|||||||
{ 0xd03, "Cortex-A53" },
|
{ 0xd03, "Cortex-A53" },
|
||||||
{ 0xd04, "Cortex-A35" },
|
{ 0xd04, "Cortex-A35" },
|
||||||
{ 0xd05, "Cortex-A55" },
|
{ 0xd05, "Cortex-A55" },
|
||||||
|
{ 0xd06, "Cortex-A65" },
|
||||||
{ 0xd07, "Cortex-A57" },
|
{ 0xd07, "Cortex-A57" },
|
||||||
{ 0xd08, "Cortex-A72" },
|
{ 0xd08, "Cortex-A72" },
|
||||||
{ 0xd09, "Cortex-A73" },
|
{ 0xd09, "Cortex-A73" },
|
||||||
{ 0xd0a, "Cortex-A75" },
|
{ 0xd0a, "Cortex-A75" },
|
||||||
{ 0xd0b, "Cortex-A76" },
|
{ 0xd0b, "Cortex-A76" },
|
||||||
{ 0xd0c, "Neoverse-N1" },
|
{ 0xd0c, "Neoverse-N1" },
|
||||||
|
{ 0xd0d, "Cortex-A77" },
|
||||||
|
{ 0xd0e, "Cortex-A76AE" },
|
||||||
{ 0xd13, "Cortex-R52" },
|
{ 0xd13, "Cortex-R52" },
|
||||||
{ 0xd20, "Cortex-M23" },
|
{ 0xd20, "Cortex-M23" },
|
||||||
{ 0xd21, "Cortex-M33" },
|
{ 0xd21, "Cortex-M33" },
|
||||||
|
{ 0xd41, "Cortex-A78" },
|
||||||
|
{ 0xd42, "Cortex-A78AE" },
|
||||||
{ 0xd4a, "Neoverse-E1" },
|
{ 0xd4a, "Neoverse-E1" },
|
||||||
|
{ 0xd4b, "Cortex-A78C" },
|
||||||
{ -1, nullptr },
|
{ -1, nullptr },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,6 +156,7 @@ static const id_part samsung_part[] = {
|
|||||||
static const id_part nvidia_part[] = {
|
static const id_part nvidia_part[] = {
|
||||||
{ 0x000, "Denver" },
|
{ 0x000, "Denver" },
|
||||||
{ 0x003, "Denver 2" },
|
{ 0x003, "Denver 2" },
|
||||||
|
{ 0x004, "Carmel" },
|
||||||
{ -1, nullptr },
|
{ -1, nullptr },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,23 +198,36 @@ static const id_part intel_part[] = {
|
|||||||
{ -1, nullptr },
|
{ -1, nullptr },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct id_part fujitsu_part[] = {
|
||||||
|
{ 0x001, "A64FX" },
|
||||||
|
{ -1, "unknown" },
|
||||||
|
};
|
||||||
|
|
||||||
static const id_part hisi_part[] = {
|
static const id_part hisi_part[] = {
|
||||||
{ 0xd01, "Kunpeng-920" }, /* aka tsv110 */
|
{ 0xd01, "Kunpeng-920" }, /* aka tsv110 */
|
||||||
{ -1, nullptr },
|
{ -1, nullptr },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const id_part apple_part[] = {
|
||||||
|
{ 0x022, "M1" },
|
||||||
|
{ 0x023, "M1" },
|
||||||
|
{ -1, nullptr },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static const hw_impl hw_implementer[] = {
|
static const hw_impl hw_implementer[] = {
|
||||||
{ 0x41, arm_part, "ARM" },
|
{ 0x41, arm_part, "ARM" },
|
||||||
{ 0x42, brcm_part, "Broadcom" },
|
{ 0x42, brcm_part, "Broadcom" },
|
||||||
{ 0x43, cavium_part, "Cavium" },
|
{ 0x43, cavium_part, "Cavium" },
|
||||||
{ 0x44, dec_part, "DEC" },
|
{ 0x44, dec_part, "DEC" },
|
||||||
|
{ 0x46, fujitsu_part, "FUJITSU" },
|
||||||
{ 0x48, hisi_part, "HiSilicon" },
|
{ 0x48, hisi_part, "HiSilicon" },
|
||||||
{ 0x4e, nvidia_part, "Nvidia" },
|
{ 0x4e, nvidia_part, "Nvidia" },
|
||||||
{ 0x50, apm_part, "APM" },
|
{ 0x50, apm_part, "APM" },
|
||||||
{ 0x51, qcom_part, "Qualcomm" },
|
{ 0x51, qcom_part, "Qualcomm" },
|
||||||
{ 0x53, samsung_part, "Samsung" },
|
{ 0x53, samsung_part, "Samsung" },
|
||||||
{ 0x56, marvell_part, "Marvell" },
|
{ 0x56, marvell_part, "Marvell" },
|
||||||
|
{ 0x61, apple_part, "Apple" },
|
||||||
{ 0x66, faraday_part, "Faraday" },
|
{ 0x66, faraday_part, "Faraday" },
|
||||||
{ 0x69, intel_part, "Intel" }
|
{ 0x69, intel_part, "Intel" }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ bool xmrig::OclWorker::selfTest()
|
|||||||
|
|
||||||
size_t xmrig::OclWorker::intensity() const
|
size_t xmrig::OclWorker::intensity() const
|
||||||
{
|
{
|
||||||
return m_runner ? m_runner->intensity() : 0;
|
return m_runner ? m_runner->roundSize() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,6 @@
|
|||||||
|
|
||||||
#define COUNTING_SORT_BITS 11
|
#define COUNTING_SORT_BITS 11
|
||||||
#define COUNTING_SORT_SIZE (1 << COUNTING_SORT_BITS)
|
#define COUNTING_SORT_SIZE (1 << COUNTING_SORT_BITS)
|
||||||
#define FINAL_SORT_BATCH_SIZE COUNTING_SORT_SIZE
|
|
||||||
#define FINAL_SORT_OVERLAP_SIZE 32
|
|
||||||
|
|
||||||
__attribute__((reqd_work_group_size(BWT_GROUP_SIZE, 1, 1)))
|
__attribute__((reqd_work_group_size(BWT_GROUP_SIZE, 1, 1)))
|
||||||
__kernel void BWT(__global uint8_t* datas, __global uint32_t* data_sizes, uint32_t data_stride, __global uint64_t* indices, __global uint64_t* tmp_indices)
|
__kernel void BWT(__global uint8_t* datas, __global uint32_t* data_sizes, uint32_t data_stride, __global uint64_t* indices, __global uint64_t* tmp_indices)
|
||||||
@@ -40,6 +38,8 @@ __kernel void BWT(__global uint8_t* datas, __global uint32_t* data_sizes, uint32
|
|||||||
for (uint32_t i = tid; i < COUNTING_SORT_SIZE * 2; i += BWT_GROUP_SIZE)
|
for (uint32_t i = tid; i < COUNTING_SORT_SIZE * 2; i += BWT_GROUP_SIZE)
|
||||||
((__local int*)counters)[i] = 0;
|
((__local int*)counters)[i] = 0;
|
||||||
|
|
||||||
|
barrier(CLK_LOCAL_MEM_FENCE);
|
||||||
|
|
||||||
const uint64_t data_offset = (uint64_t)(gid) * data_stride;
|
const uint64_t data_offset = (uint64_t)(gid) * data_stride;
|
||||||
|
|
||||||
__global uint8_t* input = datas + data_offset + 128;
|
__global uint8_t* input = datas + data_offset + 128;
|
||||||
@@ -76,6 +76,8 @@ __kernel void BWT(__global uint8_t* datas, __global uint32_t* data_sizes, uint32
|
|||||||
atomic_add((volatile __local int*)(counters_atomic + ((value >> (64 - COUNTING_SORT_BITS)) << 3) + 4), 1);
|
atomic_add((volatile __local int*)(counters_atomic + ((value >> (64 - COUNTING_SORT_BITS)) << 3) + 4), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
barrier(CLK_LOCAL_MEM_FENCE);
|
||||||
|
|
||||||
if (tid == 0)
|
if (tid == 0)
|
||||||
{
|
{
|
||||||
int t0 = counters[0][0];
|
int t0 = counters[0][0];
|
||||||
@@ -91,59 +93,62 @@ __kernel void BWT(__global uint8_t* datas, __global uint32_t* data_sizes, uint32
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
barrier(CLK_LOCAL_MEM_FENCE);
|
||||||
|
|
||||||
for (int i = tid; i < N; i += BWT_GROUP_SIZE)
|
for (int i = tid; i < N; i += BWT_GROUP_SIZE)
|
||||||
{
|
{
|
||||||
const uint64_t data = indices[i];
|
const uint64_t data = indices[i];
|
||||||
const int k = atomic_sub((volatile __local int*)(counters_atomic + (((data >> (64 - COUNTING_SORT_BITS * 2)) & (COUNTING_SORT_SIZE - 1)) << 3)), 1);
|
const int k = atomic_sub((volatile __local int*)(counters_atomic + (((data >> (64 - COUNTING_SORT_BITS * 2)) & (COUNTING_SORT_SIZE - 1)) << 3)), 1);
|
||||||
tmp_indices[k] = data;
|
tmp_indices[k] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
barrier(CLK_GLOBAL_MEM_FENCE);
|
barrier(CLK_GLOBAL_MEM_FENCE);
|
||||||
|
|
||||||
for (int i = N - 1 - tid; i >= 0; i -= BWT_GROUP_SIZE)
|
if (tid == 0)
|
||||||
{
|
{
|
||||||
const uint64_t data = tmp_indices[i];
|
for (int i = N - 1; i >= 0; --i)
|
||||||
const int k = atomic_sub((volatile __local int*)(counters_atomic + ((data >> (64 - COUNTING_SORT_BITS)) << 3) + 4), 1);
|
|
||||||
indices[k] = data;
|
|
||||||
}
|
|
||||||
barrier(CLK_GLOBAL_MEM_FENCE);
|
|
||||||
|
|
||||||
__local uint64_t* buf = (__local uint64_t*)(counters);
|
|
||||||
for (uint32_t i = 0; i < N; i += FINAL_SORT_BATCH_SIZE - FINAL_SORT_OVERLAP_SIZE)
|
|
||||||
{
|
|
||||||
const uint32_t len = (N - i < FINAL_SORT_BATCH_SIZE) ? (N - i) : FINAL_SORT_BATCH_SIZE;
|
|
||||||
|
|
||||||
for (uint32_t j = tid; j < len; j += BWT_GROUP_SIZE)
|
|
||||||
buf[j] = indices[i + j];
|
|
||||||
|
|
||||||
if (tid == 0)
|
|
||||||
{
|
{
|
||||||
uint64_t prev_t = buf[0];
|
const uint64_t data = tmp_indices[i];
|
||||||
for (int i = 1; i < len; ++i)
|
const int k = atomic_sub((volatile __local int*)(counters_atomic + ((data >> (64 - COUNTING_SORT_BITS)) << 3) + 4), 1);
|
||||||
{
|
indices[k] = data;
|
||||||
uint64_t t = buf[i];
|
|
||||||
if (t < prev_t)
|
|
||||||
{
|
|
||||||
const uint64_t t2 = prev_t;
|
|
||||||
int j = i - 1;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
buf[j + 1] = prev_t;
|
|
||||||
--j;
|
|
||||||
if (j < 0)
|
|
||||||
break;
|
|
||||||
prev_t = buf[j];
|
|
||||||
} while (t < prev_t);
|
|
||||||
buf[j + 1] = t;
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
prev_t = t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t j = tid; j < len; j += BWT_GROUP_SIZE)
|
|
||||||
indices[i + j] = buf[j];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
barrier(CLK_GLOBAL_MEM_FENCE);
|
||||||
|
|
||||||
|
const uint32_t N1 = N - 1;
|
||||||
|
__global uint32_t* indices32 = (__global uint32_t*)(indices);
|
||||||
|
for (uint32_t i = tid; i < N1; i += BWT_GROUP_SIZE)
|
||||||
|
{
|
||||||
|
const uint32_t value = indices32[i * 2 + 1] >> (32 - COUNTING_SORT_BITS * 2);
|
||||||
|
if (value != (indices32[i * 2 + 3] >> (32 - COUNTING_SORT_BITS * 2)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((i > 0) && ((indices32[i * 2 - 1] >> (32 - COUNTING_SORT_BITS * 2)) == value))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32_t i1 = i + 2;
|
||||||
|
while ((i1 < N) && ((indices32[i1 * 2 + 1] >> (32 - COUNTING_SORT_BITS * 2)) == value))
|
||||||
|
++i1;
|
||||||
|
|
||||||
|
for (uint32_t j = i; j < i1; ++j)
|
||||||
|
{
|
||||||
|
uint64_t t = indices[j];
|
||||||
|
for (uint32_t k = j + 1; k < i1; ++k)
|
||||||
|
{
|
||||||
|
if (t > indices[k])
|
||||||
|
{
|
||||||
|
const uint64_t t1 = t;
|
||||||
|
t = indices[k];
|
||||||
|
indices[k] = t1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indices[j] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
barrier(CLK_GLOBAL_MEM_FENCE);
|
||||||
|
|
||||||
--input;
|
--input;
|
||||||
__global uint8_t* output = (__global uint8_t*)(tmp_indices);
|
__global uint8_t* output = (__global uint8_t*)(tmp_indices);
|
||||||
for (int i = tid; i <= N; i += BWT_GROUP_SIZE)
|
for (int i = tid; i <= N; i += BWT_GROUP_SIZE)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
static const char astrobwt_cl[12434] = {
|
static const char astrobwt_cl[12493] = {
|
||||||
0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,
|
0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x63,0x68,0x61,0x72,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,
|
||||||
0x73,0x68,0x6f,0x72,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x20,0x75,0x69,0x6e,
|
0x73,0x68,0x6f,0x72,0x74,0x20,0x75,0x69,0x6e,0x74,0x31,0x36,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x69,0x6e,0x74,0x20,0x75,0x69,0x6e,
|
||||||
0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,
|
0x74,0x33,0x32,0x5f,0x74,0x3b,0x0a,0x74,0x79,0x70,0x65,0x64,0x65,0x66,0x20,0x75,0x6c,0x6f,0x6e,0x67,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x74,
|
||||||
@@ -10,388 +10,390 @@ static const char astrobwt_cl[12434] = {
|
|||||||
0x20,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,0x45,0x20,0x31,0x34,
|
0x20,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x3b,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,0x45,0x20,0x31,0x34,
|
||||||
0x37,0x32,0x35,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x20,
|
0x37,0x32,0x35,0x33,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x20,
|
||||||
0x31,0x31,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x20,0x28,0x31,
|
0x31,0x31,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x20,0x28,0x31,
|
||||||
0x20,0x3c,0x3c,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,
|
0x20,0x3c,0x3c,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,
|
||||||
0x46,0x49,0x4e,0x41,0x4c,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x41,0x54,0x43,0x48,0x5f,0x53,0x49,0x5a,0x45,0x20,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,
|
0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x42,0x57,0x54,0x5f,
|
||||||
0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x46,0x49,0x4e,0x41,0x4c,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x4f,0x56,0x45,0x52,
|
0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,
|
||||||
0x4c,0x41,0x50,0x5f,0x53,0x49,0x5a,0x45,0x20,0x33,0x32,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,
|
0x42,0x57,0x54,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x2c,0x5f,0x5f,0x67,0x6c,
|
||||||
0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,
|
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||||
0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x42,0x57,0x54,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,
|
||||||
0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
0x2a,0x20,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x74,0x6d,0x70,
|
||||||
0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x74,0x72,0x69,
|
0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x69,0x64,0x3d,0x67,
|
||||||
0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2c,0x5f,0x5f,
|
0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,
|
||||||
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x0a,0x7b,0x0a,
|
0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x20,
|
||||||
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,
|
0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x5b,0x32,0x5d,0x3b,
|
||||||
0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,
|
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,
|
||||||
0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x43,0x4f,0x55,
|
0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x32,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,
|
||||||
0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x5d,0x5b,0x32,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,
|
0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x29,0x5b,0x69,0x5d,0x3d,0x30,0x3b,0x0a,
|
||||||
0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x32,
|
0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x63,0x6f,
|
||||||
0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x28,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,
|
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,
|
||||||
0x6e,0x74,0x2a,0x29,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x29,0x5b,0x69,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,
|
0x5f,0x74,0x29,0x28,0x67,0x69,0x64,0x29,0x2a,0x64,0x61,0x74,0x61,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
|
||||||
0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x67,0x69,0x64,0x29,0x2a,0x64,
|
0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x64,0x61,0x74,0x61,0x73,0x2b,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,
|
||||||
0x61,0x74,0x61,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,
|
0x31,0x32,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,0x3d,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,
|
||||||
0x70,0x75,0x74,0x3d,0x64,0x61,0x74,0x61,0x73,0x2b,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x31,0x32,0x38,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,
|
0x5b,0x67,0x69,0x64,0x5d,0x2b,0x31,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x5f,
|
||||||
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,0x3d,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x69,0x64,0x5d,0x2b,0x31,0x3b,0x0a,0x5f,
|
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0x0a,0x76,0x6f,0x6c,0x61,0x74,
|
||||||
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,
|
0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,
|
||||||
0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x29,0x3b,0x0a,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,
|
0x6f,0x6d,0x69,0x63,0x3d,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,
|
||||||
0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x3d,0x28,0x76,0x6f,0x6c,0x61,
|
0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,
|
||||||
0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x29,
|
0x3b,0x0a,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,
|
||||||
0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,
|
0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,
|
||||||
0x63,0x65,0x73,0x2b,0x3d,0x64,0x61,0x74,0x61,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,
|
||||||
0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,
|
0x69,0x3e,0x3e,0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,
|
||||||
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,0x69,0x3e,0x3e,0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
|
0x28,0x69,0x26,0x37,0x29,0x3c,0x3c,0x33,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x3d,0x70,0x5b,0x69,0x6e,0x64,
|
||||||
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x69,0x26,0x37,0x29,0x3c,0x3c,0x33,0x3b,0x0a,
|
0x65,0x78,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x62,0x3d,0x70,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x62,
|
||||||
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x61,0x3d,0x70,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,
|
0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x3d,0x30,0x29,0x0a,0x62,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,
|
||||||
0x34,0x5f,0x74,0x20,0x62,0x3d,0x70,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x31,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x62,0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,
|
0x65,0x3d,0x28,0x61,0x3e,0x3e,0x62,0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x7c,0x28,0x62,0x3c,0x3c,0x28,0x36,0x34,0x2d,0x62,0x69,0x74,0x5f,0x6f,0x66,
|
||||||
0x3d,0x30,0x29,0x0a,0x62,0x3d,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x28,0x61,0x3e,0x3e,0x62,0x69,0x74,0x5f,
|
0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x32,0x20,0x74,0x6d,0x70,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x34,0x20,
|
||||||
0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x7c,0x28,0x62,0x3c,0x3c,0x28,0x36,0x34,0x2d,0x62,0x69,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x29,0x3b,0x0a,0x75,0x69,
|
0x6d,0x61,0x73,0x6b,0x3d,0x28,0x75,0x63,0x68,0x61,0x72,0x34,0x29,0x28,0x33,0x2c,0x32,0x2c,0x31,0x2c,0x30,0x29,0x3b,0x0a,0x74,0x6d,0x70,0x2e,0x78,0x3d,0x61,0x73,
|
||||||
0x6e,0x74,0x32,0x20,0x74,0x6d,0x70,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x63,0x68,0x61,0x72,0x34,0x20,0x6d,0x61,0x73,0x6b,0x3d,0x28,0x75,0x63,0x68,0x61,
|
0x5f,0x75,0x69,0x6e,0x74,0x28,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x34,0x28,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,
|
||||||
0x72,0x34,0x29,0x28,0x33,0x2c,0x32,0x2c,0x31,0x2c,0x30,0x29,0x3b,0x0a,0x74,0x6d,0x70,0x2e,0x78,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x28,0x73,0x68,0x75,0x66,
|
0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x2e,0x79,0x29,0x2c,0x6d,0x61,0x73,0x6b,0x29,0x29,0x3b,0x0a,0x74,0x6d,0x70,0x2e,0x79,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,
|
||||||
0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x34,0x28,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x2e,0x79,0x29,
|
0x28,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x34,0x28,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x76,0x61,0x6c,0x75,
|
||||||
0x2c,0x6d,0x61,0x73,0x6b,0x29,0x29,0x3b,0x0a,0x74,0x6d,0x70,0x2e,0x79,0x3d,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x28,0x73,0x68,0x75,0x66,0x66,0x6c,0x65,0x28,0x61,
|
0x65,0x29,0x2e,0x78,0x29,0x2c,0x6d,0x61,0x73,0x6b,0x29,0x29,0x3b,0x0a,0x76,0x61,0x6c,0x75,0x65,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x74,0x6d,0x70,
|
||||||
0x73,0x5f,0x75,0x63,0x68,0x61,0x72,0x34,0x28,0x61,0x73,0x5f,0x75,0x69,0x6e,0x74,0x32,0x28,0x76,0x61,0x6c,0x75,0x65,0x29,0x2e,0x78,0x29,0x2c,0x6d,0x61,0x73,0x6b,
|
0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x3d,0x28,0x76,0x61,0x6c,0x75,0x65,0x26,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,
|
||||||
0x29,0x29,0x3b,0x0a,0x76,0x61,0x6c,0x75,0x65,0x3d,0x61,0x73,0x5f,0x75,0x6c,0x6f,0x6e,0x67,0x28,0x74,0x6d,0x70,0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,
|
0x28,0x2d,0x31,0x29,0x3c,0x3c,0x32,0x31,0x29,0x29,0x7c,0x69,0x3b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,
|
||||||
0x5b,0x69,0x5d,0x3d,0x28,0x76,0x61,0x6c,0x75,0x65,0x26,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x2d,0x31,0x29,0x3c,0x3c,0x32,0x31,0x29,0x29,
|
0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,
|
||||||
0x7c,0x69,0x3b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,
|
0x2b,0x28,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,
|
||||||
0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,0x28,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x3e,
|
0x53,0x2a,0x32,0x29,0x29,0x26,0x28,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x29,0x29,0x3c,0x3c,0x33,
|
||||||
0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,0x29,0x26,0x28,0x43,0x4f,0x55,
|
0x29,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,
|
||||||
0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x29,0x29,0x3c,0x3c,0x33,0x29,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x61,0x74,0x6f,
|
0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,0x28,0x28,0x76,0x61,0x6c,0x75,
|
||||||
0x6d,0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,
|
0x65,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,0x29,0x3c,0x3c,0x33,0x29,0x2b,
|
||||||
0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,0x28,0x28,0x76,0x61,0x6c,0x75,0x65,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,
|
0x34,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,
|
||||||
0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,0x29,0x3c,0x3c,0x33,0x29,0x2b,0x34,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x7d,0x0a,0x69,
|
0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x20,0x74,0x30,0x3d,0x63,0x6f,0x75,0x6e,0x74,
|
||||||
0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x69,0x6e,0x74,0x20,0x74,0x30,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x30,
|
0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x74,0x31,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x31,0x5d,
|
||||||
0x5d,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x74,0x31,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,
|
0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x30,0x5d,0x3d,0x74,0x30,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,
|
||||||
0x72,0x73,0x5b,0x30,0x5d,0x5b,0x30,0x5d,0x3d,0x74,0x30,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x30,0x5d,0x5b,0x31,0x5d,0x3d,0x74,0x31,
|
0x30,0x5d,0x5b,0x31,0x5d,0x3d,0x74,0x31,0x2d,0x31,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,
|
||||||
0x2d,0x31,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x31,0x3b,0x20,0x69,0x3c,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,
|
0x3c,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,0x30,0x2b,0x3d,
|
||||||
0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,0x30,0x2b,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,
|
0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x31,0x2b,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,
|
||||||
0x5b,0x69,0x5d,0x5b,0x30,0x5d,0x3b,0x0a,0x74,0x31,0x2b,0x3d,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,
|
0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,0x30,0x5d,0x3d,0x74,0x30,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,
|
||||||
0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,0x30,0x5d,0x3d,0x74,0x30,0x2d,0x31,0x3b,0x0a,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5b,0x69,0x5d,0x5b,0x31,0x5d,0x3d,
|
0x73,0x5b,0x69,0x5d,0x5b,0x31,0x5d,0x3d,0x74,0x31,0x2d,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x4c,0x4f,
|
||||||
0x74,0x31,0x2d,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x3b,0x20,0x69,
|
0x43,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,
|
||||||
0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,
|
0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
|
||||||
0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x3d,
|
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
|
||||||
0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x73,0x75,0x62,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,
|
0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x73,0x75,0x62,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,
|
||||||
0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,0x28,0x28,0x28,0x64,0x61,0x74,0x61,0x3e,0x3e,0x28,0x36,0x34,0x2d,
|
0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,0x28,0x28,0x28,0x64,0x61,0x74,0x61,
|
||||||
0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,0x29,0x26,0x28,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,
|
0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,0x29,0x26,0x28,0x43,0x4f,
|
||||||
0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x29,0x29,0x3c,0x3c,0x33,0x29,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,
|
0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x53,0x49,0x5a,0x45,0x2d,0x31,0x29,0x29,0x3c,0x3c,0x33,0x29,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x74,0x6d,
|
||||||
0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x64,0x61,0x74,0x61,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,
|
0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x64,0x61,0x74,0x61,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,
|
||||||
0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x4e,0x2d,0x31,0x2d,0x74,0x69,0x64,
|
0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x7b,
|
||||||
0x3b,0x20,0x69,0x3e,0x3d,0x30,0x3b,0x20,0x69,0x2d,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,
|
0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x4e,0x2d,0x31,0x3b,0x20,0x69,0x3e,0x3d,0x30,0x3b,0x20,0x2d,0x2d,0x69,0x29,0x0a,0x7b,0x0a,0x63,0x6f,
|
||||||
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3d,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x3b,
|
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x64,0x61,0x74,0x61,0x3d,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,
|
||||||
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x73,0x75,0x62,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,
|
0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x6b,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x73,0x75,0x62,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,
|
||||||
0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,0x2b,
|
0x6c,0x65,0x20,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x5f,0x61,0x74,0x6f,0x6d,0x69,0x63,
|
||||||
0x28,0x28,0x64,0x61,0x74,0x61,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,0x29,
|
0x2b,0x28,0x28,0x64,0x61,0x74,0x61,0x3e,0x3e,0x28,0x36,0x34,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x29,
|
||||||
0x3c,0x3c,0x33,0x29,0x2b,0x34,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x64,0x61,0x74,0x61,0x3b,0x0a,0x7d,0x0a,0x62,
|
0x29,0x3c,0x3c,0x33,0x29,0x2b,0x34,0x29,0x2c,0x31,0x29,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x64,0x61,0x74,0x61,0x3b,0x0a,0x7d,0x0a,
|
||||||
0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x5f,0x5f,
|
0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,
|
||||||
0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x62,0x75,0x66,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
|
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,0x31,0x3d,0x4e,0x2d,0x31,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
||||||
0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x63,0x6f,0x75,0x6e,0x74,0x65,0x72,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
|
||||||
0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x46,0x49,0x4e,0x41,0x4c,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x41,0x54,0x43,0x48,0x5f,0x53,
|
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x49,0x5a,0x45,0x2d,0x46,0x49,0x4e,0x41,0x4c,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x4f,0x56,0x45,0x52,0x4c,0x41,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x7b,0x0a,0x63,
|
0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x4e,0x31,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,
|
||||||
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6c,0x65,0x6e,0x3d,0x28,0x4e,0x2d,0x69,0x3c,0x46,0x49,0x4e,0x41,0x4c,0x5f,0x53,0x4f,0x52,
|
0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,
|
||||||
0x54,0x5f,0x42,0x41,0x54,0x43,0x48,0x5f,0x53,0x49,0x5a,0x45,0x29,0x3f,0x28,0x4e,0x2d,0x69,0x29,0x3a,0x46,0x49,0x4e,0x41,0x4c,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,
|
0x33,0x32,0x5b,0x69,0x2a,0x32,0x2b,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,
|
||||||
0x41,0x54,0x43,0x48,0x5f,0x53,0x49,0x5a,0x45,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x74,0x69,0x64,0x3b,0x20,
|
0x53,0x2a,0x32,0x29,0x3b,0x0a,0x69,0x66,0x28,0x76,0x61,0x6c,0x75,0x65,0x21,0x3d,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,0x5b,0x69,0x2a,0x32,0x2b,0x33,
|
||||||
0x6a,0x3c,0x6c,0x65,0x6e,0x3b,0x20,0x6a,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x62,0x75,0x66,0x5b,0x6a,0x5d,
|
0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,0x29,0x29,0x0a,0x63,
|
||||||
0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x2b,0x6a,0x5d,0x3b,0x0a,0x69,0x66,0x28,0x74,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,
|
0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x69,0x66,0x28,0x28,0x69,0x3e,0x30,0x29,0x26,0x26,0x28,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,0x5b,0x69,
|
||||||
0x36,0x34,0x5f,0x74,0x20,0x70,0x72,0x65,0x76,0x5f,0x74,0x3d,0x62,0x75,0x66,0x5b,0x30,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x31,
|
0x2a,0x32,0x2d,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,0x2a,0x32,0x29,
|
||||||
0x3b,0x20,0x69,0x3c,0x6c,0x65,0x6e,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x3d,0x62,0x75,0x66,0x5b,0x69,
|
0x29,0x3d,0x3d,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x0a,0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x31,
|
||||||
0x5d,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x70,0x72,0x65,0x76,0x5f,0x74,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,
|
0x3d,0x69,0x2b,0x32,0x3b,0x0a,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x28,0x69,0x31,0x3c,0x4e,0x29,0x26,0x26,0x28,0x28,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x33,0x32,
|
||||||
0x20,0x74,0x32,0x3d,0x70,0x72,0x65,0x76,0x5f,0x74,0x3b,0x0a,0x69,0x6e,0x74,0x20,0x6a,0x3d,0x69,0x2d,0x31,0x3b,0x0a,0x64,0x6f,0x0a,0x7b,0x0a,0x62,0x75,0x66,0x5b,
|
0x5b,0x69,0x31,0x2a,0x32,0x2b,0x31,0x5d,0x3e,0x3e,0x28,0x33,0x32,0x2d,0x43,0x4f,0x55,0x4e,0x54,0x49,0x4e,0x47,0x5f,0x53,0x4f,0x52,0x54,0x5f,0x42,0x49,0x54,0x53,
|
||||||
0x6a,0x2b,0x31,0x5d,0x3d,0x70,0x72,0x65,0x76,0x5f,0x74,0x3b,0x0a,0x2d,0x2d,0x6a,0x3b,0x0a,0x69,0x66,0x28,0x6a,0x3c,0x30,0x29,0x0a,0x62,0x72,0x65,0x61,0x6b,0x3b,
|
0x2a,0x32,0x29,0x29,0x3d,0x3d,0x76,0x61,0x6c,0x75,0x65,0x29,0x29,0x0a,0x2b,0x2b,0x69,0x31,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x0a,0x70,0x72,0x65,0x76,0x5f,0x74,0x3d,0x62,0x75,0x66,0x5b,0x6a,0x5d,0x3b,0x0a,0x7d,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x28,0x74,0x3c,0x70,0x72,0x65,0x76,0x5f,
|
0x74,0x20,0x6a,0x3d,0x69,0x3b,0x20,0x6a,0x3c,0x69,0x31,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x3d,0x69,
|
||||||
0x74,0x29,0x3b,0x0a,0x62,0x75,0x66,0x5b,0x6a,0x2b,0x31,0x5d,0x3d,0x74,0x3b,0x0a,0x74,0x3d,0x74,0x32,0x3b,0x0a,0x7d,0x0a,0x70,0x72,0x65,0x76,0x5f,0x74,0x3d,0x74,
|
0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6a,0x5d,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6b,0x3d,0x6a,0x2b,0x31,0x3b,0x20,
|
||||||
0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x3d,0x74,0x69,0x64,0x3b,0x20,0x6a,0x3c,0x6c,0x65,0x6e,
|
0x6b,0x3c,0x69,0x31,0x3b,0x20,0x2b,0x2b,0x6b,0x29,0x0a,0x7b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x29,0x0a,0x7b,0x0a,
|
||||||
0x3b,0x20,0x6a,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x2b,0x6a,
|
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x31,0x3d,0x74,0x3b,0x0a,0x74,0x3d,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,
|
||||||
0x5d,0x3d,0x62,0x75,0x66,0x5b,0x6a,0x5d,0x3b,0x0a,0x7d,0x0a,0x2d,0x2d,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,
|
0x5d,0x3b,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6b,0x5d,0x3d,0x74,0x31,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x6a,0x5d,
|
||||||
0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,
|
0x3d,0x74,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,
|
||||||
0x29,0x28,0x74,0x6d,0x70,0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,
|
0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x2d,0x2d,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,
|
||||||
0x69,0x3c,0x3d,0x4e,0x3b,0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,
|
0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x28,0x74,0x6d,0x70,
|
||||||
0x69,0x5d,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x26,0x28,0x28,0x31,0x3c,0x3c,0x32,0x31,0x29,0x2d,0x31,0x29,0x5d,
|
0x5f,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x74,0x69,0x64,0x3b,0x20,0x69,0x3c,0x3d,0x4e,0x3b,
|
||||||
0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
0x20,0x69,0x2b,0x3d,0x42,0x57,0x54,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x69,0x5d,0x3d,0x69,0x6e,
|
||||||
0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x77,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x5f,0x5f,
|
0x70,0x75,0x74,0x5b,0x69,0x6e,0x64,0x69,0x63,0x65,0x73,0x5b,0x69,0x5d,0x26,0x28,0x28,0x31,0x3c,0x3c,0x32,0x31,0x29,0x2d,0x31,0x29,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,
|
||||||
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,
|
0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,
|
||||||
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,
|
0x63,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x62,0x77,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
||||||
0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3d,0x67,0x65,0x74,
|
0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
||||||
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
|
0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,
|
||||||
0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x3d,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2a,0x28,0x33,
|
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,
|
||||||
0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x28,0x2a,0x68,0x61,
|
0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x3d,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,
|
||||||
0x73,0x68,0x26,0x30,0x78,0x66,0x66,0x66,0x66,0x66,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3c,0x62,0x77,0x74,0x5f,
|
0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,
|
||||||
0x6d,0x61,0x78,0x5f,0x73,0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,0x61,0x74,0x6f,0x6d,
|
0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x28,0x2a,0x68,0x61,0x73,0x68,0x26,0x30,0x78,
|
||||||
0x69,0x63,0x5f,0x61,0x64,0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,
|
0x66,0x66,0x66,0x66,0x66,0x29,0x3b,0x0a,0x69,0x66,0x28,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3c,0x62,0x77,0x74,0x5f,0x6d,0x61,0x78,0x5f,0x73,
|
||||||
0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x2c,0x31,0x29,0x2a,0x28,0x33,0x36,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,
|
0x69,0x7a,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x69,0x6e,0x64,0x65,0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x61,0x64,
|
||||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x29,0x2b,0x31,0x3b,0x0a,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x69,0x6e,0x64,
|
0x64,0x28,0x28,0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,0x20,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x69,0x6e,0x74,0x2a,0x29,0x28,0x66,0x69,0x6c,0x74,0x65,
|
||||||
0x65,0x78,0x5d,0x3d,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,
|
0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x2c,0x31,0x29,0x2a,0x28,0x33,0x36,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||||
0x6f,0x6c,0x6c,0x20,0x38,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x2b,0x2b,
|
0x5f,0x74,0x29,0x29,0x2b,0x31,0x3b,0x0a,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x69,0x6e,0x64,0x65,0x78,0x5d,0x3d,0x6e,
|
||||||
0x69,0x29,0x0a,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x69,0x2b,0x31,0x5d,0x3d,0x68,0x61,
|
0x6f,0x6e,0x63,0x65,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x38,
|
||||||
0x73,0x68,0x5b,0x69,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x70,0x61,0x72,0x65,
|
0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x66,0x69,
|
||||||
0x5f,0x62,0x61,0x74,0x63,0x68,0x32,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,
|
0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x69,0x6e,0x64,0x65,0x78,0x2b,0x69,0x2b,0x31,0x5d,0x3d,0x68,0x61,0x73,0x68,0x5b,0x69,0x5d,
|
||||||
0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,
|
0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x70,0x72,0x65,0x70,0x61,0x72,0x65,0x5f,0x62,0x61,0x74,0x63,
|
||||||
0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,
|
0x68,0x32,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,0x67,
|
||||||
0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3d,0x67,
|
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,
|
||||||
0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x29,0x0a,0x7b,
|
||||||
0x4e,0x3d,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x2d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,
|
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,
|
||||||
0x73,0x69,0x7a,0x65,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x66,0x69,0x6c,0x74,0x65,0x72,
|
0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x4e,0x3d,0x66,0x69,0x6c,
|
||||||
0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x3d,0x4e,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x2d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x28,
|
||||||
0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x3d,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,
|
0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x3d,0x3d,0x30,0x29,0x0a,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,
|
||||||
0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x3d,0x66,0x69,0x6c,
|
0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x3d,0x4e,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x68,0x61,
|
||||||
0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2b,0x4e,0x29,0x2a,0x39,0x2b,0x31,0x3b,0x0a,
|
0x73,0x68,0x3d,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
|
||||||
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x53,0x54,0x41,0x47,0x45,
|
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x3d,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,
|
||||||
0x31,0x5f,0x53,0x49,0x5a,0x45,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d,0x26,0x30,0x78,0x66,0x66,0x66,0x66,0x66,
|
0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x28,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x2b,0x4e,0x29,0x2a,0x39,0x2b,0x31,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,
|
||||||
0x29,0x3b,0x0a,0x64,0x61,0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x5d,0x3d,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,
|
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x53,0x54,0x41,0x47,0x45,0x31,0x5f,0x53,0x49,0x5a,
|
||||||
0x73,0x69,0x7a,0x65,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x38,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,
|
0x45,0x2b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x5b,0x31,0x5d,0x26,0x30,0x78,0x66,0x66,0x66,0x66,0x66,0x29,0x3b,0x0a,0x64,0x61,
|
||||||
0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x68,0x61,0x73,0x68,0x5b,0x69,0x5d,0x3d,0x66,0x69,0x6c,0x74,
|
0x74,0x61,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x5d,0x3d,0x73,0x74,0x61,0x67,0x65,0x32,0x5f,0x73,0x69,0x7a,0x65,0x3b,
|
||||||
0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x5b,0x69,0x2b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,
|
0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x38,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
||||||
0x66,0x69,0x6e,0x64,0x5f,0x73,0x68,0x61,0x72,0x65,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,
|
0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x38,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x68,0x61,0x73,0x68,0x5b,0x69,0x5d,0x3d,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,
|
||||||
0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
0x68,0x61,0x73,0x68,0x5b,0x69,0x2b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x66,0x69,0x6e,0x64,0x5f,
|
||||||
0x32,0x5f,0x74,0x2a,0x20,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,
|
0x73,0x68,0x61,0x72,0x65,0x73,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,
|
||||||
0x72,0x67,0x65,0x74,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x68,0x61,0x72,0x65,0x73,0x29,0x0a,
|
0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,
|
||||||
0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,
|
0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2c,
|
||||||
0x74,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x73,0x68,0x61,0x72,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,
|
||||||
0x5f,0x69,0x6e,0x64,0x65,0x78,0x2a,0x34,0x2b,0x33,0x5d,0x3c,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
|
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x3d,0x67,0x65,0x74,0x5f,0x67,0x6c,0x6f,
|
||||||
0x33,0x32,0x5f,0x74,0x20,0x69,0x64,0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x68,0x61,0x72,0x65,0x73,0x2b,0x30,0x78,0x46,0x46,0x29,
|
0x62,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,
|
||||||
0x3b,0x0a,0x69,0x66,0x28,0x69,0x64,0x78,0x3c,0x30,0x78,0x46,0x46,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,0x73,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x66,0x69,0x6c,0x74,0x65,
|
0x78,0x2a,0x34,0x2b,0x33,0x5d,0x3c,0x74,0x61,0x72,0x67,0x65,0x74,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
||||||
0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x2b,0x67,
|
0x69,0x64,0x78,0x3d,0x61,0x74,0x6f,0x6d,0x69,0x63,0x5f,0x69,0x6e,0x63,0x28,0x73,0x68,0x61,0x72,0x65,0x73,0x2b,0x30,0x78,0x46,0x46,0x29,0x3b,0x0a,0x69,0x66,0x28,
|
||||||
0x6c,0x6f,0x62,0x61,0x6c,0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x2a,0x39,0x2b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,
|
0x69,0x64,0x78,0x3c,0x30,0x78,0x46,0x46,0x29,0x0a,0x73,0x68,0x61,0x72,0x65,0x73,0x5b,0x69,0x64,0x78,0x5d,0x3d,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,
|
||||||
0x4f,0x54,0x41,0x54,0x45,0x28,0x76,0x2c,0x63,0x29,0x20,0x28,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x76,0x2c,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x63,
|
0x61,0x73,0x68,0x65,0x73,0x5b,0x28,0x66,0x69,0x6c,0x74,0x65,0x72,0x65,0x64,0x5f,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x30,0x5d,0x2b,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
||||||
0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x58,0x4f,0x52,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,0x28,0x76,0x29,0x20,0x5e,0x20,0x28,0x77,0x29,0x29,0x0a,
|
0x5f,0x69,0x6e,0x64,0x65,0x78,0x29,0x2a,0x39,0x2b,0x31,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x54,0x41,0x54,0x45,
|
||||||
0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x50,0x4c,0x55,0x53,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,0x28,0x76,0x29,0x20,0x2b,0x20,0x28,0x77,0x29,0x29,0x0a,0x5f,0x5f,
|
0x28,0x76,0x2c,0x63,0x29,0x20,0x28,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x76,0x2c,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x63,0x29,0x29,0x0a,0x23,0x64,
|
||||||
0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,
|
0x65,0x66,0x69,0x6e,0x65,0x20,0x58,0x4f,0x52,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,0x28,0x76,0x29,0x20,0x5e,0x20,0x28,0x77,0x29,0x29,0x0a,0x23,0x64,0x65,0x66,0x69,
|
||||||
0x65,0x28,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,
|
0x6e,0x65,0x20,0x50,0x4c,0x55,0x53,0x28,0x76,0x2c,0x77,0x29,0x20,0x28,0x28,0x76,0x29,0x20,0x2b,0x20,0x28,0x77,0x29,0x29,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,
|
||||||
0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x53,0x61,0x6c,0x73,0x61,0x32,0x30,0x5f,0x58,0x4f,0x52,0x4b,0x65,0x79,0x53,0x74,0x72,0x65,0x61,0x6d,0x28,0x5f,
|
0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x53,0x41,0x4c,
|
||||||
0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x65,0x79,0x73,0x2c,0x5f,0x5f,0x67,
|
0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,
|
||||||
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
0x76,0x6f,0x69,0x64,0x20,0x53,0x61,0x6c,0x73,0x61,0x32,0x30,0x5f,0x58,0x4f,0x52,0x4b,0x65,0x79,0x53,0x74,0x72,0x65,0x61,0x6d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,
|
||||||
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x65,0x79,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
||||||
0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
||||||
0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,
|
||||||
0x5f,0x74,0x20,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
|
0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,
|
||||||
0x36,0x34,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x67,0x2a,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,
|
0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x3d,
|
||||||
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2b,0x31,0x32,0x38,0x3b,0x0a,0x7b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,
|
0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,
|
||||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,
|
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x67,0x2a,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x6f,0x75,0x74,0x70,0x75,
|
||||||
0x74,0x2d,0x31,0x32,0x38,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,
|
0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2b,0x31,0x32,0x38,0x3b,0x0a,0x7b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||||
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x3b,0x20,0x69,0x3c,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2d,0x31,0x32,0x38,
|
||||||
0x74,0x29,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x70,0x5b,0x69,0x5d,0x3d,
|
0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x30,0x3b,0x0a,0x7d,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x3d,
|
0x74,0x20,0x69,0x3d,0x74,0x3b,0x20,0x69,0x3c,0x31,0x32,0x38,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x20,0x69,
|
||||||
0x6b,0x65,0x79,0x73,0x2b,0x67,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,
|
0x2b,0x3d,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x29,0x0a,0x70,0x5b,0x69,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,
|
||||||
0x70,0x75,0x74,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x74,0x2a,0x36,0x34,
|
0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6b,0x3d,0x6b,0x65,0x79,0x73,0x2b,
|
||||||
0x29,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
0x67,0x2a,0x38,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x3d,0x6f,
|
||||||
0x32,0x5f,0x74,0x20,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x5d,0x3b,
|
0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x28,0x74,0x2a,0x36,0x34,0x29,0x29,0x2f,0x73,0x69,
|
||||||
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x3d,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
|
0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6f,
|
||||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x32,0x3d,0x6b,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
|
||||||
0x6a,0x33,0x3d,0x6b,0x5b,0x32,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x34,0x3d,0x6b,0x5b,0x33,0x5d,0x3b,
|
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x3d,0x6b,0x5b,0x30,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||||
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x31,0x3d,0x6b,0x5b,0x34,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
|
0x5f,0x74,0x20,0x6a,0x32,0x3d,0x6b,0x5b,0x31,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x33,0x3d,0x6b,0x5b,
|
||||||
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x32,0x3d,0x6b,0x5b,0x35,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
0x32,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x34,0x3d,0x6b,0x5b,0x33,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,
|
||||||
0x74,0x20,0x6a,0x31,0x33,0x3d,0x6b,0x5b,0x36,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x34,0x3d,0x6b,
|
0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x31,0x3d,0x6b,0x5b,0x34,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
||||||
0x5b,0x37,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x30,0x3d,0x30,0x78,0x36,0x31,0x37,0x30,0x37,0x38,0x36,
|
0x32,0x5f,0x74,0x20,0x6a,0x31,0x32,0x3d,0x6b,0x5b,0x35,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x33,
|
||||||
0x35,0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x35,0x3d,0x30,0x78,0x33,0x33,0x32,0x30,0x36,0x34,0x36,0x45,
|
0x3d,0x6b,0x5b,0x36,0x5d,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x34,0x3d,0x6b,0x5b,0x37,0x5d,0x3b,0x0a,
|
||||||
0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x30,0x3d,0x30,0x78,0x37,0x39,0x36,0x32,0x32,0x44,0x33,0x32,
|
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x30,0x3d,0x30,0x78,0x36,0x31,0x37,0x30,0x37,0x38,0x36,0x35,0x55,0x3b,0x0a,0x63,
|
||||||
0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x35,0x3d,0x30,0x78,0x36,0x42,0x32,0x30,0x36,0x35,0x37,0x34,
|
0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x35,0x3d,0x30,0x78,0x33,0x33,0x32,0x30,0x36,0x34,0x36,0x45,0x55,0x3b,0x0a,0x63,0x6f,
|
||||||
0x55,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x36,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
|
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x30,0x3d,0x30,0x78,0x37,0x39,0x36,0x32,0x32,0x44,0x33,0x32,0x55,0x3b,0x0a,0x63,0x6f,
|
||||||
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x37,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,0x3d,0x30,
|
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x31,0x35,0x3d,0x30,0x78,0x36,0x42,0x32,0x30,0x36,0x35,0x37,0x34,0x55,0x3b,0x0a,0x63,0x6f,
|
||||||
0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x39,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,
|
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x36,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x74,0x2a,0x36,0x34,0x3b,0x20,0x69,0x3c,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x69,0x2b,0x3d,0x53,
|
0x74,0x20,0x6a,0x37,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,
|
||||||
0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x36,0x34,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,
|
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x39,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
||||||
0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,0x38,0x5f,0x31,0x3d,0x6a,0x38,0x2b,0x28,0x69,0x2f,0x36,0x34,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x69,0x3d,0x74,0x2a,0x36,0x34,0x3b,0x20,0x69,0x3c,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x69,0x2b,0x3d,0x53,0x41,0x4c,0x53,0x41,0x32,
|
||||||
0x78,0x30,0x3d,0x6a,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x3d,0x6a,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x36,0x34,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x78,0x32,0x3d,0x6a,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x33,0x3d,0x6a,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x74,0x20,0x6a,0x38,0x5f,0x31,0x3d,0x6a,0x38,0x2b,0x28,0x69,0x2f,0x36,0x34,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x30,0x3d,0x6a,0x30,
|
||||||
0x78,0x34,0x3d,0x6a,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x35,0x3d,0x6a,0x35,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x3d,0x6a,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x32,0x3d,0x6a,0x32,
|
||||||
0x78,0x36,0x3d,0x6a,0x36,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x37,0x3d,0x6a,0x37,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x33,0x3d,0x6a,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x34,0x3d,0x6a,0x34,
|
||||||
0x78,0x38,0x3d,0x6a,0x38,0x5f,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x39,0x3d,0x6a,0x39,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x35,0x3d,0x6a,0x35,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x36,0x3d,0x6a,0x36,
|
||||||
0x74,0x20,0x78,0x31,0x30,0x3d,0x6a,0x31,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x31,0x3d,0x6a,0x31,0x31,0x3b,0x0a,0x75,0x69,0x6e,
|
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x37,0x3d,0x6a,0x37,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x38,0x3d,0x6a,0x38,
|
||||||
0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x32,0x3d,0x6a,0x31,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x33,0x3d,0x6a,0x31,0x33,0x3b,
|
0x5f,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x39,0x3d,0x6a,0x39,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x30,
|
||||||
0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x34,0x3d,0x6a,0x31,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x35,0x3d,
|
0x3d,0x6a,0x31,0x30,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x31,0x3d,0x6a,0x31,0x31,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
||||||
0x6a,0x31,0x35,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x35,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,
|
0x20,0x78,0x31,0x32,0x3d,0x6a,0x31,0x32,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x33,0x3d,0x6a,0x31,0x33,0x3b,0x0a,0x75,0x69,0x6e,0x74,
|
||||||
0x32,0x5f,0x74,0x20,0x6a,0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,
|
0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x34,0x3d,0x6a,0x31,0x34,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x78,0x31,0x35,0x3d,0x6a,0x31,0x35,0x3b,0x0a,
|
||||||
0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x30,0x2c,0x78,0x31,0x32,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,
|
0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x35,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6a,
|
||||||
0x52,0x28,0x20,0x78,0x38,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x34,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,
|
0x3d,0x30,0x3b,0x20,0x6a,0x3c,0x31,0x30,0x3b,0x20,0x2b,0x2b,0x6a,0x29,0x0a,0x7b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,
|
||||||
0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x34,0x29,0x2c,0x31,
|
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x30,0x2c,0x78,0x31,0x32,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x38,
|
||||||
0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,
|
0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x34,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x32,0x3d,0x58,0x4f,
|
||||||
0x78,0x38,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
|
0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x34,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,
|
||||||
0x28,0x20,0x78,0x35,0x2c,0x78,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,
|
0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x78,0x38,0x29,0x2c,0x31,
|
||||||
0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,
|
0x38,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x35,0x2c,
|
||||||
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x39,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,
|
0x78,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
|
||||||
0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,
|
0x28,0x20,0x78,0x39,0x2c,0x78,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,
|
||||||
0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x36,0x29,0x2c,0x37,0x29,
|
0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x39,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,
|
||||||
0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,
|
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,
|
||||||
0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,
|
0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x36,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,
|
||||||
0x78,0x32,0x2c,0x78,0x31,0x34,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,
|
0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,0x30,0x29,0x2c,0x39,0x29,
|
||||||
0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,
|
0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x32,0x2c,0x78,0x31,
|
||||||
0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x78,0x31,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,0x52,0x28,
|
0x34,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
|
||||||
0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,
|
0x28,0x20,0x78,0x36,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,
|
||||||
0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,0x33,0x29,0x2c,0x31,0x33,
|
0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x78,0x31,0x31,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x37,0x2c,0x52,
|
||||||
0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,
|
0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,
|
||||||
0x78,0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
|
0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,0x33,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,
|
||||||
0x28,0x20,0x78,0x30,0x2c,0x78,0x33,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,
|
0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x78,0x37,0x29,0x2c,0x31,
|
||||||
0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x31,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,0x4f,0x54,
|
0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x30,0x2c,
|
||||||
0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x32,0x2c,0x78,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,
|
0x78,0x33,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x32,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,
|
||||||
0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,
|
0x20,0x78,0x31,0x2c,0x78,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x33,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,
|
||||||
0x4f,0x52,0x28,0x20,0x78,0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x35,0x2c,0x78,0x34,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,
|
0x4c,0x55,0x53,0x28,0x20,0x78,0x32,0x2c,0x78,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x30,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x30,0x2c,0x52,0x4f,0x54,
|
||||||
0x78,0x37,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x35,0x29,0x2c,0x39,
|
0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x33,0x2c,0x78,0x32,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x36,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,
|
||||||
0x29,0x29,0x3b,0x0a,0x78,0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,
|
0x36,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x35,0x2c,0x78,0x34,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x37,0x3d,0x58,0x4f,
|
||||||
0x36,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,
|
0x52,0x28,0x20,0x78,0x37,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x36,0x2c,0x78,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,
|
||||||
0x20,0x78,0x34,0x2c,0x78,0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,
|
0x34,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x37,0x2c,0x78,0x36,0x29,0x2c,0x31,0x33,
|
||||||
0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x78,0x39,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x38,0x2c,0x52,0x4f,
|
0x29,0x29,0x3b,0x0a,0x78,0x35,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x34,0x2c,0x78,
|
||||||
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x78,0x31,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,
|
0x37,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,0x31,0x31,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x31,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,
|
||||||
0x78,0x39,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x31,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,
|
0x28,0x78,0x31,0x30,0x2c,0x78,0x39,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x38,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x38,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,
|
||||||
0x30,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x38,0x29,0x2c,0x31,0x38,
|
0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x78,0x31,0x30,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x39,0x3d,0x58,0x4f,0x52,0x28,0x20,0x78,0x39,0x2c,0x52,0x4f,
|
||||||
0x29,0x29,0x3b,0x0a,0x78,0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,
|
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x38,0x2c,0x78,0x31,0x31,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x30,0x3d,0x58,0x4f,0x52,
|
||||||
0x78,0x31,0x34,0x29,0x2c,0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,
|
0x28,0x78,0x31,0x30,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x20,0x78,0x39,0x2c,0x78,0x38,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x78,
|
||||||
0x53,0x28,0x78,0x31,0x32,0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,
|
0x31,0x32,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x32,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x78,0x31,0x34,0x29,0x2c,
|
||||||
0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x31,0x32,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,
|
0x37,0x29,0x29,0x3b,0x0a,0x78,0x31,0x33,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x33,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,
|
||||||
0x31,0x35,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x7d,0x0a,
|
0x2c,0x78,0x31,0x35,0x29,0x2c,0x39,0x29,0x29,0x3b,0x0a,0x78,0x31,0x34,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x34,0x2c,0x52,0x4f,0x54,0x41,0x54,0x45,0x28,0x50,0x4c,
|
||||||
0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x30,0x2c,0x6a,0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x5d,
|
0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x78,0x31,0x32,0x29,0x2c,0x31,0x33,0x29,0x29,0x3b,0x0a,0x78,0x31,0x35,0x3d,0x58,0x4f,0x52,0x28,0x78,0x31,0x35,0x2c,0x52,0x4f,
|
||||||
0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x2c,0x6a,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x32,0x2c,
|
0x54,0x41,0x54,0x45,0x28,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x78,0x31,0x33,0x29,0x2c,0x31,0x38,0x29,0x29,0x3b,0x0a,0x7d,0x0a,0x6f,0x75,0x74,0x70,0x75,
|
||||||
0x6a,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x33,0x2c,0x6a,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,
|
0x74,0x5b,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x30,0x2c,0x6a,0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,
|
||||||
0x75,0x74,0x5b,0x34,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x34,0x2c,0x6a,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x50,0x4c,0x55,
|
0x28,0x78,0x31,0x2c,0x6a,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x32,0x2c,0x6a,0x32,0x29,0x3b,0x0a,
|
||||||
0x53,0x28,0x78,0x35,0x2c,0x6a,0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x36,0x2c,0x6a,0x36,0x29,0x3b,
|
0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x33,0x2c,0x6a,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x34,0x5d,
|
||||||
0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x37,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x37,0x2c,0x6a,0x37,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x38,
|
0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x34,0x2c,0x6a,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x35,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x35,0x2c,
|
||||||
0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x38,0x2c,0x6a,0x38,0x5f,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x39,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,
|
0x6a,0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x36,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x36,0x2c,0x6a,0x36,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,
|
||||||
0x78,0x39,0x2c,0x6a,0x39,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x6a,0x31,0x30,0x29,
|
0x75,0x74,0x5b,0x37,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x37,0x2c,0x6a,0x37,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x38,0x5d,0x3d,0x50,0x4c,0x55,
|
||||||
0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x6a,0x31,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,
|
0x53,0x28,0x78,0x38,0x2c,0x6a,0x38,0x5f,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x39,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x39,0x2c,0x6a,0x39,
|
||||||
0x75,0x74,0x5b,0x31,0x32,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x6a,0x31,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x33,0x5d,
|
0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x30,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x30,0x2c,0x6a,0x31,0x30,0x29,0x3b,0x0a,0x6f,0x75,0x74,
|
||||||
0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x33,0x2c,0x6a,0x31,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,
|
0x70,0x75,0x74,0x5b,0x31,0x31,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x31,0x2c,0x6a,0x31,0x31,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x32,
|
||||||
0x78,0x31,0x34,0x2c,0x6a,0x31,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x6a,0x31,
|
0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x32,0x2c,0x6a,0x31,0x32,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x33,0x5d,0x3d,0x50,0x4c,0x55,0x53,
|
||||||
0x35,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x2b,0x3d,0x28,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,
|
0x28,0x78,0x31,0x33,0x2c,0x6a,0x31,0x33,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x34,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x34,0x2c,0x6a,
|
||||||
0x36,0x34,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,
|
0x31,0x34,0x29,0x3b,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x5b,0x31,0x35,0x5d,0x3d,0x50,0x4c,0x55,0x53,0x28,0x78,0x31,0x35,0x2c,0x6a,0x31,0x35,0x29,0x3b,0x0a,0x6f,
|
||||||
0x43,0x4c,0x4b,0x5f,0x47,0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x31,0x36,0x29,0x0a,
|
0x75,0x74,0x70,0x75,0x74,0x2b,0x3d,0x28,0x53,0x41,0x4c,0x53,0x41,0x32,0x30,0x5f,0x47,0x52,0x4f,0x55,0x50,0x5f,0x53,0x49,0x5a,0x45,0x2a,0x36,0x34,0x29,0x2f,0x73,
|
||||||
0x7b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,
|
0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x7d,0x0a,0x62,0x61,0x72,0x72,0x69,0x65,0x72,0x28,0x43,0x4c,0x4b,0x5f,0x47,
|
||||||
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2b,0x33,0x29,0x2f,0x73,0x69,0x7a,
|
0x4c,0x4f,0x42,0x41,0x4c,0x5f,0x4d,0x45,0x4d,0x5f,0x46,0x45,0x4e,0x43,0x45,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3c,0x31,0x36,0x29,0x0a,0x7b,0x0a,0x5f,0x5f,0x67,
|
||||||
0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x70,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x74,0x3d,0x3d,
|
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x2b,0x28,0x6f,0x75,0x74,0x70,0x75,
|
||||||
0x30,0x29,0x26,0x26,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x5b,0x28,0x6f,0x75,
|
0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2b,0x33,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,
|
||||||
0x74,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,
|
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x3b,0x0a,0x70,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x28,0x74,0x3d,0x3d,0x30,0x29,0x26,0x26,0x28,
|
||||||
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x29,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x28,0x28,0x34,0x2d,0x28,
|
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x0a,0x6f,0x75,0x74,0x70,0x75,0x74,0x73,0x5b,0x28,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,
|
||||||
0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,
|
0x6f,0x66,0x66,0x73,0x65,0x74,0x2b,0x6f,0x75,0x74,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x29,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x33,
|
||||||
0x4f,0x55,0x4e,0x44,0x53,0x20,0x32,0x34,0x20,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x36,0x34,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x20,0x28,0x28,0x28,
|
0x32,0x5f,0x74,0x29,0x5d,0x20,0x26,0x3d,0x20,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x3e,0x3e,0x28,0x28,0x34,0x2d,0x28,0x6f,0x75,0x74,0x70,0x75,
|
||||||
0x61,0x29,0x20,0x3c,0x3c,0x20,0x62,0x29,0x20,0x7c,0x20,0x28,0x28,0x61,0x29,0x20,0x3e,0x3e,0x20,0x63,0x29,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,
|
0x74,0x5f,0x73,0x69,0x7a,0x65,0x26,0x33,0x29,0x29,0x3c,0x3c,0x33,0x29,0x3b,0x0a,0x7d,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,
|
||||||
0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x63,0x5b,0x32,0x5d,0x5b,0x52,0x4f,0x55,0x4e,0x44,0x53,0x5d,0x3d,0x7b,
|
0x20,0x32,0x34,0x20,0x0a,0x23,0x64,0x65,0x66,0x69,0x6e,0x65,0x20,0x52,0x36,0x34,0x28,0x61,0x2c,0x62,0x2c,0x63,0x29,0x20,0x28,0x28,0x28,0x61,0x29,0x20,0x3c,0x3c,
|
||||||
0x0a,0x7b,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x20,0x62,0x29,0x20,0x7c,0x20,0x28,0x28,0x61,0x29,0x20,0x3e,0x3e,0x20,0x63,0x29,0x29,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,
|
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x72,0x63,0x5b,0x32,0x5d,0x5b,0x52,0x4f,0x55,0x4e,0x44,0x53,0x5d,0x3d,0x7b,0x0a,0x7b,0x30,0x78,0x30,
|
||||||
0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,
|
0x38,0x30,0x38,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
||||||
0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,
|
0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
||||||
0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,
|
0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,
|
||||||
0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x38,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,
|
0x38,0x30,0x30,0x39,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,
|
||||||
0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,
|
0x30,0x30,0x38,0x42,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x39,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
||||||
0x2c,0x0a,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x33,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,
|
0x38,0x30,0x30,0x32,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x30,
|
||||||
0x2c,0x0a,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
|
||||||
0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,
|
0x30,0x30,0x30,0x41,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x38,0x31,0x55,0x4c,0x2c,0x0a,0x30,0x78,0x38,
|
||||||
0x7d,0x2c,0x0a,0x7b,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x38,0x30,0x55,0x4c,0x2c,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,
|
||||||
0x30,0x55,0x4c,0x2c,0x0a,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,
|
0x30,0x30,0x30,0x31,0x55,0x4c,0x2c,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x38,0x30,0x30,0x30,0x38,0x30,0x30,0x38,0x55,0x4c,0x7d,0x2c,0x0a,0x7b,0x30,
|
||||||
0x2c,0x30,0x55,0x4c,0x2c,0x0a,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,
|
0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x0a,
|
||||||
0x4c,0x2c,0x30,0x55,0x4c,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,
|
0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,
|
||||||
0x6f,0x5b,0x32,0x35,0x5d,0x5b,0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x36,0x34,0x7d,0x2c,0x7b,0x34,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x34,0x33,0x2c,0x32,
|
0x0a,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,0x2c,0x30,0x55,0x4c,
|
||||||
0x31,0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x34,0x33,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x35,0x30,0x7d,0x2c,0x0a,0x7b,0x20,0x31,0x2c,0x36,0x33,0x7d,0x2c,0x7b,0x20,0x36,0x2c,
|
0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x72,0x6f,0x5b,0x32,0x35,0x5d,
|
||||||
0x35,0x38,0x7d,0x2c,0x7b,0x32,0x35,0x2c,0x33,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x35,0x36,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x34,0x36,0x7d,0x2c,0x0a,0x7b,0x36,0x32,
|
0x5b,0x32,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x36,0x34,0x7d,0x2c,0x7b,0x34,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x34,0x33,0x2c,0x32,0x31,0x7d,0x2c,0x7b,0x32,
|
||||||
0x2c,0x32,0x7d,0x2c,0x7b,0x35,0x35,0x2c,0x39,0x7d,0x2c,0x7b,0x33,0x39,0x2c,0x32,0x35,0x7d,0x2c,0x7b,0x34,0x31,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x20,0x32,0x2c,0x36,
|
0x31,0x2c,0x34,0x33,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x35,0x30,0x7d,0x2c,0x0a,0x7b,0x20,0x31,0x2c,0x36,0x33,0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x35,0x38,0x7d,0x2c,0x7b,
|
||||||
0x32,0x7d,0x2c,0x0a,0x7b,0x32,0x38,0x2c,0x33,0x36,0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x34,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x36,0x31,0x7d,0x2c,0x7b,0x34,0x35,0x2c,
|
0x32,0x35,0x2c,0x33,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x35,0x36,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x34,0x36,0x7d,0x2c,0x0a,0x7b,0x36,0x32,0x2c,0x32,0x7d,0x2c,0x7b,
|
||||||
0x31,0x39,0x7d,0x2c,0x7b,0x36,0x31,0x2c,0x33,0x7d,0x2c,0x0a,0x7b,0x32,0x37,0x2c,0x33,0x37,0x7d,0x2c,0x7b,0x33,0x36,0x2c,0x32,0x38,0x7d,0x2c,0x7b,0x31,0x30,0x2c,
|
0x35,0x35,0x2c,0x39,0x7d,0x2c,0x7b,0x33,0x39,0x2c,0x32,0x35,0x7d,0x2c,0x7b,0x34,0x31,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x20,0x32,0x2c,0x36,0x32,0x7d,0x2c,0x0a,0x7b,
|
||||||
0x35,0x34,0x7d,0x2c,0x7b,0x31,0x35,0x2c,0x34,0x39,0x7d,0x2c,0x7b,0x35,0x36,0x2c,0x38,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,
|
0x32,0x38,0x2c,0x33,0x36,0x7d,0x2c,0x7b,0x32,0x30,0x2c,0x34,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x36,0x31,0x7d,0x2c,0x7b,0x34,0x35,0x2c,0x31,0x39,0x7d,0x2c,0x7b,
|
||||||
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x36,0x2c,0x31,0x32,0x2c,0x31,0x38,0x2c,0x32,0x34,0x2c,
|
0x36,0x31,0x2c,0x33,0x7d,0x2c,0x0a,0x7b,0x32,0x37,0x2c,0x33,0x37,0x7d,0x2c,0x7b,0x33,0x36,0x2c,0x32,0x38,0x7d,0x2c,0x7b,0x31,0x30,0x2c,0x35,0x34,0x7d,0x2c,0x7b,
|
||||||
0x0a,0x31,0x2c,0x37,0x2c,0x31,0x33,0x2c,0x31,0x39,0x2c,0x32,0x30,0x2c,0x0a,0x32,0x2c,0x38,0x2c,0x31,0x34,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x0a,0x33,0x2c,0x39,
|
0x31,0x35,0x2c,0x34,0x39,0x7d,0x2c,0x7b,0x35,0x36,0x2c,0x38,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,
|
||||||
0x2c,0x31,0x30,0x2c,0x31,0x36,0x2c,0x32,0x32,0x2c,0x0a,0x34,0x2c,0x35,0x2c,0x31,0x31,0x2c,0x31,0x37,0x2c,0x32,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,
|
0x74,0x20,0x69,0x6e,0x74,0x20,0x61,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x36,0x2c,0x31,0x32,0x2c,0x31,0x38,0x2c,0x32,0x34,0x2c,0x0a,0x31,0x2c,0x37,0x2c,
|
||||||
0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,
|
0x31,0x33,0x2c,0x31,0x39,0x2c,0x32,0x30,0x2c,0x0a,0x32,0x2c,0x38,0x2c,0x31,0x34,0x2c,0x31,0x35,0x2c,0x32,0x31,0x2c,0x0a,0x33,0x2c,0x39,0x2c,0x31,0x30,0x2c,0x31,
|
||||||
0x34,0x2c,0x0a,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x0a,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x0a,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,
|
0x36,0x2c,0x32,0x32,0x2c,0x0a,0x34,0x2c,0x35,0x2c,0x31,0x31,0x2c,0x31,0x37,0x2c,0x32,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,
|
||||||
0x2c,0x32,0x2c,0x0a,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,
|
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x62,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x2c,
|
||||||
0x74,0x20,0x69,0x6e,0x74,0x20,0x63,0x5b,0x32,0x35,0x5d,0x5b,0x33,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x31,0x2c,0x32,0x7d,0x2c,0x7b,0x20,0x31,0x2c,0x32,0x2c,
|
0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x0a,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x0a,0x33,0x2c,0x34,0x2c,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x0a,0x34,
|
||||||
0x33,0x7d,0x2c,0x7b,0x20,0x32,0x2c,0x33,0x2c,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x34,0x2c,0x30,0x7d,0x2c,0x7b,0x20,0x34,0x2c,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,
|
0x2c,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,
|
||||||
0x20,0x35,0x2c,0x36,0x2c,0x37,0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x37,0x2c,0x38,0x7d,0x2c,0x7b,0x20,0x37,0x2c,0x38,0x2c,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x39,0x2c,
|
0x20,0x63,0x5b,0x32,0x35,0x5d,0x5b,0x33,0x5d,0x3d,0x7b,0x0a,0x7b,0x20,0x30,0x2c,0x31,0x2c,0x32,0x7d,0x2c,0x7b,0x20,0x31,0x2c,0x32,0x2c,0x33,0x7d,0x2c,0x7b,0x20,
|
||||||
0x35,0x7d,0x2c,0x7b,0x20,0x39,0x2c,0x35,0x2c,0x36,0x7d,0x2c,0x0a,0x7b,0x31,0x30,0x2c,0x31,0x31,0x2c,0x31,0x32,0x7d,0x2c,0x7b,0x31,0x31,0x2c,0x31,0x32,0x2c,0x31,
|
0x32,0x2c,0x33,0x2c,0x34,0x7d,0x2c,0x7b,0x20,0x33,0x2c,0x34,0x2c,0x30,0x7d,0x2c,0x7b,0x20,0x34,0x2c,0x30,0x2c,0x31,0x7d,0x2c,0x0a,0x7b,0x20,0x35,0x2c,0x36,0x2c,
|
||||||
0x33,0x7d,0x2c,0x7b,0x31,0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x31,0x34,0x2c,0x31,0x30,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x31,0x30,0x2c,
|
0x37,0x7d,0x2c,0x7b,0x20,0x36,0x2c,0x37,0x2c,0x38,0x7d,0x2c,0x7b,0x20,0x37,0x2c,0x38,0x2c,0x39,0x7d,0x2c,0x7b,0x20,0x38,0x2c,0x39,0x2c,0x35,0x7d,0x2c,0x7b,0x20,
|
||||||
0x31,0x31,0x7d,0x2c,0x0a,0x7b,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x7d,0x2c,0x7b,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x31,0x37,0x2c,0x31,
|
0x39,0x2c,0x35,0x2c,0x36,0x7d,0x2c,0x0a,0x7b,0x31,0x30,0x2c,0x31,0x31,0x2c,0x31,0x32,0x7d,0x2c,0x7b,0x31,0x31,0x2c,0x31,0x32,0x2c,0x31,0x33,0x7d,0x2c,0x7b,0x31,
|
||||||
0x38,0x2c,0x31,0x39,0x7d,0x2c,0x7b,0x31,0x38,0x2c,0x31,0x39,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x31,0x39,0x2c,0x31,0x35,0x2c,0x31,0x36,0x7d,0x2c,0x0a,0x7b,0x32,0x30,
|
0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x7d,0x2c,0x7b,0x31,0x33,0x2c,0x31,0x34,0x2c,0x31,0x30,0x7d,0x2c,0x7b,0x31,0x34,0x2c,0x31,0x30,0x2c,0x31,0x31,0x7d,0x2c,0x0a,
|
||||||
0x2c,0x32,0x31,0x2c,0x32,0x32,0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x7d,0x2c,0x7b,0x32,
|
0x7b,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x7d,0x2c,0x7b,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x7d,0x2c,0x7b,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x7d,
|
||||||
0x33,0x2c,0x32,0x34,0x2c,0x32,0x30,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x32,0x30,0x2c,0x32,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,
|
0x2c,0x7b,0x31,0x38,0x2c,0x31,0x39,0x2c,0x31,0x35,0x7d,0x2c,0x7b,0x31,0x39,0x2c,0x31,0x35,0x2c,0x31,0x36,0x7d,0x2c,0x0a,0x7b,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,
|
||||||
0x74,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,
|
0x32,0x7d,0x2c,0x7b,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x7d,0x2c,0x7b,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x7d,0x2c,0x7b,0x32,0x33,0x2c,0x32,0x34,0x2c,
|
||||||
0x30,0x2c,0x31,0x31,0x2c,0x31,0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x2c,0x0a,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x2c,0x0a,0x35,
|
0x32,0x30,0x7d,0x2c,0x7b,0x32,0x34,0x2c,0x32,0x30,0x2c,0x32,0x31,0x7d,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x63,0x6f,0x6e,0x73,0x74,0x61,0x6e,0x74,0x20,0x63,0x6f,0x6e,
|
||||||
0x2c,0x36,0x2c,0x37,0x2c,0x38,0x2c,0x39,0x2c,0x0a,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x61,0x74,
|
0x73,0x74,0x20,0x69,0x6e,0x74,0x20,0x64,0x5b,0x32,0x35,0x5d,0x3d,0x7b,0x0a,0x30,0x2c,0x31,0x2c,0x32,0x2c,0x33,0x2c,0x34,0x2c,0x0a,0x31,0x30,0x2c,0x31,0x31,0x2c,
|
||||||
0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,
|
0x31,0x32,0x2c,0x31,0x33,0x2c,0x31,0x34,0x2c,0x0a,0x32,0x30,0x2c,0x32,0x31,0x2c,0x32,0x32,0x2c,0x32,0x33,0x2c,0x32,0x34,0x2c,0x0a,0x35,0x2c,0x36,0x2c,0x37,0x2c,
|
||||||
0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x28,0x5f,0x5f,0x67,
|
0x38,0x2c,0x39,0x2c,0x0a,0x31,0x35,0x2c,0x31,0x36,0x2c,0x31,0x37,0x2c,0x31,0x38,0x2c,0x31,0x39,0x0a,0x7d,0x3b,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,
|
||||||
0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,
|
0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,
|
||||||
0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,
|
0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
||||||
0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
|
0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x73,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,
|
||||||
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,
|
0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x2c,0x75,0x69,0x6e,0x74,
|
||||||
0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
|
0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,
|
||||||
0x33,0x32,0x5f,0x74,0x20,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,
|
0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,
|
||||||
0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,
|
0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,
|
||||||
0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x28,
|
0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,
|
||||||
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2a,0x67,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,
|
0x75,0x72,0x6e,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x63,0x6f,0x6e,
|
||||||
0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,
|
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x3d,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,
|
||||||
0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x73,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x63,0x6f,
|
0x34,0x5f,0x74,0x29,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x74,0x72,0x69,0x64,0x65,0x29,0x2a,0x67,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,
|
||||||
0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,
|
0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,
|
||||||
0x7a,0x65,0x73,0x5b,0x67,0x5d,0x2b,0x31,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,
|
0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x73,0x2b,0x69,0x6e,0x70,0x75,0x74,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,
|
||||||
0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,
|
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x73,0x5b,0x67,
|
||||||
0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,
|
0x5d,0x2b,0x31,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,
|
||||||
0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,
|
0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,
|
||||||
0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,
|
0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x30,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,
|
||||||
0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
|
0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x73,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,
|
||||||
0x74,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,
|
0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,
|
||||||
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x77,0x6f,0x72,0x64,0x73,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x2b,0x2b,0x69,0x6e,0x70,0x75,
|
0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x75,
|
||||||
0x74,0x29,0x0a,0x7b,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x2b,0x2b,0x77,
|
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,
|
||||||
0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x69,0x66,0x28,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x3d,0x31,0x37,0x29,0x0a,0x7b,0x0a,0x23,0x70,
|
0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x77,0x6f,0x72,0x64,0x73,0x3b,0x20,0x2b,0x2b,0x69,0x2c,0x2b,0x2b,0x69,0x6e,0x70,0x75,0x74,0x29,0x0a,0x7b,0x0a,
|
||||||
0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,
|
0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x2a,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x2b,0x2b,0x77,0x6f,0x72,0x64,0x49,0x6e,
|
||||||
0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,
|
0x64,0x65,0x78,0x3b,0x0a,0x69,0x66,0x28,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x3d,0x31,0x37,0x29,0x0a,0x7b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,
|
||||||
0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,
|
0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,
|
||||||
0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,
|
0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,
|
||||||
0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,
|
0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,
|
||||||
0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,
|
0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,
|
||||||
0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,
|
0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,
|
||||||
0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,0x77,0x6f,0x72,0x64,
|
0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,
|
||||||
0x49,0x6e,0x64,0x65,0x78,0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,
|
0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,
|
||||||
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,
|
||||||
0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,
|
0x3d,0x30,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x3d,0x30,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
||||||
0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,
|
0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,0x70,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,
|
||||||
0x61,0x69,0x6c,0x7c,0x3d,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x70,0x5b,0x69,0x5d,0x29,0x3c,0x3c,0x28,0x69,0x2a,0x38,0x29,0x3b,0x0a,0x7d,0x0a,
|
0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x29,0x69,0x6e,0x70,0x75,0x74,0x3b,0x0a,0x66,0x6f,0x72,0x20,0x28,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
||||||
0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x61,0x69,0x6c,0x5e,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,
|
0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x74,0x61,0x69,0x6c,0x7c,0x3d,
|
||||||
0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,
|
0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x70,0x5b,0x69,0x5d,0x29,0x3c,0x3c,0x28,0x69,0x2a,0x38,0x29,0x3b,0x0a,0x7d,0x0a,0x41,0x5b,0x77,0x6f,0x72,
|
||||||
0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x74,0x61,0x69,0x6c,0x5e,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,
|
||||||
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,
|
0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,
|
||||||
0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,
|
0x65,0x2a,0x38,0x29,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
|
||||||
0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,
|
0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x31,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,
|
||||||
0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,
|
0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,
|
||||||
0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,
|
0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,
|
||||||
0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,
|
0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,
|
||||||
0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,
|
0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,
|
||||||
0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,
|
0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,
|
||||||
0x3b,0x20,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,
|
0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,
|
||||||
0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,
|
0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,
|
||||||
0x7d,0x0a,0x7d,0x0a,0x5f,0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,
|
0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,
|
||||||
0x75,0x70,0x5f,0x73,0x69,0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,
|
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x5f,
|
||||||
0x73,0x68,0x61,0x33,0x5f,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,
|
0x5f,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x5f,0x5f,0x28,0x28,0x72,0x65,0x71,0x64,0x5f,0x77,0x6f,0x72,0x6b,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x73,0x69,
|
||||||
0x38,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,
|
0x7a,0x65,0x28,0x33,0x32,0x2c,0x31,0x2c,0x31,0x29,0x29,0x29,0x0a,0x5f,0x5f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x20,0x76,0x6f,0x69,0x64,0x20,0x73,0x68,0x61,0x33,0x5f,
|
||||||
0x69,0x7a,0x65,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x38,0x5f,0x74,0x2a,0x20,
|
||||||
0x36,0x34,0x5f,0x74,0x2a,0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,
|
0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x2c,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2c,0x75,
|
||||||
0x3d,0x67,0x65,0x74,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x2c,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,
|
||||||
0x20,0x67,0x3d,0x67,0x65,0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,
|
0x20,0x68,0x61,0x73,0x68,0x65,0x73,0x29,0x0a,0x7b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x3d,0x67,0x65,0x74,0x5f,
|
||||||
0x74,0x75,0x72,0x6e,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x5f,0x5f,
|
0x6c,0x6f,0x63,0x61,0x6c,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x67,0x3d,0x67,0x65,
|
||||||
0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,
|
0x74,0x5f,0x67,0x72,0x6f,0x75,0x70,0x5f,0x69,0x64,0x28,0x30,0x29,0x3b,0x0a,0x69,0x66,0x28,0x74,0x3e,0x3d,0x32,0x35,0x29,0x0a,0x72,0x65,0x74,0x75,0x72,0x6e,0x3b,
|
||||||
0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,
|
0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x73,0x3d,0x74,0x20,0x25,0x20,0x35,0x3b,0x0a,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,
|
||||||
0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,
|
0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x2a,0x20,0x69,0x6e,0x70,0x75,0x74,0x3d,0x28,0x5f,0x5f,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
||||||
0x74,0x20,0x43,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,
|
0x36,0x34,0x5f,0x74,0x2a,0x29,0x28,0x69,0x6e,0x70,0x75,0x74,0x5f,0x64,0x61,0x74,0x61,0x29,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
||||||
0x0a,0x41,0x5b,0x74,0x5d,0x3d,0x28,0x74,0x3c,0x31,0x36,0x29,0x3f,0x69,0x6e,0x70,0x75,0x74,0x5b,0x74,0x5d,0x3a,0x30,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,
|
0x36,0x34,0x5f,0x74,0x20,0x41,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x43,0x5b,0x32,
|
||||||
0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,
|
0x35,0x5d,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x20,0x44,0x5b,0x32,0x35,0x5d,0x3b,0x0a,0x41,0x5b,0x74,0x5d,
|
||||||
0x6e,0x74,0x33,0x32,0x5f,0x74,0x2a,0x29,0x28,0x41,0x29,0x2b,0x39,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x3d,0x67,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,
|
0x3d,0x28,0x74,0x3c,0x31,0x36,0x29,0x3f,0x69,0x6e,0x70,0x75,0x74,0x5b,0x74,0x5d,0x3a,0x30,0x3b,0x0a,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,
|
||||||
0x6f,0x73,0x5b,0x30,0x5d,0x3d,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,
|
0x33,0x32,0x5f,0x74,0x2a,0x20,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x3d,0x28,0x5f,0x5f,0x6c,0x6f,0x63,0x61,0x6c,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,
|
||||||
0x28,0x6e,0x6f,0x6e,0x63,0x65,0x26,0x30,0x78,0x46,0x46,0x29,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x3d,
|
0x74,0x2a,0x29,0x28,0x41,0x29,0x2b,0x39,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x2b,0x3d,0x67,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,
|
||||||
0x28,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x29,0x7c,0x28,0x6e,0x6f,0x6e,0x63,
|
0x3d,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x30,0x5d,0x26,0x30,0x78,0x46,0x46,0x46,0x46,0x46,0x46,0x55,0x29,0x7c,0x28,0x28,0x6e,0x6f,0x6e,0x63,
|
||||||
0x65,0x3e,0x3e,0x38,0x29,0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,
|
0x65,0x26,0x30,0x78,0x46,0x46,0x29,0x3c,0x3c,0x32,0x34,0x29,0x3b,0x0a,0x6e,0x6f,0x6e,0x63,0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x3d,0x28,0x6e,0x6f,0x6e,0x63,
|
||||||
0x73,0x69,0x7a,0x65,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,
|
0x65,0x5f,0x70,0x6f,0x73,0x5b,0x31,0x5d,0x26,0x30,0x78,0x46,0x46,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x29,0x7c,0x28,0x6e,0x6f,0x6e,0x63,0x65,0x3e,0x3e,0x38,0x29,
|
||||||
0x74,0x33,0x32,0x5f,0x74,0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,
|
0x3b,0x0a,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,0x20,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x2f,
|
||||||
0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x28,
|
0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x63,0x6f,0x6e,0x73,0x74,0x20,0x75,0x69,0x6e,0x74,0x33,0x32,0x5f,0x74,
|
||||||
0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,
|
0x20,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x3d,0x69,0x6e,0x70,0x75,0x74,0x5f,0x73,0x69,0x7a,0x65,0x20,0x25,0x20,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,
|
||||||
0x29,0x29,0x29,0x3c,0x3c,0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,
|
0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x3b,0x0a,0x41,0x5b,0x77,0x6f,0x72,0x64,0x49,0x6e,0x64,0x65,0x78,0x5d,0x20,0x5e,0x3d,0x20,0x28,0x75,0x69,0x6e,0x74,0x36,
|
||||||
0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,
|
0x34,0x5f,0x74,0x29,0x28,0x28,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x28,0x30,0x78,0x30,0x32,0x7c,0x28,0x31,0x3c,0x3c,0x32,0x29,0x29,0x29,0x3c,0x3c,
|
||||||
0x6c,0x6c,0x20,0x52,0x4f,0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,
|
0x28,0x74,0x61,0x69,0x6c,0x5f,0x73,0x69,0x7a,0x65,0x2a,0x38,0x29,0x29,0x3b,0x0a,0x41,0x5b,0x31,0x36,0x5d,0x20,0x5e,0x3d,0x20,0x30,0x78,0x38,0x30,0x30,0x30,0x30,
|
||||||
0x3b,0x20,0x2b,0x2b,0x69,0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,
|
0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x55,0x4c,0x3b,0x0a,0x23,0x70,0x72,0x61,0x67,0x6d,0x61,0x20,0x75,0x6e,0x72,0x6f,0x6c,0x6c,0x20,0x52,0x4f,
|
||||||
0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,
|
0x55,0x4e,0x44,0x53,0x0a,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x69,0x3d,0x30,0x3b,0x20,0x69,0x3c,0x52,0x4f,0x55,0x4e,0x44,0x53,0x3b,0x20,0x2b,0x2b,0x69,
|
||||||
0x5d,0x5d,0x5e,0x52,0x36,0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,
|
0x29,0x0a,0x7b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x73,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x31,0x30,0x5d,0x5e,0x41,0x5b,0x73,
|
||||||
0x28,0x41,0x5b,0x61,0x5b,0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,
|
0x2b,0x31,0x35,0x5d,0x5e,0x41,0x5b,0x73,0x2b,0x32,0x30,0x5d,0x3b,0x0a,0x44,0x5b,0x74,0x5d,0x3d,0x43,0x5b,0x62,0x5b,0x32,0x30,0x2b,0x73,0x5d,0x5d,0x5e,0x52,0x36,
|
||||||
0x31,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,
|
0x34,0x28,0x43,0x5b,0x62,0x5b,0x35,0x2b,0x73,0x5d,0x5d,0x2c,0x31,0x2c,0x36,0x33,0x29,0x3b,0x0a,0x43,0x5b,0x74,0x5d,0x3d,0x52,0x36,0x34,0x28,0x41,0x5b,0x61,0x5b,
|
||||||
0x5d,0x5b,0x31,0x5d,0x5d,0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,
|
0x74,0x5d,0x5d,0x5e,0x44,0x5b,0x62,0x5b,0x74,0x5d,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x2c,0x72,0x6f,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x29,0x3b,0x0a,
|
||||||
0x74,0x3d,0x3d,0x30,0x29,0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,
|
0x41,0x5b,0x64,0x5b,0x74,0x5d,0x5d,0x3d,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x30,0x5d,0x5d,0x5e,0x28,0x28,0x7e,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x31,0x5d,0x5d,
|
||||||
0x65,0x73,0x2b,0x3d,0x67,0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,
|
0x29,0x26,0x43,0x5b,0x63,0x5b,0x74,0x5d,0x5b,0x32,0x5d,0x5d,0x29,0x3b,0x0a,0x41,0x5b,0x74,0x5d,0x20,0x5e,0x3d,0x20,0x72,0x63,0x5b,0x28,0x74,0x3d,0x3d,0x30,0x29,
|
||||||
0x68,0x65,0x73,0x5b,0x74,0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
|
0x3f,0x30,0x3a,0x31,0x5d,0x5b,0x69,0x5d,0x3b,0x20,0x0a,0x7d,0x0a,0x69,0x66,0x28,0x74,0x3c,0x34,0x29,0x0a,0x7b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x2b,0x3d,0x67,
|
||||||
|
0x2a,0x28,0x33,0x32,0x2f,0x73,0x69,0x7a,0x65,0x6f,0x66,0x28,0x75,0x69,0x6e,0x74,0x36,0x34,0x5f,0x74,0x29,0x29,0x3b,0x0a,0x68,0x61,0x73,0x68,0x65,0x73,0x5b,0x74,
|
||||||
|
0x5d,0x3d,0x41,0x5b,0x74,0x5d,0x3b,0x0a,0x7d,0x0a,0x7d,0x0a,0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xmrig
|
} // namespace xmrig
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ xmrig::OclAstroBWTRunner::OclAstroBWTRunner(size_t index, const OclLaunchData &d
|
|||||||
|
|
||||||
m_bwt_allocation_size = static_cast<uint64_t>(m_intensity) * BWT_DATA_STRIDE;
|
m_bwt_allocation_size = static_cast<uint64_t>(m_intensity) * BWT_DATA_STRIDE;
|
||||||
m_batch_size1 = static_cast<uint32_t>(m_bwt_allocation_size / STAGE1_DATA_STRIDE + 255U) & ~255U;
|
m_batch_size1 = static_cast<uint32_t>(m_bwt_allocation_size / STAGE1_DATA_STRIDE + 255U) & ~255U;
|
||||||
|
m_bwt_allocation_size = std::max(m_bwt_allocation_size, m_batch_size1 * STAGE1_DATA_STRIDE);
|
||||||
|
|
||||||
m_bwt_data_sizes_host = new uint32_t[m_batch_size1];
|
m_bwt_data_sizes_host = new uint32_t[m_batch_size1];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2008-2018 Advanced Micro Devices, Inc.
|
* Copyright (c) 2008-2018 Advanced Micro Devices, Inc.
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2020 Patrick Bollinger <https://github.com/pjbollinger>
|
||||||
* Copyright 2020 Patrick Bollinger <https://github.com/pjbollinger>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -20,10 +20,13 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "backend/opencl/wrappers/AdlLib.h"
|
#include "backend/opencl/wrappers/AdlLib.h"
|
||||||
|
#include "3rdparty/fmt/core.h"
|
||||||
#include "backend/opencl/wrappers/OclDevice.h"
|
#include "backend/opencl/wrappers/OclDevice.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -35,18 +38,27 @@ namespace xmrig {
|
|||||||
bool AdlLib::m_initialized = false;
|
bool AdlLib::m_initialized = false;
|
||||||
bool AdlLib::m_ready = false;
|
bool AdlLib::m_ready = false;
|
||||||
static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/";
|
static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/";
|
||||||
|
static std::map<PciTopology, std::string> hwmon_cache;
|
||||||
|
|
||||||
|
|
||||||
static inline bool sysfs_is_file(const std::string &path)
|
static inline bool sysfs_is_file(const char *path)
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
return stat(path.c_str(), &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG);
|
return stat(path, &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool sysfs_is_amdgpu(const std::string &path)
|
static inline int dir_filter(const struct dirent *dirp)
|
||||||
{
|
{
|
||||||
|
return strlen(dirp->d_name) > 5 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool sysfs_is_amdgpu(const char *path, char *buf, const char *filename)
|
||||||
|
{
|
||||||
|
strcpy(buf, filename);
|
||||||
|
|
||||||
if (!sysfs_is_file(path)) {
|
if (!sysfs_is_file(path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -63,8 +75,10 @@ static inline bool sysfs_is_amdgpu(const std::string &path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t sysfs_read(const std::string &path)
|
static uint32_t sysfs_read(const char *path, char *buf, const char *filename)
|
||||||
{
|
{
|
||||||
|
strcpy(buf, filename);
|
||||||
|
|
||||||
std::ifstream file(path);
|
std::ifstream file(path);
|
||||||
if (!file.is_open()) {
|
if (!file.is_open()) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -77,18 +91,44 @@ uint32_t sysfs_read(const std::string &path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline std::string sysfs_prefix(const PciTopology &topology)
|
static size_t sysfs_prefix(char path[PATH_MAX], const PciTopology &topology)
|
||||||
{
|
{
|
||||||
const std::string path = kPrefix + "0000:" + topology.toString().data() + "/hwmon/hwmon";
|
const auto it = hwmon_cache.find(topology);
|
||||||
|
if (it != hwmon_cache.end()) {
|
||||||
|
strcpy(path, it->second.data());
|
||||||
|
|
||||||
for (uint32_t i = 1; i < 10; ++i) {
|
return it->second.size();
|
||||||
const std::string prefix = path + std::to_string(i) + "/";
|
|
||||||
if (sysfs_is_amdgpu(prefix + "name") && (sysfs_read(prefix + "temp1_input") || sysfs_read(prefix + "power1_average"))) {
|
|
||||||
return prefix;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
char *base = fmt::format_to(path, "{}0000:{}/hwmon/", kPrefix, topology.toString());
|
||||||
|
*base = '\0';
|
||||||
|
char *end = nullptr;
|
||||||
|
|
||||||
|
struct dirent **namelist;
|
||||||
|
int n = scandir(path, &namelist, dir_filter, nullptr);
|
||||||
|
if (n < 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
if (!end) {
|
||||||
|
char *tmp = fmt::format_to(base, "{}/", namelist[n]->d_name);
|
||||||
|
end = (sysfs_is_amdgpu(path, tmp, "name") && (sysfs_read(path, tmp, "temp1_input") || sysfs_read(path, tmp, "power1_average"))) ? tmp : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(namelist[n]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(namelist);
|
||||||
|
|
||||||
|
if (end) {
|
||||||
|
*end = '\0';
|
||||||
|
hwmon_cache.insert({ topology, path });
|
||||||
|
|
||||||
|
return end - path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -124,20 +164,22 @@ AdlHealth xmrig::AdlLib::health(const OclDevice &device)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto prefix = sysfs_prefix(device.topology());
|
static char path[PATH_MAX]{};
|
||||||
if (prefix.empty()) {
|
|
||||||
|
char *buf = path + sysfs_prefix(path, device.topology());
|
||||||
|
if (buf == path) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
AdlHealth health;
|
AdlHealth health;
|
||||||
health.clock = sysfs_read(prefix + "freq1_input") / 1000000;
|
health.clock = sysfs_read(path, buf, "freq1_input") / 1000000;
|
||||||
health.memClock = sysfs_read(prefix + "freq2_input") / 1000000;
|
health.memClock = sysfs_read(path, buf, "freq2_input") / 1000000;
|
||||||
health.power = sysfs_read(prefix + "power1_average") / 1000000;
|
health.power = sysfs_read(path, buf, "power1_average") / 1000000;
|
||||||
health.rpm = sysfs_read(prefix + "fan1_input");
|
health.rpm = sysfs_read(path, buf, "fan1_input");
|
||||||
health.temperature = sysfs_read(prefix + "temp2_input") / 1000;
|
health.temperature = sysfs_read(path, buf, "temp2_input") / 1000;
|
||||||
|
|
||||||
if (!health.temperature) {
|
if (!health.temperature) {
|
||||||
health.temperature = sysfs_read(prefix + "temp1_input") / 1000;
|
health.temperature = sysfs_read(path, buf, "temp1_input") / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
return health;
|
return health;
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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
|
||||||
@@ -31,7 +25,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "base/kernel/interfaces/IBaseListener.h"
|
#include "base/kernel/interfaces/IBaseListener.h"
|
||||||
#include "base/tools/Object.h"
|
|
||||||
#include "base/tools/String.h"
|
#include "base/tools/String.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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
|
* 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
|
||||||
@@ -24,6 +20,9 @@
|
|||||||
#define XMRIG_IAPILISTENER_H
|
#define XMRIG_IAPILISTENER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/tools/Object.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
@@ -33,6 +32,9 @@ class IApiRequest;
|
|||||||
class IApiListener
|
class IApiListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
XMRIG_DISABLE_COPY_MOVE(IApiListener)
|
||||||
|
|
||||||
|
IApiListener() = default;
|
||||||
virtual ~IApiListener() = default;
|
virtual ~IApiListener() = default;
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_API
|
# ifdef XMRIG_FEATURE_API
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -27,6 +21,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "3rdparty/rapidjson/fwd.h"
|
#include "3rdparty/rapidjson/fwd.h"
|
||||||
|
#include "base/tools/Object.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
@@ -38,6 +33,8 @@ class String;
|
|||||||
class IApiRequest
|
class IApiRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
XMRIG_DISABLE_COPY_MOVE(IApiRequest)
|
||||||
|
|
||||||
enum Method {
|
enum Method {
|
||||||
METHOD_DELETE,
|
METHOD_DELETE,
|
||||||
METHOD_GET,
|
METHOD_GET,
|
||||||
@@ -67,7 +64,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
virtual ~IApiRequest() = default;
|
IApiRequest() = default;
|
||||||
|
virtual ~IApiRequest() = default;
|
||||||
|
|
||||||
virtual bool accept() = 0;
|
virtual bool accept() = 0;
|
||||||
virtual bool hasParseError() const = 0;
|
virtual bool hasParseError() const = 0;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -59,6 +59,11 @@ static void createVariables()
|
|||||||
variables.insert({ "XMRIG_HOME_DIR", Process::location(Process::HomeLocation) });
|
variables.insert({ "XMRIG_HOME_DIR", Process::location(Process::HomeLocation) });
|
||||||
variables.insert({ "XMRIG_TEMP_DIR", Process::location(Process::TempLocation) });
|
variables.insert({ "XMRIG_TEMP_DIR", Process::location(Process::TempLocation) });
|
||||||
variables.insert({ "XMRIG_DATA_DIR", Process::location(Process::DataLocation) });
|
variables.insert({ "XMRIG_DATA_DIR", Process::location(Process::DataLocation) });
|
||||||
|
|
||||||
|
String hostname = "HOSTNAME";
|
||||||
|
if (!getenv(hostname)) {
|
||||||
|
variables.insert({ std::move(hostname), Env::hostname() });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -37,6 +37,14 @@ const char *xmrig::Tags::network()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char* xmrig::Tags::origin()
|
||||||
|
{
|
||||||
|
static const char* tag = YELLOW_BG_BOLD(WHITE_BOLD_S " origin ");
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *xmrig::Tags::signal()
|
const char *xmrig::Tags::signal()
|
||||||
{
|
{
|
||||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " signal ");
|
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " signal ");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -32,6 +32,7 @@ class Tags
|
|||||||
public:
|
public:
|
||||||
static const char *config();
|
static const char *config();
|
||||||
static const char *network();
|
static const char *network();
|
||||||
|
static const char *origin();
|
||||||
static const char *signal();
|
static const char *signal();
|
||||||
|
|
||||||
# ifdef XMRIG_MINER_PROJECT
|
# ifdef XMRIG_MINER_PROJECT
|
||||||
|
|||||||
@@ -76,7 +76,12 @@ public:
|
|||||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(BasePrivate)
|
XMRIG_DISABLE_COPY_MOVE_DEFAULT(BasePrivate)
|
||||||
|
|
||||||
|
|
||||||
inline BasePrivate(Process *process) : config(load(process)) {}
|
inline BasePrivate(Process *process)
|
||||||
|
{
|
||||||
|
Log::init();
|
||||||
|
|
||||||
|
config = load(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline ~BasePrivate()
|
inline ~BasePrivate()
|
||||||
@@ -166,7 +171,7 @@ private:
|
|||||||
xmrig::Base::Base(Process *process)
|
xmrig::Base::Base(Process *process)
|
||||||
: d_ptr(new BasePrivate(process))
|
: d_ptr(new BasePrivate(process))
|
||||||
{
|
{
|
||||||
Log::init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -46,9 +46,11 @@ public:
|
|||||||
static void setProcessPriority(int priority);
|
static void setProcessPriority(int priority);
|
||||||
static void setThreadPriority(int priority);
|
static void setThreadPriority(int priority);
|
||||||
|
|
||||||
static inline const String &userAgent() { return m_userAgent; }
|
static inline bool isUserActive(uint64_t ms) { return idleTime() < ms; }
|
||||||
|
static inline const String &userAgent() { return m_userAgent; }
|
||||||
|
|
||||||
static bool isOnBatteryPower();
|
static bool isOnBatteryPower();
|
||||||
|
static uint64_t idleTime();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static char *createUserAgent();
|
static char *createUserAgent();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -107,3 +107,18 @@ bool xmrig::Platform::isOnBatteryPower()
|
|||||||
{
|
{
|
||||||
return IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited;
|
return IOPSGetTimeRemainingEstimate() != kIOPSTimeRemainingUnlimited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t xmrig::Platform::idleTime()
|
||||||
|
{
|
||||||
|
uint64_t idle_time = 0;
|
||||||
|
const auto service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"));
|
||||||
|
const auto property = IORegistryEntryCreateCFProperty(service, CFSTR("HIDIdleTime"), kCFAllocatorDefault, 0);
|
||||||
|
|
||||||
|
CFNumberGetValue((CFNumberRef)property, kCFNumberSInt64Type, &idle_time);
|
||||||
|
|
||||||
|
CFRelease(property);
|
||||||
|
IOObjectRelease(service);
|
||||||
|
|
||||||
|
return idle_time / 1000000U;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
#include "base/kernel/Platform.h"
|
#include "base/kernel/Platform.h"
|
||||||
@@ -158,3 +159,9 @@ bool xmrig::Platform::isOnBatteryPower()
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t xmrig::Platform::idleTime()
|
||||||
|
{
|
||||||
|
return std::numeric_limits<uint64_t>::max();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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,7 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
|
||||||
#include "base/kernel/Platform.h"
|
#include "base/kernel/Platform.h"
|
||||||
@@ -161,3 +162,16 @@ bool xmrig::Platform::isOnBatteryPower()
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint64_t xmrig::Platform::idleTime()
|
||||||
|
{
|
||||||
|
LASTINPUTINFO info{};
|
||||||
|
info.cbSize = sizeof(LASTINPUTINFO);
|
||||||
|
|
||||||
|
if (!GetLastInputInfo(&info)) {
|
||||||
|
return std::numeric_limits<uint64_t>::max();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<uint64_t>(GetTickCount() - info.dwTime);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -61,7 +55,6 @@ const char *BaseConfig::kColors = "colors";
|
|||||||
const char *BaseConfig::kDryRun = "dry-run";
|
const char *BaseConfig::kDryRun = "dry-run";
|
||||||
const char *BaseConfig::kHttp = "http";
|
const char *BaseConfig::kHttp = "http";
|
||||||
const char *BaseConfig::kLogFile = "log-file";
|
const char *BaseConfig::kLogFile = "log-file";
|
||||||
const char *BaseConfig::kPauseOnBattery = "pause-on-battery";
|
|
||||||
const char *BaseConfig::kPrintTime = "print-time";
|
const char *BaseConfig::kPrintTime = "print-time";
|
||||||
const char *BaseConfig::kSyslog = "syslog";
|
const char *BaseConfig::kSyslog = "syslog";
|
||||||
const char *BaseConfig::kTitle = "title";
|
const char *BaseConfig::kTitle = "title";
|
||||||
@@ -91,7 +84,6 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
|
|||||||
m_dryRun = reader.getBool(kDryRun, m_dryRun);
|
m_dryRun = reader.getBool(kDryRun, m_dryRun);
|
||||||
m_syslog = reader.getBool(kSyslog, m_syslog);
|
m_syslog = reader.getBool(kSyslog, m_syslog);
|
||||||
m_watch = reader.getBool(kWatch, m_watch);
|
m_watch = reader.getBool(kWatch, m_watch);
|
||||||
m_pauseOnBattery = reader.getBool(kPauseOnBattery, m_pauseOnBattery);
|
|
||||||
m_logFile = reader.getString(kLogFile);
|
m_logFile = reader.getString(kLogFile);
|
||||||
m_userAgent = reader.getString(kUserAgent);
|
m_userAgent = reader.getString(kUserAgent);
|
||||||
m_printTime = std::min(reader.getUint(kPrintTime, m_printTime), 3600U);
|
m_printTime = std::min(reader.getUint(kPrintTime, m_printTime), 3600U);
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -55,7 +49,6 @@ public:
|
|||||||
static const char *kDryRun;
|
static const char *kDryRun;
|
||||||
static const char *kHttp;
|
static const char *kHttp;
|
||||||
static const char *kLogFile;
|
static const char *kLogFile;
|
||||||
static const char *kPauseOnBattery;
|
|
||||||
static const char *kPrintTime;
|
static const char *kPrintTime;
|
||||||
static const char *kSyslog;
|
static const char *kSyslog;
|
||||||
static const char *kTitle;
|
static const char *kTitle;
|
||||||
@@ -72,7 +65,6 @@ public:
|
|||||||
inline bool isAutoSave() const { return m_autoSave; }
|
inline bool isAutoSave() const { return m_autoSave; }
|
||||||
inline bool isBackground() const { return m_background; }
|
inline bool isBackground() const { return m_background; }
|
||||||
inline bool isDryRun() const { return m_dryRun; }
|
inline bool isDryRun() const { return m_dryRun; }
|
||||||
inline bool isPauseOnBattery() const { return m_pauseOnBattery; }
|
|
||||||
inline bool isSyslog() const { return m_syslog; }
|
inline bool isSyslog() const { return m_syslog; }
|
||||||
inline const char *logFile() const { return m_logFile.data(); }
|
inline const char *logFile() const { return m_logFile.data(); }
|
||||||
inline const char *userAgent() const { return m_userAgent.data(); }
|
inline const char *userAgent() const { return m_userAgent.data(); }
|
||||||
@@ -100,7 +92,6 @@ protected:
|
|||||||
bool m_autoSave = true;
|
bool m_autoSave = true;
|
||||||
bool m_background = false;
|
bool m_background = false;
|
||||||
bool m_dryRun = false;
|
bool m_dryRun = false;
|
||||||
bool m_pauseOnBattery = false;
|
|
||||||
bool m_syslog = false;
|
bool m_syslog = false;
|
||||||
bool m_upgrade = false;
|
bool m_upgrade = false;
|
||||||
bool m_watch = true;
|
bool m_watch = true;
|
||||||
@@ -112,7 +103,7 @@ protected:
|
|||||||
String m_logFile;
|
String m_logFile;
|
||||||
String m_userAgent;
|
String m_userAgent;
|
||||||
Title m_title;
|
Title m_title;
|
||||||
uint32_t m_printTime = 60;
|
uint32_t m_printTime = 60;
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
TlsConfig m_tls;
|
TlsConfig m_tls;
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -260,8 +254,8 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
|
|||||||
case IConfig::DryRunKey: /* --dry-run */
|
case IConfig::DryRunKey: /* --dry-run */
|
||||||
case IConfig::HttpEnabledKey: /* --http-enabled */
|
case IConfig::HttpEnabledKey: /* --http-enabled */
|
||||||
case IConfig::DaemonKey: /* --daemon */
|
case IConfig::DaemonKey: /* --daemon */
|
||||||
|
case IConfig::SubmitToOriginKey: /* --submit-to-origin */
|
||||||
case IConfig::VerboseKey: /* --verbose */
|
case IConfig::VerboseKey: /* --verbose */
|
||||||
case IConfig::PauseOnBatteryKey: /* --pause-on-battery */
|
|
||||||
return transformBoolean(doc, key, true);
|
return transformBoolean(doc, key, true);
|
||||||
|
|
||||||
case IConfig::ColorKey: /* --no-color */
|
case IConfig::ColorKey: /* --no-color */
|
||||||
@@ -290,6 +284,8 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
|
|||||||
case IConfig::TlsKey: /* --tls */
|
case IConfig::TlsKey: /* --tls */
|
||||||
return add(doc, Pools::kPools, Pool::kTls, enable);
|
return add(doc, Pools::kPools, Pool::kTls, enable);
|
||||||
|
|
||||||
|
case IConfig::SubmitToOriginKey: /* --submit-to-origin */
|
||||||
|
return add(doc, Pools::kPools, Pool::kSubmitToOrigin, enable);
|
||||||
# ifdef XMRIG_FEATURE_HTTP
|
# ifdef XMRIG_FEATURE_HTTP
|
||||||
case IConfig::DaemonKey: /* --daemon */
|
case IConfig::DaemonKey: /* --daemon */
|
||||||
return add(doc, Pools::kPools, Pool::kDaemon, enable);
|
return add(doc, Pools::kPools, Pool::kDaemon, enable);
|
||||||
@@ -320,9 +316,6 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
|
|||||||
case IConfig::NoTitleKey: /* --no-title */
|
case IConfig::NoTitleKey: /* --no-title */
|
||||||
return set(doc, BaseConfig::kTitle, enable);
|
return set(doc, BaseConfig::kTitle, enable);
|
||||||
|
|
||||||
case IConfig::PauseOnBatteryKey: /* --pause-on-battery */
|
|
||||||
return set(doc, BaseConfig::kPauseOnBattery, enable);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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,6 +20,9 @@
|
|||||||
#define XMRIG_IBASELISTENER_H
|
#define XMRIG_IBASELISTENER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/tools/Object.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +32,10 @@ class Config;
|
|||||||
class IBaseListener
|
class IBaseListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IBaseListener() = default;
|
XMRIG_DISABLE_COPY_MOVE(IBaseListener)
|
||||||
|
|
||||||
|
IBaseListener() = default;
|
||||||
|
virtual ~IBaseListener() = default;
|
||||||
|
|
||||||
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -84,6 +78,10 @@ public:
|
|||||||
BenchSeedKey = 1046,
|
BenchSeedKey = 1046,
|
||||||
BenchHashKey = 1047,
|
BenchHashKey = 1047,
|
||||||
BenchTokenKey = 1048,
|
BenchTokenKey = 1048,
|
||||||
|
DmiKey = 1049,
|
||||||
|
HugePageSizeKey = 1050,
|
||||||
|
PauseOnActiveKey = 1051,
|
||||||
|
SubmitToOriginKey = 1052,
|
||||||
|
|
||||||
// xmrig common
|
// xmrig common
|
||||||
CPUPriorityKey = 1021,
|
CPUPriorityKey = 1021,
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
|
|||||||
# ifdef XMRIG_PROXY_PROJECT
|
# ifdef XMRIG_PROXY_PROJECT
|
||||||
memcpy(data + 78, result.nonce, 8);
|
memcpy(data + 78, result.nonce, 8);
|
||||||
# else
|
# else
|
||||||
Cvt::toHex(data + 78, 9, reinterpret_cast<const uint8_t *>(&result.nonce), 4);
|
Cvt::toHex(data + 78, 8, reinterpret_cast<const uint8_t *>(&result.nonce), 4);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
@@ -227,7 +227,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||||||
m_blockhashingblob = Json::getString(params, "blockhashing_blob");
|
m_blockhashingblob = Json::getString(params, "blockhashing_blob");
|
||||||
if (m_apiVersion == API_DERO) {
|
if (m_apiVersion == API_DERO) {
|
||||||
const uint64_t offset = Json::getUint64(params, "reserved_offset");
|
const uint64_t offset = Json::getUint64(params, "reserved_offset");
|
||||||
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2 + 1, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
|
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocktemplate.isNull() || !job.setBlob(m_blockhashingblob)) {
|
if (blocktemplate.isNull() || !job.setBlob(m_blockhashingblob)) {
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2019 Howard Chu <https://github.com/hyc>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2019 Howard Chu <https://github.com/hyc>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -80,6 +74,7 @@ const char *Pool::kPass = "pass";
|
|||||||
const char *Pool::kRigId = "rig-id";
|
const char *Pool::kRigId = "rig-id";
|
||||||
const char *Pool::kSelfSelect = "self-select";
|
const char *Pool::kSelfSelect = "self-select";
|
||||||
const char *Pool::kSOCKS5 = "socks5";
|
const char *Pool::kSOCKS5 = "socks5";
|
||||||
|
const char *Pool::kSubmitToOrigin = "submit-to-origin";
|
||||||
const char *Pool::kTls = "tls";
|
const char *Pool::kTls = "tls";
|
||||||
const char *Pool::kUrl = "url";
|
const char *Pool::kUrl = "url";
|
||||||
const char *Pool::kUser = "user";
|
const char *Pool::kUser = "user";
|
||||||
@@ -137,7 +132,8 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
|
|||||||
setKeepAlive(Json::getValue(object, kKeepalive));
|
setKeepAlive(Json::getValue(object, kKeepalive));
|
||||||
|
|
||||||
if (m_daemon.isValid()) {
|
if (m_daemon.isValid()) {
|
||||||
m_mode = MODE_SELF_SELECT;
|
m_mode = MODE_SELF_SELECT;
|
||||||
|
m_submitToOrigin = Json::getBool(object, kSubmitToOrigin, m_submitToOrigin);
|
||||||
}
|
}
|
||||||
else if (Json::getBool(object, kDaemon)) {
|
else if (Json::getBool(object, kDaemon)) {
|
||||||
m_mode = MODE_DAEMON;
|
m_mode = MODE_DAEMON;
|
||||||
@@ -237,7 +233,7 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
|
|||||||
client = new DaemonClient(id, listener);
|
client = new DaemonClient(id, listener);
|
||||||
}
|
}
|
||||||
else if (m_mode == MODE_SELF_SELECT) {
|
else if (m_mode == MODE_SELF_SELECT) {
|
||||||
client = new SelfSelectClient(id, Platform::userAgent(), listener);
|
client = new SelfSelectClient(id, Platform::userAgent(), listener, m_submitToOrigin);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
# ifdef XMRIG_ALGO_KAWPOW
|
# ifdef XMRIG_ALGO_KAWPOW
|
||||||
@@ -300,7 +296,8 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
|
|||||||
obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator);
|
obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator);
|
obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator);
|
||||||
|
obj.AddMember(StringRef(kSubmitToOrigin), m_submitToOrigin, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
@@ -319,7 +316,7 @@ std::string xmrig::Pool::printableName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_mode == MODE_SELF_SELECT) {
|
if (m_mode == MODE_SELF_SELECT) {
|
||||||
out += std::string(" self-select ") + CSI "1;" + std::to_string(m_daemon.isTLS() ? 32 : 36) + "m" + m_daemon.url().data() + CLEAR;
|
out += std::string(" self-select ") + CSI "1;" + std::to_string(m_daemon.isTLS() ? 32 : 36) + "m" + m_daemon.url().data() + WHITE_BOLD_S + (m_submitToOrigin ? " submit-to-origin" : "") + CLEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@@ -1,13 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2019 Howard Chu <https://github.com/hyc>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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 2019 Howard Chu <https://github.com/hyc>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -73,6 +67,7 @@ public:
|
|||||||
static const char *kRigId;
|
static const char *kRigId;
|
||||||
static const char *kSelfSelect;
|
static const char *kSelfSelect;
|
||||||
static const char *kSOCKS5;
|
static const char *kSOCKS5;
|
||||||
|
static const char *kSubmitToOrigin;
|
||||||
static const char *kTls;
|
static const char *kTls;
|
||||||
static const char *kUrl;
|
static const char *kUrl;
|
||||||
static const char *kUser;
|
static const char *kUser;
|
||||||
@@ -144,6 +139,7 @@ private:
|
|||||||
void setKeepAlive(const rapidjson::Value &value);
|
void setKeepAlive(const rapidjson::Value &value);
|
||||||
|
|
||||||
Algorithm m_algorithm;
|
Algorithm m_algorithm;
|
||||||
|
bool m_submitToOrigin = false;
|
||||||
Coin m_coin;
|
Coin m_coin;
|
||||||
int m_keepAlive = 0;
|
int m_keepAlive = 0;
|
||||||
Mode m_mode = MODE_POOL;
|
Mode m_mode = MODE_POOL;
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2021 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
|
||||||
@@ -134,7 +134,7 @@ void xmrig::Pools::load(const IJsonReader &reader)
|
|||||||
m_data.clear();
|
m_data.clear();
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||||
m_benchmark = std::shared_ptr<BenchConfig>(BenchConfig::create(reader.getObject(BenchConfig::kBenchmark)));
|
m_benchmark = std::shared_ptr<BenchConfig>(BenchConfig::create(reader.getObject(BenchConfig::kBenchmark), reader.getBool("dmi", true)));
|
||||||
if (m_benchmark) {
|
if (m_benchmark) {
|
||||||
m_data.emplace_back(m_benchmark);
|
m_data.emplace_back(m_benchmark);
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright 2016-2021 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
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2019 jtgrassie <https://github.com/jtgrassie>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2021 Hansie Odendaal <https://github.com/hansieodendaal>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2019 jtgrassie <https://github.com/jtgrassie>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -31,9 +26,12 @@
|
|||||||
#include "base/io/json/Json.h"
|
#include "base/io/json/Json.h"
|
||||||
#include "base/io/json/JsonRequest.h"
|
#include "base/io/json/JsonRequest.h"
|
||||||
#include "base/io/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/io/log/Tags.h"
|
||||||
#include "base/net/http/Fetch.h"
|
#include "base/net/http/Fetch.h"
|
||||||
#include "base/net/http/HttpData.h"
|
#include "base/net/http/HttpData.h"
|
||||||
#include "base/net/stratum/Client.h"
|
#include "base/net/stratum/Client.h"
|
||||||
|
#include "net/JobResult.h"
|
||||||
|
#include "base/tools/Cvt.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
@@ -54,7 +52,8 @@ static const char * const required_fields[] = { kBlocktemplateBlob, kBlockhashin
|
|||||||
} /* namespace xmrig */
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener) :
|
xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener, bool submitToOrigin) :
|
||||||
|
m_submitToOrigin(submitToOrigin),
|
||||||
m_listener(listener)
|
m_listener(listener)
|
||||||
{
|
{
|
||||||
m_httpListener = std::make_shared<HttpListener>(this);
|
m_httpListener = std::make_shared<HttpListener>(this);
|
||||||
@@ -68,6 +67,16 @@ xmrig::SelfSelectClient::~SelfSelectClient()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int64_t xmrig::SelfSelectClient::submit(const JobResult &result)
|
||||||
|
{
|
||||||
|
if (m_submitToOrigin) {
|
||||||
|
submitOriginDaemon(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_client->submit(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::SelfSelectClient::tick(uint64_t now)
|
void xmrig::SelfSelectClient::tick(uint64_t now)
|
||||||
{
|
{
|
||||||
m_client->tick(now);
|
m_client->tick(now);
|
||||||
@@ -201,6 +210,9 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result)
|
|||||||
Document doc(kObjectType);
|
Document doc(kObjectType);
|
||||||
auto &allocator = doc.GetAllocator();
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
m_blocktemplate = Json::getString(result,kBlocktemplateBlob);
|
||||||
|
m_blockDiff = Json::getUint64(result, kDifficulty);
|
||||||
|
|
||||||
Value params(kObjectType);
|
Value params(kObjectType);
|
||||||
params.AddMember(StringRef(kId), m_job.clientId().toJSON(), allocator);
|
params.AddMember(StringRef(kId), m_job.clientId().toJSON(), allocator);
|
||||||
params.AddMember(StringRef(kJobId), m_job.id().toJSON(), allocator);
|
params.AddMember(StringRef(kJobId), m_job.id().toJSON(), allocator);
|
||||||
@@ -236,6 +248,44 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::SelfSelectClient::submitOriginDaemon(const JobResult& result)
|
||||||
|
{
|
||||||
|
if (result.diff == 0 || m_blockDiff == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.actualDiff() < m_blockDiff) {
|
||||||
|
m_originNotSubmitted++;
|
||||||
|
LOG_DEBUG("%s " RED_BOLD("not submitted to origin daemon, difficulty too low") " (%" PRId64 "/%" PRId64 ") "
|
||||||
|
BLACK_BOLD(" diff ") BLACK_BOLD("%" PRIu64) BLACK_BOLD(" vs. ") BLACK_BOLD("%" PRIu64),
|
||||||
|
Tags::origin(), m_originSubmitted, m_originNotSubmitted, m_blockDiff, result.actualDiff());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *data = m_blocktemplate.data();
|
||||||
|
Cvt::toHex(data + 78, 8, reinterpret_cast<const uint8_t*>(&result.nonce), 4);
|
||||||
|
|
||||||
|
using namespace rapidjson;
|
||||||
|
Document doc(kObjectType);
|
||||||
|
|
||||||
|
Value params(kArrayType);
|
||||||
|
params.PushBack(m_blocktemplate.toJSON(), doc.GetAllocator());
|
||||||
|
|
||||||
|
JsonRequest::create(doc, m_sequence, "submitblock", params);
|
||||||
|
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend);
|
||||||
|
|
||||||
|
FetchRequest req(HTTP_POST, pool().daemon().host(), pool().daemon().port(), "/json_rpc", doc, pool().daemon().isTLS(), isQuiet());
|
||||||
|
fetch(tag(), std::move(req), m_httpListener);
|
||||||
|
|
||||||
|
m_originSubmitted++;
|
||||||
|
LOG_INFO("%s " GREEN_BOLD("submitted to origin daemon") " (%" PRId64 "/%" PRId64 ") "
|
||||||
|
" diff " WHITE("%" PRIu64) " vs. " WHITE("%" PRIu64),
|
||||||
|
Tags::origin(), m_originSubmitted, m_originNotSubmitted, m_blockDiff, result.actualDiff(), result.diff);
|
||||||
|
|
||||||
|
// Ensure that the latest block template is available after block submission
|
||||||
|
getBlockTemplate();
|
||||||
|
}
|
||||||
|
|
||||||
void xmrig::SelfSelectClient::onHttpData(const HttpData &data)
|
void xmrig::SelfSelectClient::onHttpData(const HttpData &data)
|
||||||
{
|
{
|
||||||
if (data.status != HTTP_STATUS_OK) {
|
if (data.status != HTTP_STATUS_OK) {
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2019 jtgrassie <https://github.com/jtgrassie>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2021 Hansie Odendaal <https://github.com/hansieodendaal>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
|
||||||
* Copyright 2019 jtgrassie <https://github.com/jtgrassie>
|
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -31,9 +26,9 @@
|
|||||||
#include "base/kernel/interfaces/IClientListener.h"
|
#include "base/kernel/interfaces/IClientListener.h"
|
||||||
#include "base/net/http/HttpListener.h"
|
#include "base/net/http/HttpListener.h"
|
||||||
#include "base/net/stratum/Job.h"
|
#include "base/net/stratum/Job.h"
|
||||||
#include "base/tools/Object.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +40,7 @@ class SelfSelectClient : public IClient, public IClientListener, public IHttpLis
|
|||||||
public:
|
public:
|
||||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(SelfSelectClient)
|
XMRIG_DISABLE_COPY_MOVE_DEFAULT(SelfSelectClient)
|
||||||
|
|
||||||
SelfSelectClient(int id, const char *agent, IClientListener *listener);
|
SelfSelectClient(int id, const char *agent, IClientListener *listener, bool submitToOrigin);
|
||||||
~SelfSelectClient() override;
|
~SelfSelectClient() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -65,7 +60,6 @@ protected:
|
|||||||
inline int64_t send(const rapidjson::Value &obj, Callback callback) override { return m_client->send(obj, callback); }
|
inline int64_t send(const rapidjson::Value &obj, Callback callback) override { return m_client->send(obj, callback); }
|
||||||
inline int64_t send(const rapidjson::Value &obj) override { return m_client->send(obj); }
|
inline int64_t send(const rapidjson::Value &obj) override { return m_client->send(obj); }
|
||||||
inline int64_t sequence() const override { return m_client->sequence(); }
|
inline int64_t sequence() const override { return m_client->sequence(); }
|
||||||
inline int64_t submit(const JobResult &result) override { return m_client->submit(result); }
|
|
||||||
inline void connect() override { m_client->connect(); }
|
inline void connect() override { m_client->connect(); }
|
||||||
inline void connect(const Pool &pool) override { m_client->connect(pool); }
|
inline void connect(const Pool &pool) override { m_client->connect(pool); }
|
||||||
inline void deleteLater() override { m_client->deleteLater(); }
|
inline void deleteLater() override { m_client->deleteLater(); }
|
||||||
@@ -77,6 +71,7 @@ protected:
|
|||||||
inline void setRetries(int retries) override { m_client->setRetries(retries); m_retries = retries; }
|
inline void setRetries(int retries) override { m_client->setRetries(retries); m_retries = retries; }
|
||||||
inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); m_retryPause = ms; }
|
inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); m_retryPause = ms; }
|
||||||
|
|
||||||
|
int64_t submit(const JobResult &result) override;
|
||||||
void tick(uint64_t now) override;
|
void tick(uint64_t now) override;
|
||||||
|
|
||||||
// IClientListener
|
// IClientListener
|
||||||
@@ -105,19 +100,26 @@ private:
|
|||||||
void retry();
|
void retry();
|
||||||
void setState(State state);
|
void setState(State state);
|
||||||
void submitBlockTemplate(rapidjson::Value &result);
|
void submitBlockTemplate(rapidjson::Value &result);
|
||||||
|
void submitOriginDaemon(const JobResult &result);
|
||||||
|
|
||||||
bool m_active = false;
|
bool m_active = false;
|
||||||
bool m_quiet = false;
|
bool m_quiet = false;
|
||||||
|
const bool m_submitToOrigin;
|
||||||
IClient *m_client;
|
IClient *m_client;
|
||||||
IClientListener *m_listener;
|
IClientListener *m_listener;
|
||||||
int m_retries = 5;
|
int m_retries = 5;
|
||||||
int64_t m_failures = 0;
|
int64_t m_failures = 0;
|
||||||
int64_t m_sequence = 1;
|
int64_t m_sequence = 1;
|
||||||
Job m_job;
|
Job m_job;
|
||||||
State m_state = IdleState;
|
State m_state = IdleState;
|
||||||
|
std::map<int64_t, SubmitResult> m_results;
|
||||||
std::shared_ptr<IHttpListener> m_httpListener;
|
std::shared_ptr<IHttpListener> m_httpListener;
|
||||||
uint64_t m_retryPause = 5000;
|
String m_blocktemplate;
|
||||||
uint64_t m_timestamp = 0;
|
uint64_t m_blockDiff = 0;
|
||||||
|
uint64_t m_originNotSubmitted = 0;
|
||||||
|
uint64_t m_originSubmitted = 0;
|
||||||
|
uint64_t m_retryPause = 5000;
|
||||||
|
uint64_t m_timestamp = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -34,6 +34,10 @@
|
|||||||
#include "base/tools/Cvt.h"
|
#include "base/tools/Cvt.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_DMI
|
||||||
|
# include "hw/dmi/DmiReader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, IClientListener* listener) :
|
xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, IClientListener* listener) :
|
||||||
m_listener(listener),
|
m_listener(listener),
|
||||||
@@ -126,7 +130,8 @@ void xmrig::BenchClient::onBenchDone(uint64_t result, uint64_t diff, uint64_t ts
|
|||||||
const uint64_t ref = referenceHash();
|
const uint64_t ref = referenceHash();
|
||||||
const char *color = ref ? ((result == ref) ? GREEN_BOLD_S : RED_BOLD_S) : BLACK_BOLD_S;
|
const char *color = ref ? ((result == ref) ? GREEN_BOLD_S : RED_BOLD_S) : BLACK_BOLD_S;
|
||||||
|
|
||||||
LOG_NOTICE("%s " WHITE_BOLD("benchmark finished in ") CYAN_BOLD("%.3f seconds") WHITE_BOLD_S " hash sum = " CLEAR "%s%016" PRIX64 CLEAR, tag(), static_cast<double>(ts - m_readyTime) / 1000.0, color, result);
|
const double dt = static_cast<int64_t>(ts - m_readyTime) / 1000.0;
|
||||||
|
LOG_NOTICE("%s " WHITE_BOLD("benchmark finished in ") CYAN_BOLD("%.3f seconds (%.1f h/s)") WHITE_BOLD_S " hash sum = " CLEAR "%s%016" PRIX64 CLEAR, tag(), dt, BenchState::size() / dt, color, result);
|
||||||
|
|
||||||
if (m_token.isEmpty()) {
|
if (m_token.isEmpty()) {
|
||||||
printExit();
|
printExit();
|
||||||
@@ -335,6 +340,15 @@ void xmrig::BenchClient::send(Request request)
|
|||||||
doc.AddMember("steady_ready_ts", m_readyTime, allocator);
|
doc.AddMember("steady_ready_ts", m_readyTime, allocator);
|
||||||
doc.AddMember("cpu", Cpu::toJSON(doc), allocator);
|
doc.AddMember("cpu", Cpu::toJSON(doc), allocator);
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
if (m_benchmark->isDMI()) {
|
||||||
|
DmiReader reader;
|
||||||
|
if (reader.read()) {
|
||||||
|
doc.AddMember("dmi", reader.toJSON(doc), allocator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
FetchRequest req(HTTP_POST, m_ip, BenchConfig::kApiPort, "/1/benchmark", doc, BenchConfig::kApiTLS, true);
|
FetchRequest req(HTTP_POST, m_ip, BenchConfig::kApiPort, "/1/benchmark", doc, BenchConfig::kApiTLS, true);
|
||||||
fetch(tag(), std::move(req), m_httpListener);
|
fetch(tag(), std::move(req), m_httpListener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -52,8 +52,9 @@ const char *BenchConfig::kApiHost = "127.0.0.1";
|
|||||||
} // namespace xmrig
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object) :
|
xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object, bool dmi) :
|
||||||
m_algorithm(Json::getString(object, kAlgo)),
|
m_algorithm(Json::getString(object, kAlgo)),
|
||||||
|
m_dmi(dmi),
|
||||||
m_submit(Json::getBool(object, kSubmit)),
|
m_submit(Json::getBool(object, kSubmit)),
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_seed(Json::getString(object, kSeed)),
|
m_seed(Json::getString(object, kSeed)),
|
||||||
@@ -72,7 +73,7 @@ xmrig::BenchConfig::BenchConfig(uint32_t size, const String &id, const rapidjson
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object)
|
xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object, bool dmi)
|
||||||
{
|
{
|
||||||
if (!object.IsObject() || object.ObjectEmpty()) {
|
if (!object.IsObject() || object.ObjectEmpty()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -85,7 +86,7 @@ xmrig::BenchConfig *xmrig::BenchConfig::create(const rapidjson::Value &object)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BenchConfig(size, id, object);
|
return new BenchConfig(size, id, object, dmi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -49,10 +49,11 @@ public:
|
|||||||
static constexpr const uint16_t kApiPort = 18805;
|
static constexpr const uint16_t kApiPort = 18805;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object);
|
BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object, bool dmi);
|
||||||
|
|
||||||
static BenchConfig *create(const rapidjson::Value &object);
|
static BenchConfig *create(const rapidjson::Value &object, bool dmi);
|
||||||
|
|
||||||
|
inline bool isDMI() const { return m_dmi; }
|
||||||
inline bool isSubmit() const { return m_submit; }
|
inline bool isSubmit() const { return m_submit; }
|
||||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||||
inline const String &id() const { return m_id; }
|
inline const String &id() const { return m_id; }
|
||||||
@@ -67,6 +68,7 @@ private:
|
|||||||
static uint32_t getSize(const char *benchmark);
|
static uint32_t getSize(const char *benchmark);
|
||||||
|
|
||||||
Algorithm m_algorithm;
|
Algorithm m_algorithm;
|
||||||
|
bool m_dmi;
|
||||||
bool m_submit;
|
bool m_submit;
|
||||||
String m_id;
|
String m_id;
|
||||||
String m_seed;
|
String m_seed;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2013-2020 Frank Denis <j at pureftpd dot org>
|
* Copyright (c) 2013-2020 Frank Denis <j at pureftpd dot org>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -34,11 +34,6 @@
|
|||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
#ifndef XMRIG_SODIUM
|
|
||||||
static std::random_device randomDevice;
|
|
||||||
static std::mt19937 randomEngine(randomDevice());
|
|
||||||
|
|
||||||
|
|
||||||
static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigned char *const bin, const size_t bin_len)
|
static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigned char *const bin, const size_t bin_len)
|
||||||
{
|
{
|
||||||
size_t i = 0U;
|
size_t i = 0U;
|
||||||
@@ -46,7 +41,7 @@ static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigne
|
|||||||
int b;
|
int b;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) {
|
if (bin_len >= SIZE_MAX / 2 || hex_maxlen < bin_len * 2U) {
|
||||||
return nullptr; /* LCOV_EXCL_LINE */
|
return nullptr; /* LCOV_EXCL_LINE */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,12 +55,20 @@ static char *cvt_bin2hex(char *const hex, const size_t hex_maxlen, const unsigne
|
|||||||
hex[i * 2U + 1U] = (char) x;
|
hex[i * 2U + 1U] = (char) x;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
hex[i * 2U] = 0U;
|
|
||||||
|
if (i * 2U < hex_maxlen) {
|
||||||
|
hex[i * 2U] = 0U;
|
||||||
|
}
|
||||||
|
|
||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef XMRIG_SODIUM
|
||||||
|
static std::random_device randomDevice;
|
||||||
|
static std::mt19937 randomEngine(randomDevice());
|
||||||
|
|
||||||
|
|
||||||
static int cvt_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const char *const hex, const size_t hex_len, const char *const ignore, size_t *const bin_len, const char **const hex_end)
|
static int cvt_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const char *const hex, const size_t hex_len, const char *const ignore, size_t *const bin_len, const char **const hex_end)
|
||||||
{
|
{
|
||||||
size_t bin_pos = 0U;
|
size_t bin_pos = 0U;
|
||||||
@@ -137,7 +140,6 @@ static int cvt_hex2bin(unsigned char *const bin, const size_t bin_maxlen, const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sodium_bin2hex cvt_bin2hex
|
|
||||||
#define sodium_hex2bin cvt_hex2bin
|
#define sodium_hex2bin cvt_hex2bin
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -215,7 +217,7 @@ xmrig::Buffer xmrig::Cvt::fromHex(const char *in, size_t size)
|
|||||||
|
|
||||||
bool xmrig::Cvt::toHex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len)
|
bool xmrig::Cvt::toHex(char *hex, size_t hex_maxlen, const uint8_t *bin, size_t bin_len)
|
||||||
{
|
{
|
||||||
return sodium_bin2hex(hex, hex_maxlen, bin, bin_len) != nullptr;
|
return cvt_bin2hex(hex, hex_maxlen, bin, bin_len) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -273,3 +275,17 @@ xmrig::String xmrig::Cvt::toHex(const uint8_t *in, size_t size)
|
|||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Cvt::randomBytes(void *buf, size_t size)
|
||||||
|
{
|
||||||
|
# ifndef XMRIG_SODIUM
|
||||||
|
std::uniform_int_distribution<> dis(0, 255);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
static_cast<uint8_t *>(buf)[i] = static_cast<char>(dis(randomEngine));
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
randombytes_buf(buf, size);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
static rapidjson::Value toHex(const std::string &data, rapidjson::Document &doc);
|
static rapidjson::Value toHex(const std::string &data, rapidjson::Document &doc);
|
||||||
static rapidjson::Value toHex(const uint8_t *in, size_t size, rapidjson::Document &doc);
|
static rapidjson::Value toHex(const uint8_t *in, size_t size, rapidjson::Document &doc);
|
||||||
static String toHex(const uint8_t *in, size_t size);
|
static String toHex(const uint8_t *in, size_t size);
|
||||||
|
static void randomBytes(void *buf, size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,9 @@
|
|||||||
"asm": true,
|
"asm": true,
|
||||||
"argon2-impl": null,
|
"argon2-impl": null,
|
||||||
"astrobwt-max-size": 550,
|
"astrobwt-max-size": 550,
|
||||||
|
"astrobwt-avx2": false,
|
||||||
"cn/0": false,
|
"cn/0": false,
|
||||||
"cn-lite/0": false,
|
"cn-lite/0": false
|
||||||
"kawpow": false
|
|
||||||
},
|
},
|
||||||
"opencl": {
|
"opencl": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
@@ -75,11 +75,13 @@
|
|||||||
"tls-fingerprint": null,
|
"tls-fingerprint": null,
|
||||||
"daemon": false,
|
"daemon": false,
|
||||||
"socks5": null,
|
"socks5": null,
|
||||||
"self-select": null
|
"self-select": null,
|
||||||
|
"submit-to-origin": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"print-time": 60,
|
"print-time": 60,
|
||||||
"health-print-time": 60,
|
"health-print-time": 60,
|
||||||
|
"dmi": true,
|
||||||
"retries": 5,
|
"retries": 5,
|
||||||
"retry-pause": 5,
|
"retry-pause": 5,
|
||||||
"syslog": false,
|
"syslog": false,
|
||||||
@@ -95,5 +97,6 @@
|
|||||||
"user-agent": null,
|
"user-agent": null,
|
||||||
"verbose": 0,
|
"verbose": 0,
|
||||||
"watch": true,
|
"watch": true,
|
||||||
"pause-on-battery": false
|
"pause-on-battery": false,
|
||||||
|
"pause-on-active": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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
|
||||||
@@ -31,6 +25,12 @@
|
|||||||
#include "net/Network.h"
|
#include "net/Network.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_API
|
||||||
|
# include "base/api/Api.h"
|
||||||
|
# include "hw/api/HwApi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
@@ -42,8 +42,6 @@ xmrig::Controller::Controller(Process *process) :
|
|||||||
|
|
||||||
xmrig::Controller::~Controller()
|
xmrig::Controller::~Controller()
|
||||||
{
|
{
|
||||||
delete m_network;
|
|
||||||
|
|
||||||
VirtualMemory::destroy();
|
VirtualMemory::destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,9 +50,14 @@ int xmrig::Controller::init()
|
|||||||
{
|
{
|
||||||
Base::init();
|
Base::init();
|
||||||
|
|
||||||
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages());
|
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().hugePageSize());
|
||||||
|
|
||||||
m_network = new Network(this);
|
m_network = std::make_shared<Network>(this);
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_API
|
||||||
|
m_hwApi = std::make_shared<HwApi>();
|
||||||
|
api()->addListener(m_hwApi.get());
|
||||||
|
# endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -64,7 +67,7 @@ void xmrig::Controller::start()
|
|||||||
{
|
{
|
||||||
Base::start();
|
Base::start();
|
||||||
|
|
||||||
m_miner = new Miner(this);
|
m_miner = std::make_shared<Miner>(this);
|
||||||
|
|
||||||
network()->connect();
|
network()->connect();
|
||||||
}
|
}
|
||||||
@@ -74,29 +77,26 @@ void xmrig::Controller::stop()
|
|||||||
{
|
{
|
||||||
Base::stop();
|
Base::stop();
|
||||||
|
|
||||||
delete m_network;
|
m_network.reset();
|
||||||
m_network = nullptr;
|
|
||||||
|
|
||||||
m_miner->stop();
|
m_miner->stop();
|
||||||
|
m_miner.reset();
|
||||||
delete m_miner;
|
|
||||||
m_miner = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::Miner *xmrig::Controller::miner() const
|
xmrig::Miner *xmrig::Controller::miner() const
|
||||||
{
|
{
|
||||||
assert(m_miner != nullptr);
|
assert(m_miner);
|
||||||
|
|
||||||
return m_miner;
|
return m_miner.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::Network *xmrig::Controller::network() const
|
xmrig::Network *xmrig::Controller::network() const
|
||||||
{
|
{
|
||||||
assert(m_network != nullptr);
|
assert(m_network);
|
||||||
|
|
||||||
return m_network;
|
return m_network.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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
|
||||||
@@ -27,12 +21,15 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "base/kernel/Base.h"
|
#include "base/kernel/Base.h"
|
||||||
#include "base/tools/Object.h"
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
class HwApi;
|
||||||
class Job;
|
class Job;
|
||||||
class Miner;
|
class Miner;
|
||||||
class Network;
|
class Network;
|
||||||
@@ -55,8 +52,12 @@ public:
|
|||||||
void execCommand(char command);
|
void execCommand(char command);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Miner *m_miner = nullptr;
|
std::shared_ptr<Miner> m_miner;
|
||||||
Network *m_network = nullptr;
|
std::shared_ptr<Network> m_network;
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_API
|
||||||
|
std::shared_ptr<HwApi> m_hwApi;
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,8 @@ public:
|
|||||||
return strcmp(a->m_threadId, b->m_threadId) < 0;
|
return strcmp(a->m_threadId, b->m_threadId) < 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
std::map<std::string, std::pair<uint32_t, double>> averageTime;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < n;)
|
for (uint32_t i = 0; i < n;)
|
||||||
{
|
{
|
||||||
uint32_t n1 = i;
|
uint32_t n1 = i;
|
||||||
@@ -267,19 +269,27 @@ public:
|
|||||||
|
|
||||||
for (uint32_t j = i; j < n1; ++j) {
|
for (uint32_t j = i; j < n1; ++j) {
|
||||||
ProfileScopeData* p = data[j];
|
ProfileScopeData* p = data[j];
|
||||||
|
const double t = p->m_totalCycles / p->m_totalSamples * 1e9 / ProfileScopeData::s_tscSpeed;
|
||||||
LOG_INFO("%s Thread %6s | %-30s | %7.3f%% | %9.0f ns",
|
LOG_INFO("%s Thread %6s | %-30s | %7.3f%% | %9.0f ns",
|
||||||
Tags::profiler(),
|
Tags::profiler(),
|
||||||
p->m_threadId,
|
p->m_threadId,
|
||||||
p->m_name,
|
p->m_name,
|
||||||
p->m_totalCycles * 100.0 / data[i]->m_totalCycles,
|
p->m_totalCycles * 100.0 / data[i]->m_totalCycles,
|
||||||
p->m_totalCycles / p->m_totalSamples * 1e9 / ProfileScopeData::s_tscSpeed
|
t
|
||||||
);
|
);
|
||||||
|
auto& value = averageTime[p->m_name];
|
||||||
|
++value.first;
|
||||||
|
value.second += t;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("%s --------------|--------------------------------|----------|-------------", Tags::profiler());
|
LOG_INFO("%s --------------|--------------------------------|----------|-------------", Tags::profiler());
|
||||||
|
|
||||||
i = n1;
|
i = n1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& data : averageTime) {
|
||||||
|
LOG_INFO("%s %-30s %9.1f ns", Tags::profiler(), data.first.c_str(), data.second.second / data.second.first);
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,6 +352,7 @@ public:
|
|||||||
Algorithms algorithms;
|
Algorithms algorithms;
|
||||||
bool active = false;
|
bool active = false;
|
||||||
bool battery_power = false;
|
bool battery_power = false;
|
||||||
|
bool user_active = false;
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
bool reset = true;
|
bool reset = true;
|
||||||
Controller *controller;
|
Controller *controller;
|
||||||
@@ -590,7 +601,8 @@ void xmrig::Miner::onConfigChanged(Config *config, Config *previousConfig)
|
|||||||
void xmrig::Miner::onTimer(const Timer *)
|
void xmrig::Miner::onTimer(const Timer *)
|
||||||
{
|
{
|
||||||
double maxHashrate = 0.0;
|
double maxHashrate = 0.0;
|
||||||
const auto healthPrintTime = d_ptr->controller->config()->healthPrintTime();
|
const auto config = d_ptr->controller->config();
|
||||||
|
const auto healthPrintTime = config->healthPrintTime();
|
||||||
|
|
||||||
bool stopMiner = false;
|
bool stopMiner = false;
|
||||||
|
|
||||||
@@ -610,25 +622,29 @@ void xmrig::Miner::onTimer(const Timer *)
|
|||||||
|
|
||||||
d_ptr->maxHashrate[d_ptr->algorithm] = std::max(d_ptr->maxHashrate[d_ptr->algorithm], maxHashrate);
|
d_ptr->maxHashrate[d_ptr->algorithm] = std::max(d_ptr->maxHashrate[d_ptr->algorithm], maxHashrate);
|
||||||
|
|
||||||
const auto printTime = d_ptr->controller->config()->printTime();
|
const auto printTime = config->printTime();
|
||||||
if (printTime && d_ptr->ticks && (d_ptr->ticks % (printTime * 2)) == 0) {
|
if (printTime && d_ptr->ticks && (d_ptr->ticks % (printTime * 2)) == 0) {
|
||||||
d_ptr->printHashrate(false);
|
d_ptr->printHashrate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
d_ptr->ticks++;
|
d_ptr->ticks++;
|
||||||
|
|
||||||
if (d_ptr->controller->config()->isPauseOnBattery()) {
|
auto autoPause = [this](bool &state, bool pause, const char *pauseMessage, const char *activeMessage)
|
||||||
const bool battery_power = Platform::isOnBatteryPower();
|
{
|
||||||
if (battery_power && d_ptr->enabled) {
|
if ((pause && !state) || (!pause && state)) {
|
||||||
LOG_INFO("%s " YELLOW_BOLD("on battery power"), Tags::miner());
|
LOG_INFO("%s %s", Tags::miner(), pause ? pauseMessage : activeMessage);
|
||||||
d_ptr->battery_power = true;
|
|
||||||
setEnabled(false);
|
state = pause;
|
||||||
}
|
setEnabled(!pause);
|
||||||
else if (!battery_power && !d_ptr->enabled && d_ptr->battery_power) {
|
|
||||||
LOG_INFO("%s " GREEN_BOLD("on AC power"), Tags::miner());
|
|
||||||
d_ptr->battery_power = false;
|
|
||||||
setEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (config->isPauseOnBattery()) {
|
||||||
|
autoPause(d_ptr->battery_power, Platform::isOnBatteryPower(), YELLOW_BOLD("on battery power"), GREEN_BOLD("on AC power"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->isPauseOnActive()) {
|
||||||
|
autoPause(d_ptr->user_active, Platform::isUserActive(config->idleTime()), YELLOW_BOLD("user active"), GREEN_BOLD("user inactive"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stopMiner) {
|
if (stopMiner) {
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -22,10 +16,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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cinttypes>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <uv.h>
|
#include <uv.h>
|
||||||
#include <cinttypes>
|
|
||||||
|
|
||||||
|
|
||||||
#include "core/config/Config.h"
|
#include "core/config/Config.h"
|
||||||
@@ -54,24 +49,36 @@
|
|||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
constexpr static uint32_t kIdleTime = 60U;
|
||||||
|
|
||||||
|
|
||||||
|
const char *Config::kPauseOnBattery = "pause-on-battery";
|
||||||
|
const char *Config::kPauseOnActive = "pause-on-active";
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_FEATURE_OPENCL
|
#ifdef XMRIG_FEATURE_OPENCL
|
||||||
static const char *kOcl = "opencl";
|
const char *Config::kOcl = "opencl";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XMRIG_FEATURE_CUDA
|
#ifdef XMRIG_FEATURE_CUDA
|
||||||
static const char *kCuda = "cuda";
|
const char *Config::kCuda = "cuda";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
#if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||||
static const char *kHealthPrintTime = "health-print-time";
|
const char *Config::kHealthPrintTime = "health-print-time";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_DMI
|
||||||
|
const char *Config::kDMI = "dmi";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class ConfigPrivate
|
class ConfigPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
bool pauseOnBattery = false;
|
||||||
CpuConfig cpu;
|
CpuConfig cpu;
|
||||||
|
uint32_t idleTime = 0;
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_RANDOMX
|
# ifdef XMRIG_ALGO_RANDOMX
|
||||||
RxConfig rx;
|
RxConfig rx;
|
||||||
@@ -86,8 +93,22 @@ public:
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||||
uint32_t healthPrintTime = 60;
|
uint32_t healthPrintTime = 60U;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
bool dmi = true;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
void setIdleTime(const rapidjson::Value &value)
|
||||||
|
{
|
||||||
|
if (value.IsBool()) {
|
||||||
|
idleTime = value.GetBool() ? kIdleTime : 0U;
|
||||||
|
}
|
||||||
|
else if (value.IsUint()) {
|
||||||
|
idleTime = value.GetUint();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -105,12 +126,24 @@ xmrig::Config::~Config()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::Config::isPauseOnBattery() const
|
||||||
|
{
|
||||||
|
return d_ptr->pauseOnBattery;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const xmrig::CpuConfig &xmrig::Config::cpu() const
|
const xmrig::CpuConfig &xmrig::Config::cpu() const
|
||||||
{
|
{
|
||||||
return d_ptr->cpu;
|
return d_ptr->cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t xmrig::Config::idleTime() const
|
||||||
|
{
|
||||||
|
return d_ptr->idleTime * 1000U;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_FEATURE_OPENCL
|
#ifdef XMRIG_FEATURE_OPENCL
|
||||||
const xmrig::OclConfig &xmrig::Config::cl() const
|
const xmrig::OclConfig &xmrig::Config::cl() const
|
||||||
{
|
{
|
||||||
@@ -143,6 +176,14 @@ uint32_t xmrig::Config::healthPrintTime() const
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_DMI
|
||||||
|
bool xmrig::Config::isDMI() const
|
||||||
|
{
|
||||||
|
return d_ptr->dmi;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Config::isShouldSave() const
|
bool xmrig::Config::isShouldSave() const
|
||||||
{
|
{
|
||||||
if (!isAutoSave()) {
|
if (!isAutoSave()) {
|
||||||
@@ -171,6 +212,9 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d_ptr->pauseOnBattery = reader.getBool(kPauseOnBattery, d_ptr->pauseOnBattery);
|
||||||
|
d_ptr->setIdleTime(reader.getValue(kPauseOnActive));
|
||||||
|
|
||||||
d_ptr->cpu.read(reader.getValue(CpuConfig::kField));
|
d_ptr->cpu.read(reader.getValue(CpuConfig::kField));
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_RANDOMX
|
# ifdef XMRIG_ALGO_RANDOMX
|
||||||
@@ -191,6 +235,10 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName)
|
|||||||
d_ptr->healthPrintTime = reader.getUint(kHealthPrintTime, d_ptr->healthPrintTime);
|
d_ptr->healthPrintTime = reader.getUint(kHealthPrintTime, d_ptr->healthPrintTime);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
d_ptr->dmi = reader.getBool(kDMI, d_ptr->dmi);
|
||||||
|
# endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +284,11 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
|||||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||||
doc.AddMember(StringRef(kHealthPrintTime), healthPrintTime(), allocator);
|
doc.AddMember(StringRef(kHealthPrintTime), healthPrintTime(), allocator);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
doc.AddMember(StringRef(kDMI), isDMI(), allocator);
|
||||||
|
# endif
|
||||||
|
|
||||||
doc.AddMember(StringRef(kSyslog), isSyslog(), allocator);
|
doc.AddMember(StringRef(kSyslog), isSyslog(), allocator);
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_TLS
|
# ifdef XMRIG_FEATURE_TLS
|
||||||
@@ -246,4 +299,5 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
|||||||
doc.AddMember(StringRef(kVerbose), Log::verbose(), allocator);
|
doc.AddMember(StringRef(kVerbose), Log::verbose(), allocator);
|
||||||
doc.AddMember(StringRef(kWatch), m_watch, allocator);
|
doc.AddMember(StringRef(kWatch), m_watch, allocator);
|
||||||
doc.AddMember(StringRef(kPauseOnBattery), isPauseOnBattery(), allocator);
|
doc.AddMember(StringRef(kPauseOnBattery), isPauseOnBattery(), allocator);
|
||||||
|
doc.AddMember(StringRef(kPauseOnActive), (d_ptr->idleTime == 0U || d_ptr->idleTime == kIdleTime) ? Value(isPauseOnActive()) : Value(d_ptr->idleTime), allocator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -50,10 +44,33 @@ class Config : public BaseConfig
|
|||||||
public:
|
public:
|
||||||
XMRIG_DISABLE_COPY_MOVE(Config);
|
XMRIG_DISABLE_COPY_MOVE(Config);
|
||||||
|
|
||||||
|
static const char *kPauseOnBattery;
|
||||||
|
static const char *kPauseOnActive;
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_OPENCL
|
||||||
|
static const char *kOcl;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_CUDA
|
||||||
|
static const char *kCuda;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||||
|
static const char *kHealthPrintTime;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
static const char *kDMI;
|
||||||
|
# endif
|
||||||
|
|
||||||
Config();
|
Config();
|
||||||
~Config() override;
|
~Config() override;
|
||||||
|
|
||||||
|
inline bool isPauseOnActive() const { return idleTime() > 0; }
|
||||||
|
|
||||||
|
bool isPauseOnBattery() const;
|
||||||
const CpuConfig &cpu() const;
|
const CpuConfig &cpu() const;
|
||||||
|
uint32_t idleTime() const;
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_OPENCL
|
# ifdef XMRIG_FEATURE_OPENCL
|
||||||
const OclConfig &cl() const;
|
const OclConfig &cl() const;
|
||||||
@@ -70,7 +87,13 @@ public:
|
|||||||
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||||
uint32_t healthPrintTime() const;
|
uint32_t healthPrintTime() const;
|
||||||
# else
|
# else
|
||||||
uint32_t healthPrintTime() const { return 0; }
|
uint32_t healthPrintTime() const { return 0; }
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
bool isDMI() const;
|
||||||
|
# else
|
||||||
|
static constexpr inline bool isDMI() { return false; }
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
bool isShouldSave() const;
|
bool isShouldSave() const;
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -23,11 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "core/config/ConfigTransform.h"
|
||||||
#include "base/kernel/interfaces/IConfig.h"
|
#include "base/kernel/interfaces/IConfig.h"
|
||||||
#include "backend/cpu/CpuConfig.h"
|
|
||||||
#include "base/net/stratum/Pool.h"
|
#include "base/net/stratum/Pool.h"
|
||||||
#include "base/net/stratum/Pools.h"
|
#include "base/net/stratum/Pools.h"
|
||||||
#include "core/config/ConfigTransform.h"
|
#include "core/config/Config.h"
|
||||||
#include "crypto/cn/CnHash.h"
|
#include "crypto/cn/CnHash.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -51,14 +45,6 @@ static const char *kEnabled = "enabled";
|
|||||||
static const char *kIntensity = "intensity";
|
static const char *kIntensity = "intensity";
|
||||||
static const char *kThreads = "threads";
|
static const char *kThreads = "threads";
|
||||||
|
|
||||||
#ifdef XMRIG_FEATURE_OPENCL
|
|
||||||
static const char *kOcl = "opencl";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XMRIG_FEATURE_CUDA
|
|
||||||
static const char *kCuda = "cuda";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint64_t intensity(uint64_t av)
|
static inline uint64_t intensity(uint64_t av)
|
||||||
{
|
{
|
||||||
@@ -122,7 +108,7 @@ void xmrig::ConfigTransform::finalize(rapidjson::Document &doc)
|
|||||||
|
|
||||||
# ifdef XMRIG_FEATURE_OPENCL
|
# ifdef XMRIG_FEATURE_OPENCL
|
||||||
if (m_opencl) {
|
if (m_opencl) {
|
||||||
set(doc, kOcl, kEnabled, true);
|
set(doc, Config::kOcl, kEnabled, true);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
@@ -133,9 +119,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
|
|||||||
BaseTransform::transform(doc, key, arg);
|
BaseTransform::transform(doc, key, arg);
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case IConfig::AVKey: /* --av */
|
case IConfig::AVKey: /* --av */
|
||||||
case IConfig::CPUPriorityKey: /* --cpu-priority */
|
case IConfig::CPUPriorityKey: /* --cpu-priority */
|
||||||
case IConfig::ThreadsKey: /* --threads */
|
case IConfig::ThreadsKey: /* --threads */
|
||||||
|
case IConfig::HugePageSizeKey: /* --hugepage-size */
|
||||||
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||||
|
|
||||||
case IConfig::HugePagesKey: /* --no-huge-pages */
|
case IConfig::HugePagesKey: /* --no-huge-pages */
|
||||||
@@ -157,8 +144,16 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
|
|||||||
case IConfig::YieldKey: /* --cpu-no-yield */
|
case IConfig::YieldKey: /* --cpu-no-yield */
|
||||||
return set(doc, CpuConfig::kField, CpuConfig::kYield, false);
|
return set(doc, CpuConfig::kField, CpuConfig::kYield, false);
|
||||||
|
|
||||||
|
case IConfig::PauseOnBatteryKey: /* --pause-on-battery */
|
||||||
|
return set(doc, Config::kPauseOnBattery, true);
|
||||||
|
|
||||||
|
case IConfig::PauseOnActiveKey: /* --pause-on-active */
|
||||||
|
return set(doc, Config::kPauseOnActive, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||||
|
|
||||||
|
# ifdef XMRIG_ALGO_ARGON2
|
||||||
case IConfig::Argon2ImplKey: /* --argon2-impl */
|
case IConfig::Argon2ImplKey: /* --argon2-impl */
|
||||||
return set(doc, CpuConfig::kField, CpuConfig::kArgon2Impl, arg);
|
return set(doc, CpuConfig::kField, CpuConfig::kArgon2Impl, arg);
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_ASM
|
# ifdef XMRIG_FEATURE_ASM
|
||||||
case IConfig::AssemblyKey: /* --asm */
|
case IConfig::AssemblyKey: /* --asm */
|
||||||
@@ -208,47 +203,54 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IConfig::OclCacheKey: /* --opencl-no-cache */
|
case IConfig::OclCacheKey: /* --opencl-no-cache */
|
||||||
return set(doc, kOcl, "cache", false);
|
return set(doc, Config::kOcl, "cache", false);
|
||||||
|
|
||||||
case IConfig::OclLoaderKey: /* --opencl-loader */
|
case IConfig::OclLoaderKey: /* --opencl-loader */
|
||||||
return set(doc, kOcl, "loader", arg);
|
return set(doc, Config::kOcl, "loader", arg);
|
||||||
|
|
||||||
case IConfig::OclDevicesKey: /* --opencl-devices */
|
case IConfig::OclDevicesKey: /* --opencl-devices */
|
||||||
m_opencl = true;
|
m_opencl = true;
|
||||||
return set(doc, kOcl, "devices-hint", arg);
|
return set(doc, Config::kOcl, "devices-hint", arg);
|
||||||
|
|
||||||
case IConfig::OclPlatformKey: /* --opencl-platform */
|
case IConfig::OclPlatformKey: /* --opencl-platform */
|
||||||
if (strlen(arg) < 3) {
|
if (strlen(arg) < 3) {
|
||||||
return set(doc, kOcl, "platform", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
return set(doc, Config::kOcl, "platform", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return set(doc, kOcl, "platform", arg);
|
return set(doc, Config::kOcl, "platform", arg);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_CUDA
|
# ifdef XMRIG_FEATURE_CUDA
|
||||||
case IConfig::CudaKey: /* --cuda */
|
case IConfig::CudaKey: /* --cuda */
|
||||||
return set(doc, kCuda, kEnabled, true);
|
return set(doc, Config::kCuda, kEnabled, true);
|
||||||
|
|
||||||
case IConfig::CudaLoaderKey: /* --cuda-loader */
|
case IConfig::CudaLoaderKey: /* --cuda-loader */
|
||||||
return set(doc, kCuda, "loader", arg);
|
return set(doc, Config::kCuda, "loader", arg);
|
||||||
|
|
||||||
case IConfig::CudaDevicesKey: /* --cuda-devices */
|
case IConfig::CudaDevicesKey: /* --cuda-devices */
|
||||||
set(doc, kCuda, kEnabled, true);
|
set(doc, Config::kCuda, kEnabled, true);
|
||||||
return set(doc, kCuda, "devices-hint", arg);
|
return set(doc, Config::kCuda, "devices-hint", arg);
|
||||||
|
|
||||||
case IConfig::CudaBFactorKey: /* --cuda-bfactor-hint */
|
case IConfig::CudaBFactorKey: /* --cuda-bfactor-hint */
|
||||||
return set(doc, kCuda, "bfactor-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
return set(doc, Config::kCuda, "bfactor-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||||
|
|
||||||
case IConfig::CudaBSleepKey: /* --cuda-bsleep-hint */
|
case IConfig::CudaBSleepKey: /* --cuda-bsleep-hint */
|
||||||
return set(doc, kCuda, "bsleep-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
return set(doc, Config::kCuda, "bsleep-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_NVML
|
# ifdef XMRIG_FEATURE_NVML
|
||||||
case IConfig::NvmlKey: /* --no-nvml */
|
case IConfig::NvmlKey: /* --no-nvml */
|
||||||
return set(doc, kCuda, "nvml", false);
|
return set(doc, Config::kCuda, "nvml", false);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||||
case IConfig::HealthPrintTimeKey: /* --health-print-time */
|
case IConfig::HealthPrintTimeKey: /* --health-print-time */
|
||||||
return set(doc, "health-print-time", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
return set(doc, Config::kHealthPrintTime, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
case IConfig::DmiKey: /* --no-dmi */
|
||||||
|
return set(doc, Config::kDMI, false);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||||
@@ -305,6 +307,9 @@ void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key,
|
|||||||
case IConfig::CPUPriorityKey: /* --cpu-priority */
|
case IConfig::CPUPriorityKey: /* --cpu-priority */
|
||||||
return set(doc, CpuConfig::kField, CpuConfig::kPriority, arg);
|
return set(doc, CpuConfig::kField, CpuConfig::kPriority, arg);
|
||||||
|
|
||||||
|
case IConfig::HugePageSizeKey: /* --hugepage-size */
|
||||||
|
return set(doc, CpuConfig::kField, CpuConfig::kHugePages, arg);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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
|
||||||
@@ -22,6 +16,7 @@
|
|||||||
* 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_CONFIG_DEFAULT_H
|
#ifndef XMRIG_CONFIG_DEFAULT_H
|
||||||
#define XMRIG_CONFIG_DEFAULT_H
|
#define XMRIG_CONFIG_DEFAULT_H
|
||||||
|
|
||||||
@@ -29,6 +24,7 @@
|
|||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
// This feature require CMake option: -DWITH_EMBEDDED_CONFIG=ON
|
||||||
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
|
||||||
const static char *default_config =
|
const static char *default_config =
|
||||||
R"===(
|
R"===(
|
||||||
@@ -45,9 +41,9 @@ R"===(
|
|||||||
"restricted": true
|
"restricted": true
|
||||||
},
|
},
|
||||||
"autosave": true,
|
"autosave": true,
|
||||||
"version": 1,
|
|
||||||
"background": false,
|
"background": false,
|
||||||
"colors": true,
|
"colors": true,
|
||||||
|
"title": true,
|
||||||
"randomx": {
|
"randomx": {
|
||||||
"init": -1,
|
"init": -1,
|
||||||
"init-avx2": -1,
|
"init-avx2": -1,
|
||||||
@@ -71,15 +67,16 @@ R"===(
|
|||||||
"asm": true,
|
"asm": true,
|
||||||
"argon2-impl": null,
|
"argon2-impl": null,
|
||||||
"astrobwt-max-size": 550,
|
"astrobwt-max-size": 550,
|
||||||
|
"astrobwt-avx2": false,
|
||||||
"cn/0": false,
|
"cn/0": false,
|
||||||
"cn-lite/0": false,
|
"cn-lite/0": false
|
||||||
"kawpow": false
|
|
||||||
},
|
},
|
||||||
"opencl": {
|
"opencl": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"cache": true,
|
"cache": true,
|
||||||
"loader": null,
|
"loader": null,
|
||||||
"platform": "AMD",
|
"platform": "AMD",
|
||||||
|
"adl": true,
|
||||||
"cn/0": false,
|
"cn/0": false,
|
||||||
"cn-lite/0": false
|
"cn-lite/0": false
|
||||||
},
|
},
|
||||||
@@ -90,7 +87,7 @@ R"===(
|
|||||||
"cn/0": false,
|
"cn/0": false,
|
||||||
"cn-lite/0": false
|
"cn-lite/0": false
|
||||||
},
|
},
|
||||||
"donate-level": 5,
|
"donate-level": 1,
|
||||||
"donate-over-proxy": 1,
|
"donate-over-proxy": 1,
|
||||||
"log-file": null,
|
"log-file": null,
|
||||||
"pools": [
|
"pools": [
|
||||||
@@ -107,17 +104,31 @@ R"===(
|
|||||||
"tls": false,
|
"tls": false,
|
||||||
"tls-fingerprint": null,
|
"tls-fingerprint": null,
|
||||||
"daemon": false,
|
"daemon": false,
|
||||||
"self-select": null
|
"socks5": null,
|
||||||
|
"self-select": null,
|
||||||
|
"submit-to-origin": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"print-time": 60,
|
"print-time": 60,
|
||||||
"health-print-time": 60,
|
"health-print-time": 60,
|
||||||
|
"dmi": true,
|
||||||
"retries": 5,
|
"retries": 5,
|
||||||
"retry-pause": 5,
|
"retry-pause": 5,
|
||||||
"syslog": false,
|
"syslog": false,
|
||||||
|
"tls": {
|
||||||
|
"enabled": false,
|
||||||
|
"protocols": null,
|
||||||
|
"cert": null,
|
||||||
|
"cert_key": null,
|
||||||
|
"ciphers": null,
|
||||||
|
"ciphersuites": null,
|
||||||
|
"dhparam": null
|
||||||
|
},
|
||||||
"user-agent": null,
|
"user-agent": null,
|
||||||
|
"verbose": 0,
|
||||||
"watch": true,
|
"watch": true,
|
||||||
"pause-on-battery": false
|
"pause-on-battery": false,
|
||||||
|
"pause-on-active": false
|
||||||
}
|
}
|
||||||
)===";
|
)===";
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -57,6 +51,7 @@ static const option options[] = {
|
|||||||
{ "daemon", 0, nullptr, IConfig::DaemonKey },
|
{ "daemon", 0, nullptr, IConfig::DaemonKey },
|
||||||
{ "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey },
|
{ "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey },
|
||||||
{ "self-select", 1, nullptr, IConfig::SelfSelectKey },
|
{ "self-select", 1, nullptr, IConfig::SelfSelectKey },
|
||||||
|
{ "submit-to-origin", 0, nullptr, IConfig::SubmitToOriginKey },
|
||||||
# endif
|
# endif
|
||||||
{ "av", 1, nullptr, IConfig::AVKey },
|
{ "av", 1, nullptr, IConfig::AVKey },
|
||||||
{ "background", 0, nullptr, IConfig::BackgroundKey },
|
{ "background", 0, nullptr, IConfig::BackgroundKey },
|
||||||
@@ -71,6 +66,8 @@ static const option options[] = {
|
|||||||
{ "nicehash", 0, nullptr, IConfig::NicehashKey },
|
{ "nicehash", 0, nullptr, IConfig::NicehashKey },
|
||||||
{ "no-color", 0, nullptr, IConfig::ColorKey },
|
{ "no-color", 0, nullptr, IConfig::ColorKey },
|
||||||
{ "no-huge-pages", 0, nullptr, IConfig::HugePagesKey },
|
{ "no-huge-pages", 0, nullptr, IConfig::HugePagesKey },
|
||||||
|
{ "no-hugepages", 0, nullptr, IConfig::HugePagesKey },
|
||||||
|
{ "hugepage-size", 1, nullptr, IConfig::HugePageSizeKey },
|
||||||
{ "pass", 1, nullptr, IConfig::PasswordKey },
|
{ "pass", 1, nullptr, IConfig::PasswordKey },
|
||||||
{ "print-time", 1, nullptr, IConfig::PrintTimeKey },
|
{ "print-time", 1, nullptr, IConfig::PrintTimeKey },
|
||||||
{ "retries", 1, nullptr, IConfig::RetriesKey },
|
{ "retries", 1, nullptr, IConfig::RetriesKey },
|
||||||
@@ -96,6 +93,7 @@ static const option options[] = {
|
|||||||
{ "title", 1, nullptr, IConfig::TitleKey },
|
{ "title", 1, nullptr, IConfig::TitleKey },
|
||||||
{ "no-title", 0, nullptr, IConfig::NoTitleKey },
|
{ "no-title", 0, nullptr, IConfig::NoTitleKey },
|
||||||
{ "pause-on-battery", 0, nullptr, IConfig::PauseOnBatteryKey },
|
{ "pause-on-battery", 0, nullptr, IConfig::PauseOnBatteryKey },
|
||||||
|
{ "pause-on-active", 1, nullptr, IConfig::PauseOnActiveKey },
|
||||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||||
{ "stress", 0, nullptr, IConfig::StressKey },
|
{ "stress", 0, nullptr, IConfig::StressKey },
|
||||||
{ "bench", 1, nullptr, IConfig::BenchKey },
|
{ "bench", 1, nullptr, IConfig::BenchKey },
|
||||||
@@ -155,7 +153,12 @@ static const option options[] = {
|
|||||||
# endif
|
# endif
|
||||||
# ifdef XMRIG_FEATURE_NVML
|
# ifdef XMRIG_FEATURE_NVML
|
||||||
{ "no-nvml", 0, nullptr, IConfig::NvmlKey },
|
{ "no-nvml", 0, nullptr, IConfig::NvmlKey },
|
||||||
|
# endif
|
||||||
|
# if defined(XMRIG_FEATURE_NVML) || defined (XMRIG_FEATURE_ADL)
|
||||||
{ "health-print-time", 1, nullptr, IConfig::HealthPrintTimeKey },
|
{ "health-print-time", 1, nullptr, IConfig::HealthPrintTimeKey },
|
||||||
|
# endif
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
{ "no-dmi", 0, nullptr, IConfig::DmiKey },
|
||||||
# endif
|
# endif
|
||||||
{ nullptr, 0, nullptr, 0 }
|
{ nullptr, 0, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
* Copyright (c) 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
* Copyright (c) 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* Copyright 2016-2020 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
|
||||||
@@ -64,6 +63,7 @@ static inline const std::string &usage()
|
|||||||
u += " --daemon use daemon RPC instead of pool for solo mining\n";
|
u += " --daemon use daemon RPC instead of pool for solo mining\n";
|
||||||
u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n";
|
u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n";
|
||||||
u += " --self-select=URL self-select block templates from URL\n";
|
u += " --self-select=URL self-select block templates from URL\n";
|
||||||
|
u += " --submit-to-origin also submit solution back to self-select URL\n";
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
u += " -r, --retries=N number of times to retry before switch to backup server (default: 5)\n";
|
u += " -r, --retries=N number of times to retry before switch to backup server (default: 5)\n";
|
||||||
@@ -83,6 +83,9 @@ static inline const std::string &usage()
|
|||||||
u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n";
|
u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n";
|
||||||
u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n";
|
u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n";
|
||||||
u += " --no-huge-pages disable huge pages support\n";
|
u += " --no-huge-pages disable huge pages support\n";
|
||||||
|
# ifdef XMRIG_OS_LINUX
|
||||||
|
u += " --hugepage-size=N custom hugepage size in kB\n";
|
||||||
|
# endif
|
||||||
u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n";
|
u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n";
|
||||||
|
|
||||||
# if defined(__x86_64__) || defined(_M_AMD64)
|
# if defined(__x86_64__) || defined(_M_AMD64)
|
||||||
@@ -155,7 +158,7 @@ static inline const std::string &usage()
|
|||||||
|
|
||||||
u += " -l, --log-file=FILE log all output to a file\n";
|
u += " -l, --log-file=FILE log all output to a file\n";
|
||||||
u += " --print-time=N print hashrate report every N seconds\n";
|
u += " --print-time=N print hashrate report every N seconds\n";
|
||||||
# ifdef XMRIG_FEATURE_NVML
|
# if defined(XMRIG_FEATURE_NVML) || defined(XMRIG_FEATURE_ADL)
|
||||||
u += " --health-print-time=N print health report every N seconds\n";
|
u += " --health-print-time=N print health report every N seconds\n";
|
||||||
# endif
|
# endif
|
||||||
u += " --no-color disable colored output\n";
|
u += " --no-color disable colored output\n";
|
||||||
@@ -178,6 +181,7 @@ static inline const std::string &usage()
|
|||||||
u += " --no-title disable setting console window title\n";
|
u += " --no-title disable setting console window title\n";
|
||||||
# endif
|
# endif
|
||||||
u += " --pause-on-battery pause mine on battery power\n";
|
u += " --pause-on-battery pause mine on battery power\n";
|
||||||
|
u += " --pause-on-active=N pause mine when the user is active (resume after N seconds of last activity)\n";
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||||
u += " --stress run continuous stress test to check system stability\n";
|
u += " --stress run continuous stress test to check system stability\n";
|
||||||
@@ -190,6 +194,10 @@ static inline const std::string &usage()
|
|||||||
u += " --hash=HASH compare benchmark result with specified hash\n";
|
u += " --hash=HASH compare benchmark result with specified hash\n";
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
u += " --no-dmi disable DMI/SMBIOS reader\n";
|
||||||
|
# endif
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,15 +49,15 @@
|
|||||||
|
|
||||||
|
|
||||||
#define ADD_FN(algo) \
|
#define ADD_FN(algo) \
|
||||||
m_map[algo][AV_SINGLE][Assembly::NONE] = cryptonight_single_hash<algo, false>; \
|
m_map[algo][AV_SINGLE][Assembly::NONE] = cryptonight_single_hash<algo, false, 0>; \
|
||||||
m_map[algo][AV_SINGLE_SOFT][Assembly::NONE] = cryptonight_single_hash<algo, true>; \
|
m_map[algo][AV_SINGLE_SOFT][Assembly::NONE] = cryptonight_single_hash<algo, true, 0>; \
|
||||||
m_map[algo][AV_DOUBLE][Assembly::NONE] = cryptonight_double_hash<algo, false>; \
|
m_map[algo][AV_DOUBLE][Assembly::NONE] = cryptonight_double_hash<algo, false>; \
|
||||||
m_map[algo][AV_DOUBLE_SOFT][Assembly::NONE] = cryptonight_double_hash<algo, true>; \
|
m_map[algo][AV_DOUBLE_SOFT][Assembly::NONE] = cryptonight_double_hash<algo, true>; \
|
||||||
m_map[algo][AV_TRIPLE][Assembly::NONE] = cryptonight_triple_hash<algo, false>; \
|
m_map[algo][AV_TRIPLE][Assembly::NONE] = cryptonight_triple_hash<algo, false>; \
|
||||||
m_map[algo][AV_TRIPLE_SOFT][Assembly::NONE] = cryptonight_triple_hash<algo, true>; \
|
m_map[algo][AV_TRIPLE_SOFT][Assembly::NONE] = cryptonight_triple_hash<algo, true>; \
|
||||||
m_map[algo][AV_QUAD][Assembly::NONE] = cryptonight_quad_hash<algo, false>; \
|
m_map[algo][AV_QUAD][Assembly::NONE] = cryptonight_quad_hash<algo, false>; \
|
||||||
m_map[algo][AV_QUAD_SOFT][Assembly::NONE] = cryptonight_quad_hash<algo, true>; \
|
m_map[algo][AV_QUAD_SOFT][Assembly::NONE] = cryptonight_quad_hash<algo, true>; \
|
||||||
m_map[algo][AV_PENTA][Assembly::NONE] = cryptonight_penta_hash<algo, false>; \
|
m_map[algo][AV_PENTA][Assembly::NONE] = cryptonight_penta_hash<algo, false>; \
|
||||||
m_map[algo][AV_PENTA_SOFT][Assembly::NONE] = cryptonight_penta_hash<algo, true>;
|
m_map[algo][AV_PENTA_SOFT][Assembly::NONE] = cryptonight_penta_hash<algo, true>;
|
||||||
|
|
||||||
|
|
||||||
@@ -298,6 +298,22 @@ xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
|
// cn-heavy optimization for Zen3 CPUs
|
||||||
|
if ((av == AV_SINGLE) && (assembly != Assembly::NONE) && (Cpu::info()->arch() == ICpuInfo::ARCH_ZEN3)) {
|
||||||
|
switch (algorithm.id()) {
|
||||||
|
case xmrig::Algorithm::CN_HEAVY_0:
|
||||||
|
return cryptonight_single_hash<xmrig::Algorithm::CN_HEAVY_0, false, 3>;
|
||||||
|
case xmrig::Algorithm::CN_HEAVY_TUBE:
|
||||||
|
return cryptonight_single_hash<xmrig::Algorithm::CN_HEAVY_TUBE, false, 3>;
|
||||||
|
case xmrig::Algorithm::CN_HEAVY_XHV:
|
||||||
|
return cryptonight_single_hash<xmrig::Algorithm::CN_HEAVY_XHV, false, 3>;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_ASM
|
# ifdef XMRIG_FEATURE_ASM
|
||||||
cn_hash_fun fun = cnHash.m_map[algorithm][av][Cpu::assembly(assembly)];
|
cn_hash_fun fun = cnHash.m_map[algorithm][av][Cpu::assembly(assembly)];
|
||||||
if (fun) {
|
if (fun) {
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ static inline void cryptonight_conceal_tweak(__m128i& cx, __m128& conc_var)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<Algorithm::Id ALGO, bool SOFT_AES>
|
template<Algorithm::Id ALGO, bool SOFT_AES, int interleave>
|
||||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height)
|
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height)
|
||||||
{
|
{
|
||||||
constexpr CnAlgo<ALGO> props;
|
constexpr CnAlgo<ALGO> props;
|
||||||
|
|||||||
@@ -306,7 +306,21 @@ inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3
|
|||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
template<Algorithm::Id ALGO, bool SOFT_AES>
|
template<int interleave>
|
||||||
|
static inline constexpr uint64_t interleaved_index(uint64_t k)
|
||||||
|
{
|
||||||
|
return ((k & ~63ULL) << interleave) | (k & 63);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline constexpr uint64_t interleaved_index<0>(uint64_t k)
|
||||||
|
{
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Id ALGO, bool SOFT_AES, int interleave>
|
||||||
static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
||||||
{
|
{
|
||||||
constexpr CnAlgo<ALGO> props;
|
constexpr CnAlgo<ALGO> props;
|
||||||
@@ -343,6 +357,11 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) {
|
for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) {
|
||||||
|
if (interleave > 0) {
|
||||||
|
_mm_prefetch((const char*)(output), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(output + (64 << interleave) / sizeof(__m128i)), _MM_HINT_T0);
|
||||||
|
}
|
||||||
|
|
||||||
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
aes_round<SOFT_AES>(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||||
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
aes_round<SOFT_AES>(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||||
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
aes_round<SOFT_AES>(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||||
@@ -354,19 +373,21 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output)
|
|||||||
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
aes_round<SOFT_AES>(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||||
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
aes_round<SOFT_AES>(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7);
|
||||||
|
|
||||||
_mm_store_si128(output + i + 0, xin0);
|
_mm_store_si128(output + 0, xin0);
|
||||||
_mm_store_si128(output + i + 1, xin1);
|
_mm_store_si128(output + 1, xin1);
|
||||||
_mm_store_si128(output + i + 2, xin2);
|
_mm_store_si128(output + 2, xin2);
|
||||||
_mm_store_si128(output + i + 3, xin3);
|
_mm_store_si128(output + 3, xin3);
|
||||||
_mm_store_si128(output + i + 4, xin4);
|
output += (64 << interleave) / sizeof(__m128i);
|
||||||
_mm_store_si128(output + i + 5, xin5);
|
_mm_store_si128(output + 0, xin4);
|
||||||
_mm_store_si128(output + i + 6, xin6);
|
_mm_store_si128(output + 1, xin5);
|
||||||
_mm_store_si128(output + i + 7, xin7);
|
_mm_store_si128(output + 2, xin6);
|
||||||
|
_mm_store_si128(output + 3, xin7);
|
||||||
|
output += (64 << interleave) / sizeof(__m128i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<Algorithm::Id ALGO, bool SOFT_AES>
|
template<Algorithm::Id ALGO, bool SOFT_AES, int interleave>
|
||||||
static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
||||||
{
|
{
|
||||||
constexpr CnAlgo<ALGO> props;
|
constexpr CnAlgo<ALGO> props;
|
||||||
@@ -387,15 +408,25 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||||||
xout6 = _mm_load_si128(output + 10);
|
xout6 = _mm_load_si128(output + 10);
|
||||||
xout7 = _mm_load_si128(output + 11);
|
xout7 = _mm_load_si128(output + 11);
|
||||||
|
|
||||||
for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) {
|
const __m128i* input_begin = input;
|
||||||
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
|
for (size_t i = 0; i < props.memory() / sizeof(__m128i);) {
|
||||||
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
|
xout0 = _mm_xor_si128(_mm_load_si128(input + 0), xout0);
|
||||||
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
|
xout1 = _mm_xor_si128(_mm_load_si128(input + 1), xout1);
|
||||||
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
|
xout2 = _mm_xor_si128(_mm_load_si128(input + 2), xout2);
|
||||||
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
|
xout3 = _mm_xor_si128(_mm_load_si128(input + 3), xout3);
|
||||||
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
|
input += (64 << interleave) / sizeof(__m128i);
|
||||||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
xout4 = _mm_xor_si128(_mm_load_si128(input + 0), xout4);
|
||||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
xout5 = _mm_xor_si128(_mm_load_si128(input + 1), xout5);
|
||||||
|
xout6 = _mm_xor_si128(_mm_load_si128(input + 2), xout6);
|
||||||
|
xout7 = _mm_xor_si128(_mm_load_si128(input + 3), xout7);
|
||||||
|
input += (64 << interleave) / sizeof(__m128i);
|
||||||
|
|
||||||
|
i += 8;
|
||||||
|
|
||||||
|
if ((interleave > 0) && (i < props.memory() / sizeof(__m128i))) {
|
||||||
|
_mm_prefetch((const char*)(input), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(input + (64 << interleave) / sizeof(__m128i)), _MM_HINT_T0);
|
||||||
|
}
|
||||||
|
|
||||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||||
@@ -414,15 +445,25 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IS_HEAVY) {
|
if (IS_HEAVY) {
|
||||||
for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) {
|
input = input_begin;
|
||||||
xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0);
|
for (size_t i = 0; i < props.memory() / sizeof(__m128i);) {
|
||||||
xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1);
|
xout0 = _mm_xor_si128(_mm_load_si128(input + 0), xout0);
|
||||||
xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2);
|
xout1 = _mm_xor_si128(_mm_load_si128(input + 1), xout1);
|
||||||
xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3);
|
xout2 = _mm_xor_si128(_mm_load_si128(input + 2), xout2);
|
||||||
xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4);
|
xout3 = _mm_xor_si128(_mm_load_si128(input + 3), xout3);
|
||||||
xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5);
|
input += (64 << interleave) / sizeof(__m128i);
|
||||||
xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6);
|
xout4 = _mm_xor_si128(_mm_load_si128(input + 0), xout4);
|
||||||
xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7);
|
xout5 = _mm_xor_si128(_mm_load_si128(input + 1), xout5);
|
||||||
|
xout6 = _mm_xor_si128(_mm_load_si128(input + 2), xout6);
|
||||||
|
xout7 = _mm_xor_si128(_mm_load_si128(input + 3), xout7);
|
||||||
|
input += (64 << interleave) / sizeof(__m128i);
|
||||||
|
|
||||||
|
i += 8;
|
||||||
|
|
||||||
|
if ((interleave > 0) && (i < props.memory() / sizeof(__m128i))) {
|
||||||
|
_mm_prefetch((const char*)(input), _MM_HINT_T0);
|
||||||
|
_mm_prefetch((const char*)(input + (64 << interleave) / sizeof(__m128i)), _MM_HINT_T0);
|
||||||
|
}
|
||||||
|
|
||||||
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
aes_round<SOFT_AES>(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||||
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
aes_round<SOFT_AES>(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7);
|
||||||
@@ -558,7 +599,7 @@ static inline void cryptonight_conceal_tweak(__m128i& cx, __m128& conc_var)
|
|||||||
cx = _mm_xor_si128(cx, _mm_cvttps_epi32(nc));
|
cx = _mm_xor_si128(cx, _mm_cvttps_epi32(nc));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Algorithm::Id ALGO, bool SOFT_AES>
|
template<Algorithm::Id ALGO, bool SOFT_AES, int interleave>
|
||||||
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height)
|
inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height)
|
||||||
{
|
{
|
||||||
constexpr CnAlgo<ALGO> props;
|
constexpr CnAlgo<ALGO> props;
|
||||||
@@ -577,7 +618,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
}
|
}
|
||||||
|
|
||||||
keccak(input, size, ctx[0]->state);
|
keccak(input, size, ctx[0]->state);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i *>(ctx[0]->state), reinterpret_cast<__m128i *>(ctx[0]->memory));
|
cn_explode_scratchpad<ALGO, SOFT_AES, interleave>(reinterpret_cast<const __m128i *>(ctx[0]->state), reinterpret_cast<__m128i *>(ctx[0]->memory));
|
||||||
|
|
||||||
uint64_t *h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
uint64_t *h0 = reinterpret_cast<uint64_t*>(ctx[0]->state);
|
||||||
uint8_t *l0 = ctx[0]->memory;
|
uint8_t *l0 = ctx[0]->memory;
|
||||||
@@ -620,7 +661,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
for (size_t i = 0; i < props.iterations(); i++) {
|
for (size_t i = 0; i < props.iterations(); i++) {
|
||||||
__m128i cx;
|
__m128i cx;
|
||||||
if (IS_CN_HEAVY_TUBE || !SOFT_AES) {
|
if (IS_CN_HEAVY_TUBE || !SOFT_AES) {
|
||||||
cx = _mm_load_si128(reinterpret_cast<const __m128i *>(&l0[idx0 & MASK]));
|
cx = _mm_load_si128(reinterpret_cast<const __m128i *>(&l0[interleaved_index<interleave>(idx0 & MASK)]));
|
||||||
if (ALGO == Algorithm::CN_CCX) {
|
if (ALGO == Algorithm::CN_CCX) {
|
||||||
cryptonight_conceal_tweak(cx, conc_var);
|
cryptonight_conceal_tweak(cx, conc_var);
|
||||||
}
|
}
|
||||||
@@ -632,12 +673,12 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
}
|
}
|
||||||
else if (SOFT_AES) {
|
else if (SOFT_AES) {
|
||||||
if (ALGO == Algorithm::CN_CCX) {
|
if (ALGO == Algorithm::CN_CCX) {
|
||||||
cx = _mm_load_si128(reinterpret_cast<const __m128i*>(&l0[idx0 & MASK]));
|
cx = _mm_load_si128(reinterpret_cast<const __m128i*>(&l0[interleaved_index<interleave>(idx0 & MASK)]));
|
||||||
cryptonight_conceal_tweak(cx, conc_var);
|
cryptonight_conceal_tweak(cx, conc_var);
|
||||||
cx = soft_aesenc(&cx, ax0, reinterpret_cast<const uint32_t*>(saes_table));
|
cx = soft_aesenc(&cx, ax0, reinterpret_cast<const uint32_t*>(saes_table));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cx = soft_aesenc(&l0[idx0 & MASK], ax0, reinterpret_cast<const uint32_t*>(saes_table));
|
cx = soft_aesenc(&l0[interleaved_index<interleave>(idx0 & MASK)], ax0, reinterpret_cast<const uint32_t*>(saes_table));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -645,16 +686,16 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (BASE == Algorithm::CN_1 || BASE == Algorithm::CN_2) {
|
if (BASE == Algorithm::CN_1 || BASE == Algorithm::CN_2) {
|
||||||
cryptonight_monero_tweak<ALGO>(reinterpret_cast<uint64_t*>(&l0[idx0 & MASK]), l0, idx0 & MASK, ax0, bx0, bx1, cx);
|
cryptonight_monero_tweak<ALGO>(reinterpret_cast<uint64_t*>(&l0[interleaved_index<interleave>(idx0 & MASK)]), l0, idx0 & MASK, ax0, bx0, bx1, cx);
|
||||||
} else {
|
} else {
|
||||||
_mm_store_si128(reinterpret_cast<__m128i *>(&l0[idx0 & MASK]), _mm_xor_si128(bx0, cx));
|
_mm_store_si128(reinterpret_cast<__m128i *>(&l0[interleaved_index<interleave>(idx0 & MASK)]), _mm_xor_si128(bx0, cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
idx0 = static_cast<uint64_t>(_mm_cvtsi128_si64(cx));
|
idx0 = static_cast<uint64_t>(_mm_cvtsi128_si64(cx));
|
||||||
|
|
||||||
uint64_t hi, lo, cl, ch;
|
uint64_t hi, lo, cl, ch;
|
||||||
cl = (reinterpret_cast<uint64_t*>(&l0[idx0 & MASK]))[0];
|
cl = (reinterpret_cast<uint64_t*>(&l0[interleaved_index<interleave>(idx0 & MASK)]))[0];
|
||||||
ch = (reinterpret_cast<uint64_t*>(&l0[idx0 & MASK]))[1];
|
ch = (reinterpret_cast<uint64_t*>(&l0[interleaved_index<interleave>(idx0 & MASK)]))[1];
|
||||||
|
|
||||||
if (BASE == Algorithm::CN_2) {
|
if (BASE == Algorithm::CN_2) {
|
||||||
if (props.isR()) {
|
if (props.isR()) {
|
||||||
@@ -681,14 +722,14 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
al0 += hi;
|
al0 += hi;
|
||||||
ah0 += lo;
|
ah0 += lo;
|
||||||
|
|
||||||
reinterpret_cast<uint64_t*>(&l0[idx0 & MASK])[0] = al0;
|
reinterpret_cast<uint64_t*>(&l0[interleaved_index<interleave>(idx0 & MASK)])[0] = al0;
|
||||||
|
|
||||||
if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) {
|
if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) {
|
||||||
reinterpret_cast<uint64_t*>(&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0;
|
reinterpret_cast<uint64_t*>(&l0[interleaved_index<interleave>(idx0 & MASK)])[1] = ah0 ^ tweak1_2_0 ^ al0;
|
||||||
} else if (BASE == Algorithm::CN_1) {
|
} else if (BASE == Algorithm::CN_1) {
|
||||||
reinterpret_cast<uint64_t*>(&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0;
|
reinterpret_cast<uint64_t*>(&l0[interleaved_index<interleave>(idx0 & MASK)])[1] = ah0 ^ tweak1_2_0;
|
||||||
} else {
|
} else {
|
||||||
reinterpret_cast<uint64_t*>(&l0[idx0 & MASK])[1] = ah0;
|
reinterpret_cast<uint64_t*>(&l0[interleaved_index<interleave>(idx0 & MASK)])[1] = ah0;
|
||||||
}
|
}
|
||||||
|
|
||||||
al0 ^= cl;
|
al0 ^= cl;
|
||||||
@@ -697,11 +738,11 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
|
|
||||||
# ifdef XMRIG_ALGO_CN_HEAVY
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
if (props.isHeavy()) {
|
if (props.isHeavy()) {
|
||||||
int64_t n = ((int64_t*)&l0[idx0 & MASK])[0];
|
int64_t n = ((int64_t*)&l0[interleaved_index<interleave>(idx0 & MASK)])[0];
|
||||||
int32_t d = ((int32_t*)&l0[idx0 & MASK])[2];
|
int32_t d = ((int32_t*)&l0[interleaved_index<interleave>(idx0 & MASK)])[2];
|
||||||
int64_t q = n / (d | 0x5);
|
int64_t q = n / (d | 0x5);
|
||||||
|
|
||||||
((int64_t*)&l0[idx0 & MASK])[0] = n ^ q;
|
((int64_t*)&l0[interleaved_index<interleave>(idx0 & MASK)])[0] = n ^ q;
|
||||||
|
|
||||||
if (ALGO == Algorithm::CN_HEAVY_XHV) {
|
if (ALGO == Algorithm::CN_HEAVY_XHV) {
|
||||||
d = ~d;
|
d = ~d;
|
||||||
@@ -722,7 +763,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i *>(ctx[0]->memory), reinterpret_cast<__m128i *>(ctx[0]->state));
|
cn_implode_scratchpad<ALGO, SOFT_AES, interleave>(reinterpret_cast<const __m128i *>(ctx[0]->memory), reinterpret_cast<__m128i *>(ctx[0]->state));
|
||||||
keccakf(h0, 24);
|
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);
|
||||||
}
|
}
|
||||||
@@ -810,7 +851,7 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_
|
|||||||
}
|
}
|
||||||
|
|
||||||
keccak(input, size, ctx[0]->state);
|
keccak(input, size, ctx[0]->state);
|
||||||
cn_explode_scratchpad<ALGO, false>(reinterpret_cast<const __m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory));
|
cn_explode_scratchpad<ALGO, false, 0>(reinterpret_cast<const __m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory));
|
||||||
|
|
||||||
if (ALGO == Algorithm::CN_2) {
|
if (ALGO == Algorithm::CN_2) {
|
||||||
if (ASM == Assembly::INTEL) {
|
if (ASM == Assembly::INTEL) {
|
||||||
@@ -887,7 +928,7 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_
|
|||||||
ctx[0]->generated_code(ctx);
|
ctx[0]->generated_code(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
cn_implode_scratchpad<ALGO, false>(reinterpret_cast<const __m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
|
cn_implode_scratchpad<ALGO, false, 0>(reinterpret_cast<const __m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 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);
|
||||||
}
|
}
|
||||||
@@ -909,8 +950,8 @@ inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_
|
|||||||
keccak(input, size, ctx[0]->state);
|
keccak(input, size, ctx[0]->state);
|
||||||
keccak(input + size, size, ctx[1]->state);
|
keccak(input + size, size, ctx[1]->state);
|
||||||
|
|
||||||
cn_explode_scratchpad<ALGO, false>(reinterpret_cast<const __m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory));
|
cn_explode_scratchpad<ALGO, false, 0>(reinterpret_cast<const __m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory));
|
||||||
cn_explode_scratchpad<ALGO, false>(reinterpret_cast<const __m128i*>(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory));
|
cn_explode_scratchpad<ALGO, false, 0>(reinterpret_cast<const __m128i*>(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory));
|
||||||
|
|
||||||
if (ALGO == Algorithm::CN_2) {
|
if (ALGO == Algorithm::CN_2) {
|
||||||
cnv2_double_mainloop_sandybridge_asm(ctx);
|
cnv2_double_mainloop_sandybridge_asm(ctx);
|
||||||
@@ -939,8 +980,8 @@ inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_
|
|||||||
ctx[0]->generated_code(ctx);
|
ctx[0]->generated_code(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
cn_implode_scratchpad<ALGO, false>(reinterpret_cast<const __m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
|
cn_implode_scratchpad<ALGO, false, 0>(reinterpret_cast<const __m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state));
|
||||||
cn_implode_scratchpad<ALGO, false>(reinterpret_cast<const __m128i*>(ctx[1]->memory), reinterpret_cast<__m128i*>(ctx[1]->state));
|
cn_implode_scratchpad<ALGO, false, 0>(reinterpret_cast<const __m128i*>(ctx[1]->memory), reinterpret_cast<__m128i*>(ctx[1]->state));
|
||||||
|
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[1]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[1]->state), 24);
|
||||||
@@ -991,8 +1032,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
VARIANT4_RANDOM_MATH_INIT(0);
|
VARIANT4_RANDOM_MATH_INIT(0);
|
||||||
VARIANT4_RANDOM_MATH_INIT(1);
|
VARIANT4_RANDOM_MATH_INIT(1);
|
||||||
|
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i *>(h0), reinterpret_cast<__m128i *>(l0));
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i *>(h0), reinterpret_cast<__m128i *>(l0));
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i *>(h1), reinterpret_cast<__m128i *>(l1));
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i *>(h1), reinterpret_cast<__m128i *>(l1));
|
||||||
|
|
||||||
uint64_t al0 = h0[0] ^ h0[4];
|
uint64_t al0 = h0[0] ^ h0[4];
|
||||||
uint64_t al1 = h1[0] ^ h1[4];
|
uint64_t al1 = h1[0] ^ h1[4];
|
||||||
@@ -1187,8 +1228,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
bx10 = cx1;
|
bx10 = cx1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i *>(l0), reinterpret_cast<__m128i *>(h0));
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i *>(l0), reinterpret_cast<__m128i *>(h0));
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i *>(l1), reinterpret_cast<__m128i *>(h1));
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i *>(l1), reinterpret_cast<__m128i *>(h1));
|
||||||
|
|
||||||
keccakf(h0, 24);
|
keccakf(h0, 24);
|
||||||
keccakf(h1, 24);
|
keccakf(h1, 24);
|
||||||
@@ -1333,7 +1374,7 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
|
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
keccak(input + size * i, size, ctx[i]->state);
|
keccak(input + size * i, size, ctx[i]->state);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* l0 = ctx[0]->memory;
|
uint8_t* l0 = ctx[0]->memory;
|
||||||
@@ -1378,7 +1419,7 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||||
}
|
}
|
||||||
@@ -1407,7 +1448,7 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size
|
|||||||
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
keccak(input + size * i, size, ctx[i]->state);
|
keccak(input + size * i, size, ctx[i]->state);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* l0 = ctx[0]->memory;
|
uint8_t* l0 = ctx[0]->memory;
|
||||||
@@ -1460,7 +1501,7 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||||
}
|
}
|
||||||
@@ -1489,7 +1530,7 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz
|
|||||||
|
|
||||||
for (size_t i = 0; i < 5; i++) {
|
for (size_t i = 0; i < 5; i++) {
|
||||||
keccak(input + size * i, size, ctx[i]->state);
|
keccak(input + size * i, size, ctx[i]->state);
|
||||||
cn_explode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
cn_explode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* l0 = ctx[0]->memory;
|
uint8_t* l0 = ctx[0]->memory;
|
||||||
@@ -1550,7 +1591,7 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < 5; i++) {
|
for (size_t i = 0; i < 5; i++) {
|
||||||
cn_implode_scratchpad<ALGO, SOFT_AES>(reinterpret_cast<const __m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
cn_implode_scratchpad<ALGO, SOFT_AES, 0>(reinterpret_cast<const __m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state));
|
||||||
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
keccakf(reinterpret_cast<uint64_t*>(ctx[i]->state), 24);
|
||||||
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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
|
||||||
@@ -27,24 +21,16 @@
|
|||||||
#include "crypto/common/VirtualMemory.h"
|
#include "crypto/common/VirtualMemory.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
|
||||||
|
|
||||||
constexpr size_t twoMiB = 2U * 1024U * 1024U;
|
|
||||||
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
|
||||||
|
|
||||||
} // namespace xmrig
|
|
||||||
|
|
||||||
|
|
||||||
xmrig::HugePagesInfo::HugePagesInfo(const VirtualMemory *memory)
|
xmrig::HugePagesInfo::HugePagesInfo(const VirtualMemory *memory)
|
||||||
{
|
{
|
||||||
if (memory->isOneGbPages()) {
|
if (memory->isOneGbPages()) {
|
||||||
size = VirtualMemory::align(memory->size(), oneGiB);
|
size = VirtualMemory::align(memory->size(), VirtualMemory::kOneGiB);
|
||||||
total = size / oneGiB;
|
total = size / VirtualMemory::kOneGiB;
|
||||||
allocated = size / oneGiB;
|
allocated = size / VirtualMemory::kOneGiB;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size = memory->size();
|
size = VirtualMemory::alignToHugePageSize(memory->size());
|
||||||
total = size / twoMiB;
|
total = size / VirtualMemory::hugePageSize();
|
||||||
allocated = memory->isHugePages() ? total : 0;
|
allocated = memory->isHugePages() ? total : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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-2019 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright 2016-2019 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
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
#include "crypto/common/LinuxMemory.h"
|
#include "crypto/common/LinuxMemory.h"
|
||||||
#include "3rdparty/fmt/core.h"
|
#include "3rdparty/fmt/core.h"
|
||||||
#include "backend/cpu/Cpu.h"
|
|
||||||
#include "base/io/log/Log.h"
|
|
||||||
#include "crypto/common/VirtualMemory.h"
|
#include "crypto/common/VirtualMemory.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -37,33 +35,32 @@ constexpr size_t twoMiB = 2U * 1024U * 1024U;
|
|||||||
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
|
||||||
|
|
||||||
|
|
||||||
static inline std::string sysfs_path(uint32_t node, bool oneGbPages, bool nr)
|
static inline std::string sysfs_path(uint32_t node, size_t hugePageSize, bool nr)
|
||||||
{
|
{
|
||||||
return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, oneGbPages ? "1048576" : "2048", nr ? "nr" : "free");
|
return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, hugePageSize / 1024, nr ? "nr" : "free");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool write_nr_hugepages(uint32_t node, bool oneGbPages, uint64_t count) { return LinuxMemory::write(sysfs_path(node, oneGbPages, true).c_str(), count); }
|
static inline bool write_nr_hugepages(uint32_t node, size_t hugePageSize, uint64_t count) { return LinuxMemory::write(sysfs_path(node, hugePageSize, true).c_str(), count); }
|
||||||
static inline int64_t free_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, false).c_str()); }
|
static inline int64_t free_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, false).c_str()); }
|
||||||
static inline int64_t nr_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, true).c_str()); }
|
static inline int64_t nr_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, true).c_str()); }
|
||||||
|
|
||||||
|
|
||||||
} // namespace xmrig
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, bool oneGbPages)
|
bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, size_t hugePageSize)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
const size_t pageSize = oneGbPages ? oneGiB : twoMiB;
|
const size_t required = VirtualMemory::align(size, hugePageSize) / hugePageSize;
|
||||||
const size_t required = VirtualMemory::align(size, pageSize) / pageSize;
|
|
||||||
|
|
||||||
const auto available = free_hugepages(node, oneGbPages);
|
const auto available = free_hugepages(node, hugePageSize);
|
||||||
if (available < 0 || static_cast<size_t>(available) >= required) {
|
if (available < 0 || static_cast<size_t>(available) >= required) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return write_nr_hugepages(node, oneGbPages, std::max<size_t>(nr_hugepages(node, oneGbPages), 0) + (required - available));
|
return write_nr_hugepages(node, hugePageSize, std::max<size_t>(nr_hugepages(node, hugePageSize), 0) + (required - available));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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,7 +30,7 @@ namespace xmrig {
|
|||||||
class LinuxMemory
|
class LinuxMemory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool reserve(size_t size, uint32_t node, bool oneGbPages = false);
|
static bool reserve(size_t size, uint32_t node, size_t hugePageSize);
|
||||||
|
|
||||||
static bool write(const char *path, uint64_t value);
|
static bool write(const char *path, uint64_t value);
|
||||||
static int64_t read(const char *path);
|
static int64_t read(const char *path);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -36,16 +36,19 @@
|
|||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
static IMemoryPool *pool = nullptr;
|
|
||||||
|
size_t VirtualMemory::m_hugePageSize = VirtualMemory::kDefaultHugePageSize;
|
||||||
|
static IMemoryPool *pool = nullptr;
|
||||||
static std::mutex mutex;
|
static std::mutex mutex;
|
||||||
|
|
||||||
|
|
||||||
} // namespace xmrig
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node, size_t alignSize) :
|
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node, size_t alignSize) :
|
||||||
m_size(align(size)),
|
m_size(alignToHugePageSize(size)),
|
||||||
m_capacity(m_size),
|
m_node(node),
|
||||||
m_node(node)
|
m_capacity(m_size)
|
||||||
{
|
{
|
||||||
if (usePool) {
|
if (usePool) {
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
@@ -114,18 +117,18 @@ void xmrig::VirtualMemory::destroy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::VirtualMemory::init(size_t poolSize, bool hugePages)
|
void xmrig::VirtualMemory::init(size_t poolSize, size_t hugePageSize)
|
||||||
{
|
{
|
||||||
if (!pool) {
|
if (!pool) {
|
||||||
osInit(hugePages);
|
osInit(hugePageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_HWLOC
|
# ifdef XMRIG_FEATURE_HWLOC
|
||||||
if (Cpu::info()->nodes() > 1) {
|
if (Cpu::info()->nodes() > 1) {
|
||||||
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePages);
|
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePageSize > 0);
|
||||||
} else
|
} else
|
||||||
# endif
|
# endif
|
||||||
{
|
{
|
||||||
pool = new MemoryPool(poolSize, hugePages);
|
pool = new MemoryPool(poolSize, hugePageSize > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -39,6 +39,9 @@ class VirtualMemory
|
|||||||
public:
|
public:
|
||||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory)
|
XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory)
|
||||||
|
|
||||||
|
constexpr static size_t kDefaultHugePageSize = 2U * 1024U * 1024U;
|
||||||
|
constexpr static size_t kOneGiB = 1024U * 1024U * 1024U;
|
||||||
|
|
||||||
VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64);
|
VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64);
|
||||||
~VirtualMemory();
|
~VirtualMemory();
|
||||||
|
|
||||||
@@ -65,9 +68,11 @@ public:
|
|||||||
static void destroy();
|
static void destroy();
|
||||||
static void flushInstructionCache(void *p, size_t size);
|
static void flushInstructionCache(void *p, size_t size);
|
||||||
static void freeLargePagesMemory(void *p, size_t size);
|
static void freeLargePagesMemory(void *p, size_t size);
|
||||||
static void init(size_t poolSize, bool hugePages);
|
static void init(size_t poolSize, size_t hugePageSize);
|
||||||
|
|
||||||
static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; }
|
static inline constexpr size_t align(size_t pos, size_t align = kDefaultHugePageSize) { return ((pos - 1) / align + 1) * align; }
|
||||||
|
static inline size_t alignToHugePageSize(size_t pos) { return align(pos, hugePageSize()); }
|
||||||
|
static inline size_t hugePageSize() { return m_hugePageSize; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Flags {
|
enum Flags {
|
||||||
@@ -78,15 +83,17 @@ private:
|
|||||||
FLAG_MAX
|
FLAG_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
static void osInit(bool hugePages);
|
static void osInit(size_t hugePageSize);
|
||||||
|
|
||||||
bool allocateLargePagesMemory();
|
bool allocateLargePagesMemory();
|
||||||
bool allocateOneGbPagesMemory();
|
bool allocateOneGbPagesMemory();
|
||||||
void freeLargePagesMemory();
|
void freeLargePagesMemory();
|
||||||
|
|
||||||
|
static size_t m_hugePageSize;
|
||||||
|
|
||||||
const size_t m_size;
|
const size_t m_size;
|
||||||
size_t m_capacity;
|
|
||||||
const uint32_t m_node;
|
const uint32_t m_node;
|
||||||
|
size_t m_capacity;
|
||||||
std::bitset<FLAG_MAX> m_flags;
|
std::bitset<FLAG_MAX> m_flags;
|
||||||
uint8_t *m_scratchpad = nullptr;
|
uint8_t *m_scratchpad = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -18,13 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <cstdlib>
|
#include "crypto/common/VirtualMemory.h"
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "backend/cpu/Cpu.h"
|
#include "backend/cpu/Cpu.h"
|
||||||
#include "crypto/common/portable/mm_malloc.h"
|
#include "crypto/common/portable/mm_malloc.h"
|
||||||
#include "crypto/common/VirtualMemory.h"
|
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_OS_APPLE
|
#ifdef XMRIG_OS_APPLE
|
||||||
@@ -42,14 +43,21 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(XMRIG_OS_LINUX)
|
#ifdef XMRIG_OS_LINUX
|
||||||
# if (defined(MAP_HUGE_1GB) || defined(MAP_HUGE_SHIFT))
|
|
||||||
# define XMRIG_HAS_1GB_PAGES
|
|
||||||
# endif
|
|
||||||
# include "crypto/common/LinuxMemory.h"
|
# include "crypto/common/LinuxMemory.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MAP_HUGE_SHIFT
|
||||||
|
# define MAP_HUGE_SHIFT 26
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MAP_HUGE_MASK
|
||||||
|
# define MAP_HUGE_MASK 0x3f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_SECURE_JIT
|
#ifdef XMRIG_SECURE_JIT
|
||||||
# define SECURE_PROT_EXEC 0
|
# define SECURE_PROT_EXEC 0
|
||||||
#else
|
#else
|
||||||
@@ -57,6 +65,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(XMRIG_OS_LINUX) || (!defined(XMRIG_OS_APPLE) && !defined(__FreeBSD__))
|
||||||
|
static inline int hugePagesFlag(size_t size)
|
||||||
|
{
|
||||||
|
return (static_cast<int>(log2(size)) & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::VirtualMemory::isHugepagesAvailable()
|
bool xmrig::VirtualMemory::isHugepagesAvailable()
|
||||||
{
|
{
|
||||||
# if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM)
|
# if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM)
|
||||||
@@ -69,7 +85,7 @@ bool xmrig::VirtualMemory::isHugepagesAvailable()
|
|||||||
|
|
||||||
bool xmrig::VirtualMemory::isOneGbPagesAvailable()
|
bool xmrig::VirtualMemory::isOneGbPagesAvailable()
|
||||||
{
|
{
|
||||||
# ifdef XMRIG_HAS_1GB_PAGES
|
# ifdef XMRIG_OS_LINUX
|
||||||
return Cpu::info()->hasOneGbPages();
|
return Cpu::info()->hasOneGbPages();
|
||||||
# else
|
# else
|
||||||
return false;
|
return false;
|
||||||
@@ -126,18 +142,10 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages
|
|||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
# if defined(MAP_HUGE_2MB)
|
|
||||||
constexpr int flag_2mb = MAP_HUGE_2MB;
|
|
||||||
# elif defined(MAP_HUGE_SHIFT)
|
|
||||||
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
|
|
||||||
# else
|
|
||||||
constexpr int flag_2mb = 0;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
void *mem = nullptr;
|
void *mem = nullptr;
|
||||||
|
|
||||||
if (hugePages) {
|
if (hugePages) {
|
||||||
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | flag_2mb, -1, 0);
|
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | hugePagesFlag(hugePageSize()), -1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
@@ -152,22 +160,12 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages
|
|||||||
|
|
||||||
void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
|
void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
|
||||||
{
|
{
|
||||||
# if defined(__APPLE__)
|
# if defined(XMRIG_OS_APPLE)
|
||||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
|
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
|
||||||
# elif defined(__FreeBSD__)
|
# elif defined(__FreeBSD__)
|
||||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0);
|
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0);
|
||||||
# else
|
# else
|
||||||
|
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(hugePageSize()), 0, 0);
|
||||||
# if defined(MAP_HUGE_2MB)
|
|
||||||
constexpr int flag_2mb = MAP_HUGE_2MB;
|
|
||||||
# elif defined(MAP_HUGE_SHIFT)
|
|
||||||
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
|
|
||||||
# else
|
|
||||||
constexpr int flag_2mb = 0;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_2mb, 0, 0);
|
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
return mem == MAP_FAILED ? nullptr : mem;
|
return mem == MAP_FAILED ? nullptr : mem;
|
||||||
@@ -176,17 +174,9 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
|
|||||||
|
|
||||||
void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size)
|
void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size)
|
||||||
{
|
{
|
||||||
# ifdef XMRIG_HAS_1GB_PAGES
|
# ifdef XMRIG_OS_LINUX
|
||||||
if (isOneGbPagesAvailable()) {
|
if (isOneGbPagesAvailable()) {
|
||||||
# if defined(MAP_HUGE_1GB)
|
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(kOneGiB), 0, 0);
|
||||||
constexpr int flag_1gb = MAP_HUGE_1GB;
|
|
||||||
# elif defined(MAP_HUGE_SHIFT)
|
|
||||||
constexpr int flag_1gb = (30 << MAP_HUGE_SHIFT);
|
|
||||||
# else
|
|
||||||
constexpr int flag_1gb = 0;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_1gb, 0, 0);
|
|
||||||
|
|
||||||
return mem == MAP_FAILED ? nullptr : mem;
|
return mem == MAP_FAILED ? nullptr : mem;
|
||||||
}
|
}
|
||||||
@@ -212,15 +202,18 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::VirtualMemory::osInit(bool)
|
void xmrig::VirtualMemory::osInit(size_t hugePageSize)
|
||||||
{
|
{
|
||||||
|
if (hugePageSize) {
|
||||||
|
m_hugePageSize = hugePageSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::VirtualMemory::allocateLargePagesMemory()
|
bool xmrig::VirtualMemory::allocateLargePagesMemory()
|
||||||
{
|
{
|
||||||
# if defined(XMRIG_OS_LINUX)
|
# ifdef XMRIG_OS_LINUX
|
||||||
LinuxMemory::reserve(m_size, m_node);
|
LinuxMemory::reserve(m_size, m_node, hugePageSize());
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
|
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
|
||||||
@@ -242,8 +235,8 @@ bool xmrig::VirtualMemory::allocateLargePagesMemory()
|
|||||||
|
|
||||||
bool xmrig::VirtualMemory::allocateOneGbPagesMemory()
|
bool xmrig::VirtualMemory::allocateOneGbPagesMemory()
|
||||||
{
|
{
|
||||||
# if defined(XMRIG_HAS_1GB_PAGES)
|
# ifdef XMRIG_OS_LINUX
|
||||||
LinuxMemory::reserve(m_size, m_node, true);
|
LinuxMemory::reserve(m_size, m_node, kOneGiB);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
m_scratchpad = static_cast<uint8_t*>(allocateOneGbPagesMemory(m_size));
|
m_scratchpad = static_cast<uint8_t*>(allocateOneGbPagesMemory(m_size));
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -24,9 +24,9 @@
|
|||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "crypto/common/VirtualMemory.h"
|
||||||
#include "base/io/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
#include "crypto/common/portable/mm_malloc.h"
|
#include "crypto/common/portable/mm_malloc.h"
|
||||||
#include "crypto/common/VirtualMemory.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_SECURE_JIT
|
#ifdef XMRIG_SECURE_JIT
|
||||||
@@ -233,9 +233,9 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void xmrig::VirtualMemory::osInit(bool hugePages)
|
void xmrig::VirtualMemory::osInit(size_t hugePageSize)
|
||||||
{
|
{
|
||||||
if (hugePages) {
|
if (hugePageSize) {
|
||||||
hugepagesAvailable = TrySetLockPagesPrivilege();
|
hugepagesAvailable = TrySetLockPagesPrivilege();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ hashAndFillAes1Rx4_impl* softAESImpl = &hashAndFillAes1Rx4<1,1>;
|
|||||||
|
|
||||||
void SelectSoftAESImpl(size_t threadsCount)
|
void SelectSoftAESImpl(size_t threadsCount)
|
||||||
{
|
{
|
||||||
constexpr int test_length_ms = 100;
|
constexpr uint64_t test_length_ms = 100;
|
||||||
const std::array<hashAndFillAes1Rx4_impl *, 4> impl = {
|
const std::array<hashAndFillAes1Rx4_impl *, 4> impl = {
|
||||||
&hashAndFillAes1Rx4<1,1>,
|
&hashAndFillAes1Rx4<1,1>,
|
||||||
&hashAndFillAes1Rx4<2,1>,
|
&hashAndFillAes1Rx4<2,1>,
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
|
|||||||
emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos);
|
emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos);
|
||||||
|
|
||||||
# ifndef XMRIG_OS_APPLE
|
# ifndef XMRIG_OS_APPLE
|
||||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
|
|||||||
emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos);
|
emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos);
|
||||||
|
|
||||||
# ifndef XMRIG_OS_APPLE
|
# ifndef XMRIG_OS_APPLE
|
||||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
|
|||||||
codePos += p2 - p1;
|
codePos += p2 - p1;
|
||||||
|
|
||||||
# ifndef XMRIG_OS_APPLE
|
# ifndef XMRIG_OS_APPLE
|
||||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos));
|
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), codePos - MainLoopBegin);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,6 +401,10 @@ void JitCompilerA64::allocate(size_t size)
|
|||||||
code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePages));
|
code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePages));
|
||||||
|
|
||||||
memcpy(code, reinterpret_cast<const void *>(randomx_program_aarch64), CodeSize);
|
memcpy(code, reinterpret_cast<const void *>(randomx_program_aarch64), CodeSize);
|
||||||
|
|
||||||
|
# ifndef XMRIG_OS_APPLE
|
||||||
|
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code), CodeSize);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
Copyright (c) 2019-2021, SChernykh <https://github.com/SChernykh>
|
||||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
Copyright (c) 2019-2021, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "crypto/rx/Profiler.h"
|
#include "crypto/rx/Profiler.h"
|
||||||
|
|
||||||
#ifdef XMRIG_FIX_RYZEN
|
#ifdef XMRIG_FIX_RYZEN
|
||||||
# include "crypto/rx/Rx.h"
|
# include "crypto/rx/RxFix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@@ -164,8 +164,9 @@ namespace randomx {
|
|||||||
static const uint8_t NOP6[] = { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 };
|
static const uint8_t NOP6[] = { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 };
|
||||||
static const uint8_t NOP7[] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 };
|
static const uint8_t NOP7[] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 };
|
||||||
static const uint8_t NOP8[] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
static const uint8_t NOP8[] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
static const uint8_t NOP9[] = { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
static const uint8_t* NOPX[] = { NOP1, NOP2, NOP3, NOP4, NOP5, NOP6, NOP7, NOP8 };
|
static const uint8_t* NOPX[] = { NOP1, NOP2, NOP3, NOP4, NOP5, NOP6, NOP7, NOP8, NOP9 };
|
||||||
|
|
||||||
static const uint8_t JMP_ALIGN_PREFIX[14][16] = {
|
static const uint8_t JMP_ALIGN_PREFIX[14][16] = {
|
||||||
{},
|
{},
|
||||||
@@ -416,21 +417,20 @@ namespace randomx {
|
|||||||
|
|
||||||
void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) {
|
void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) {
|
||||||
codePos = ADDR(randomx_program_prologue_first_load) - ADDR(randomx_program_prologue);
|
codePos = ADDR(randomx_program_prologue_first_load) - ADDR(randomx_program_prologue);
|
||||||
code[codePos + 2] = 0xc0 + pcfg.readReg0;
|
*(uint32_t*)(code + codePos + 4) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||||
code[codePos + 5] = 0xc0 + pcfg.readReg1;
|
*(uint32_t*)(code + codePos + 14) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
||||||
*(uint32_t*)(code + codePos + 10) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
|
||||||
*(uint32_t*)(code + codePos + 20) = RandomX_CurrentConfig.ScratchpadL3Mask64_Calculated;
|
|
||||||
if (hasAVX) {
|
if (hasAVX) {
|
||||||
uint32_t* p = (uint32_t*)(code + codePos + 67);
|
uint32_t* p = (uint32_t*)(code + codePos + 61);
|
||||||
*p = (*p & 0xFF000000U) | 0x0077F8C5U;
|
*p = (*p & 0xFF000000U) | 0x0077F8C5U;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef XMRIG_FIX_RYZEN
|
# ifdef XMRIG_FIX_RYZEN
|
||||||
xmrig::Rx::setMainLoopBounds(mainLoopBounds);
|
xmrig::RxFix::setMainLoopBounds(mainLoopBounds);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
memcpy(code + prologueSize - 48, &pcfg.eMask, sizeof(pcfg.eMask));
|
memcpy(code + prologueSize - 48, &pcfg.eMask, sizeof(pcfg.eMask));
|
||||||
codePos = codePosFirst;
|
codePos = codePosFirst;
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
//mark all registers as used
|
//mark all registers as used
|
||||||
uint64_t* r = (uint64_t*)registerUsage;
|
uint64_t* r = (uint64_t*)registerUsage;
|
||||||
@@ -1155,6 +1155,8 @@ namespace randomx {
|
|||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const uint64_t dst = instr.dst % RegisterCountFlt;
|
const uint64_t dst = instr.dst % RegisterCountFlt;
|
||||||
const uint64_t src = instr.src % RegisterCountFlt;
|
const uint64_t src = instr.src % RegisterCountFlt;
|
||||||
|
|
||||||
@@ -1168,6 +1170,8 @@ namespace randomx {
|
|||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const uint32_t src = instr.src % RegistersCount;
|
const uint32_t src = instr.src % RegistersCount;
|
||||||
const uint32_t dst = instr.dst % RegisterCountFlt;
|
const uint32_t dst = instr.dst % RegisterCountFlt;
|
||||||
|
|
||||||
@@ -1183,6 +1187,8 @@ namespace randomx {
|
|||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const uint64_t dst = instr.dst % RegisterCountFlt;
|
const uint64_t dst = instr.dst % RegisterCountFlt;
|
||||||
const uint64_t src = instr.src % RegisterCountFlt;
|
const uint64_t src = instr.src % RegisterCountFlt;
|
||||||
|
|
||||||
@@ -1196,6 +1202,8 @@ namespace randomx {
|
|||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const uint32_t src = instr.src % RegistersCount;
|
const uint32_t src = instr.src % RegistersCount;
|
||||||
const uint32_t dst = instr.dst % RegisterCountFlt;
|
const uint32_t dst = instr.dst % RegisterCountFlt;
|
||||||
|
|
||||||
@@ -1221,7 +1229,9 @@ namespace randomx {
|
|||||||
void JitCompilerX86::h_FMUL_R(const Instruction& instr) {
|
void JitCompilerX86::h_FMUL_R(const Instruction& instr) {
|
||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const uint64_t dst = instr.dst % RegisterCountFlt;
|
const uint64_t dst = instr.dst % RegisterCountFlt;
|
||||||
const uint64_t src = instr.src % RegisterCountFlt;
|
const uint64_t src = instr.src % RegisterCountFlt;
|
||||||
|
|
||||||
@@ -1235,6 +1245,8 @@ namespace randomx {
|
|||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const uint32_t src = instr.src % RegistersCount;
|
const uint32_t src = instr.src % RegistersCount;
|
||||||
const uint64_t dst = instr.dst % RegisterCountFlt;
|
const uint64_t dst = instr.dst % RegisterCountFlt;
|
||||||
|
|
||||||
@@ -1260,6 +1272,8 @@ namespace randomx {
|
|||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const uint32_t dst = instr.dst % RegisterCountFlt;
|
const uint32_t dst = instr.dst % RegisterCountFlt;
|
||||||
|
|
||||||
emit32(0xe4510f66 + (((dst << 3) + dst) << 24), p, pos);
|
emit32(0xe4510f66 + (((dst << 3) + dst) << 24), p, pos);
|
||||||
@@ -1269,7 +1283,22 @@ namespace randomx {
|
|||||||
|
|
||||||
void JitCompilerX86::h_CFROUND(const Instruction& instr) {
|
void JitCompilerX86::h_CFROUND(const Instruction& instr) {
|
||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = prevCFROUND;
|
||||||
|
|
||||||
|
if (pos) {
|
||||||
|
if (vm_flags & RANDOMX_FLAG_AMD) {
|
||||||
|
memcpy(p + pos + 0, NOP9, 9);
|
||||||
|
memcpy(p + pos + 9, NOP9, 9);
|
||||||
|
memcpy(p + pos + 18, NOP8, 8);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(p + pos + 0, NOP8, 8);
|
||||||
|
memcpy(p + pos + 8, NOP6, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = codePos;
|
||||||
|
prevCFROUND = pos;
|
||||||
|
|
||||||
const uint32_t src = instr.src % RegistersCount;
|
const uint32_t src = instr.src % RegistersCount;
|
||||||
|
|
||||||
@@ -1293,7 +1322,22 @@ namespace randomx {
|
|||||||
|
|
||||||
void JitCompilerX86::h_CFROUND_BMI2(const Instruction& instr) {
|
void JitCompilerX86::h_CFROUND_BMI2(const Instruction& instr) {
|
||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = prevCFROUND;
|
||||||
|
|
||||||
|
if (pos) {
|
||||||
|
if (vm_flags & RANDOMX_FLAG_AMD) {
|
||||||
|
memcpy(p + pos + 0, NOP9, 9);
|
||||||
|
memcpy(p + pos + 9, NOP9, 9);
|
||||||
|
memcpy(p + pos + 18, NOP7, 7);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(p + pos + 0, NOP8, 8);
|
||||||
|
memcpy(p + pos + 8, NOP5, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = codePos;
|
||||||
|
prevCFROUND = pos;
|
||||||
|
|
||||||
const uint64_t src = instr.src % RegistersCount;
|
const uint64_t src = instr.src % RegistersCount;
|
||||||
|
|
||||||
@@ -1318,7 +1362,9 @@ namespace randomx {
|
|||||||
void JitCompilerX86::h_CBRANCH(const Instruction& instr) {
|
void JitCompilerX86::h_CBRANCH(const Instruction& instr) {
|
||||||
uint8_t* const p = code;
|
uint8_t* const p = code;
|
||||||
uint32_t pos = codePos;
|
uint32_t pos = codePos;
|
||||||
|
|
||||||
|
prevCFROUND = 0;
|
||||||
|
|
||||||
const int reg = instr.dst % RegistersCount;
|
const int reg = instr.dst % RegistersCount;
|
||||||
int32_t jmp_offset = registerUsage[reg] - (pos + 16);
|
int32_t jmp_offset = registerUsage[reg] - (pos + 16);
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ namespace randomx {
|
|||||||
uint32_t codePos = 0;
|
uint32_t codePos = 0;
|
||||||
uint32_t codePosFirst = 0;
|
uint32_t codePosFirst = 0;
|
||||||
uint32_t vm_flags = 0;
|
uint32_t vm_flags = 0;
|
||||||
|
uint32_t prevCFROUND = 0;
|
||||||
|
|
||||||
# ifdef XMRIG_FIX_RYZEN
|
# ifdef XMRIG_FIX_RYZEN
|
||||||
std::pair<const void*, const void*> mainLoopBounds;
|
std::pair<const void*, const void*> mainLoopBounds;
|
||||||
|
|||||||
@@ -93,8 +93,6 @@ DECL(randomx_program_prologue):
|
|||||||
movapd xmm15, xmmword ptr [scaleMask+rip]
|
movapd xmm15, xmmword ptr [scaleMask+rip]
|
||||||
|
|
||||||
DECL(randomx_program_prologue_first_load):
|
DECL(randomx_program_prologue_first_load):
|
||||||
xor rax, r8
|
|
||||||
xor rax, r8
|
|
||||||
mov rdx, rax
|
mov rdx, rax
|
||||||
and eax, RANDOMX_SCRATCHPAD_MASK
|
and eax, RANDOMX_SCRATCHPAD_MASK
|
||||||
ror rdx, 32
|
ror rdx, 32
|
||||||
|
|||||||
@@ -81,8 +81,6 @@ randomx_program_prologue PROC
|
|||||||
randomx_program_prologue ENDP
|
randomx_program_prologue ENDP
|
||||||
|
|
||||||
randomx_program_prologue_first_load PROC
|
randomx_program_prologue_first_load PROC
|
||||||
xor rax, r8
|
|
||||||
xor rax, r8
|
|
||||||
mov rdx, rax
|
mov rdx, rax
|
||||||
and eax, RANDOMX_SCRATCHPAD_MASK
|
and eax, RANDOMX_SCRATCHPAD_MASK
|
||||||
ror rdx, 32
|
ror rdx, 32
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -27,6 +27,12 @@
|
|||||||
#include "crypto/randomx/aes_hash.hpp"
|
#include "crypto/randomx/aes_hash.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_MSR
|
||||||
|
# include "crypto/rx/RxFix.h"
|
||||||
|
# include "crypto/rx/RxMsr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
@@ -34,8 +40,6 @@ class RxPrivate;
|
|||||||
|
|
||||||
|
|
||||||
static bool osInitialized = false;
|
static bool osInitialized = false;
|
||||||
static bool msrInitialized = false;
|
|
||||||
static bool msrEnabled = false;
|
|
||||||
static RxPrivate *d_ptr = nullptr;
|
static RxPrivate *d_ptr = nullptr;
|
||||||
|
|
||||||
|
|
||||||
@@ -65,9 +69,9 @@ xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId)
|
|||||||
|
|
||||||
void xmrig::Rx::destroy()
|
void xmrig::Rx::destroy()
|
||||||
{
|
{
|
||||||
if (osInitialized) {
|
# ifdef XMRIG_FEATURE_MSR
|
||||||
msrDestroy();
|
RxMsr::destroy();
|
||||||
}
|
# endif
|
||||||
|
|
||||||
delete d_ptr;
|
delete d_ptr;
|
||||||
|
|
||||||
@@ -84,27 +88,40 @@ void xmrig::Rx::init(IRxListener *listener)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu)
|
bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu)
|
||||||
{
|
{
|
||||||
if (seed.algorithm().family() != Algorithm::RANDOM_X) {
|
const Algorithm::Family f = seed.algorithm().family();
|
||||||
if (msrInitialized) {
|
if ((f != Algorithm::RANDOM_X)
|
||||||
msrDestroy();
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
msrInitialized = false;
|
&& (f != Algorithm::CN_HEAVY)
|
||||||
msrEnabled = false;
|
# endif
|
||||||
}
|
) {
|
||||||
|
# ifdef XMRIG_FEATURE_MSR
|
||||||
|
RxMsr::destroy();
|
||||||
|
# endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_MSR
|
||||||
|
if (!RxMsr::isInitialized()) {
|
||||||
|
RxMsr::init(config, cpu.threads().get(seed.algorithm()).data());
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
|
if (f == Algorithm::CN_HEAVY) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
randomx_set_scratchpad_prefetch_mode(config.scratchpadPrefetchMode());
|
randomx_set_scratchpad_prefetch_mode(config.scratchpadPrefetchMode());
|
||||||
randomx_set_huge_pages_jit(cpu.isHugePagesJit());
|
randomx_set_huge_pages_jit(cpu.isHugePagesJit());
|
||||||
randomx_set_optimized_dataset_init(config.initDatasetAVX2());
|
randomx_set_optimized_dataset_init(config.initDatasetAVX2());
|
||||||
|
|
||||||
if (!msrInitialized) {
|
|
||||||
msrEnabled = msrInit(config, cpu.threads().get(seed.algorithm()).data());
|
|
||||||
msrInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!osInitialized) {
|
if (!osInitialized) {
|
||||||
setupMainLoopExceptionFrame();
|
# ifdef XMRIG_FIX_RYZEN
|
||||||
|
RxFix::setupMainLoopExceptionFrame();
|
||||||
|
# endif
|
||||||
|
|
||||||
if (!cpu.isHwAES()) {
|
if (!cpu.isHwAES()) {
|
||||||
SelectSoftAESImpl(cpu.threads().get(seed.algorithm()).count());
|
SelectSoftAESImpl(cpu.threads().get(seed.algorithm()).count());
|
||||||
}
|
}
|
||||||
@@ -131,24 +148,7 @@ bool xmrig::Rx::isReady(const T &seed)
|
|||||||
#ifdef XMRIG_FEATURE_MSR
|
#ifdef XMRIG_FEATURE_MSR
|
||||||
bool xmrig::Rx::isMSR()
|
bool xmrig::Rx::isMSR()
|
||||||
{
|
{
|
||||||
return msrEnabled;
|
return RxMsr::isEnabled();
|
||||||
}
|
|
||||||
#else
|
|
||||||
bool xmrig::Rx::msrInit(const RxConfig &, const std::vector<CpuThread> &)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Rx::msrDestroy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef XMRIG_FIX_RYZEN
|
|
||||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
* Copyright (c) 2016-2021 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
|
||||||
@@ -52,20 +52,11 @@ public:
|
|||||||
template<typename T> static bool init(const T &seed, const RxConfig &config, const CpuConfig &cpu);
|
template<typename T> static bool init(const T &seed, const RxConfig &config, const CpuConfig &cpu);
|
||||||
template<typename T> static bool isReady(const T &seed);
|
template<typename T> static bool isReady(const T &seed);
|
||||||
|
|
||||||
# ifdef XMRIG_FIX_RYZEN
|
|
||||||
static void setMainLoopBounds(const std::pair<const void*, const void*>& bounds);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_MSR
|
# ifdef XMRIG_FEATURE_MSR
|
||||||
static bool isMSR();
|
static bool isMSR();
|
||||||
# else
|
# else
|
||||||
static constexpr bool isMSR() { return false; }
|
static constexpr bool isMSR() { return false; }
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
private:
|
|
||||||
static bool msrInit(const RxConfig &config, const std::vector<CpuThread>& threads);
|
|
||||||
static void msrDestroy();
|
|
||||||
static void setupMainLoopExceptionFrame();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_FEATURE_MSR
|
#ifdef XMRIG_FEATURE_MSR
|
||||||
# include "crypto/rx/msr/MsrItem.h"
|
# include "hw/msr/MsrItem.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -113,7 +113,6 @@ private:
|
|||||||
|
|
||||||
Mode readMode(const rapidjson::Value &value) const;
|
Mode readMode(const rapidjson::Value &value) const;
|
||||||
|
|
||||||
bool m_numa = true;
|
|
||||||
bool m_oneGbPages = false;
|
bool m_oneGbPages = false;
|
||||||
bool m_rdmsr = true;
|
bool m_rdmsr = true;
|
||||||
int m_threads = -1;
|
int m_threads = -1;
|
||||||
@@ -123,6 +122,7 @@ private:
|
|||||||
ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0;
|
ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0;
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_HWLOC
|
# ifdef XMRIG_FEATURE_HWLOC
|
||||||
|
bool m_numa = true;
|
||||||
std::vector<uint32_t> m_nodeset;
|
std::vector<uint32_t> m_nodeset;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|||||||
42
src/crypto/rx/RxFix.h
Normal file
42
src/crypto/rx/RxFix.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||||
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2021 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_RXFIX_H
|
||||||
|
#define XMRIG_RXFIX_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class RxFix
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void setMainLoopBounds(const std::pair<const void *, const void *> &bounds);
|
||||||
|
static void setupMainLoopExceptionFrame();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_RXFIX_H */
|
||||||
71
src/crypto/rx/RxFix_linux.cpp
Normal file
71
src/crypto/rx/RxFix_linux.cpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||||
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2021 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 "crypto/rx/RxFix.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ucontext.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||||
|
|
||||||
|
|
||||||
|
static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext)
|
||||||
|
{
|
||||||
|
ucontext_t *ucp = (ucontext_t*) ucontext;
|
||||||
|
|
||||||
|
LOG_VERBOSE(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]);
|
||||||
|
|
||||||
|
void* p = reinterpret_cast<void*>(ucp->uc_mcontext.gregs[REG_RIP]);
|
||||||
|
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||||
|
|
||||||
|
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||||
|
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::RxFix::setMainLoopBounds(const std::pair<const void *, const void *> &bounds)
|
||||||
|
{
|
||||||
|
mainLoopBounds = bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::RxFix::setupMainLoopExceptionFrame()
|
||||||
|
{
|
||||||
|
struct sigaction act = {};
|
||||||
|
act.sa_sigaction = MainLoopHandler;
|
||||||
|
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||||
|
sigaction(SIGSEGV, &act, nullptr);
|
||||||
|
sigaction(SIGILL, &act, nullptr);
|
||||||
|
}
|
||||||
74
src/crypto/rx/RxFix_win.cpp
Normal file
74
src/crypto/rx/RxFix_win.cpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||||
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2021 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 "crypto/rx/RxFix.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
||||||
|
|
||||||
|
|
||||||
|
static LONG WINAPI MainLoopHandler(_EXCEPTION_POINTERS *ExceptionInfo)
|
||||||
|
{
|
||||||
|
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xC0000005) {
|
||||||
|
const char* accessType;
|
||||||
|
switch (ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) {
|
||||||
|
case 0: accessType = "read"; break;
|
||||||
|
case 1: accessType = "write"; break;
|
||||||
|
case 8: accessType = "DEP violation"; break;
|
||||||
|
default: accessType = "unknown"; break;
|
||||||
|
}
|
||||||
|
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Access violation at 0x%p: %s at address 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionAddress, accessType, ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* p = reinterpret_cast<void*>(ExceptionInfo->ContextRecord->Rip);
|
||||||
|
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
||||||
|
|
||||||
|
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
||||||
|
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::RxFix::setMainLoopBounds(const std::pair<const void *, const void *> &bounds)
|
||||||
|
{
|
||||||
|
mainLoopBounds = bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::RxFix::setupMainLoopExceptionFrame()
|
||||||
|
{
|
||||||
|
AddVectoredExceptionHandler(1, MainLoopHandler);
|
||||||
|
}
|
||||||
183
src/crypto/rx/RxMsr.cpp
Normal file
183
src/crypto/rx/RxMsr.cpp
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||||
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2021 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 "crypto/rx/RxMsr.h"
|
||||||
|
#include "backend/cpu/Cpu.h"
|
||||||
|
#include "backend/cpu/CpuThread.h"
|
||||||
|
#include "base/io/log/Log.h"
|
||||||
|
#include "base/tools/Chrono.h"
|
||||||
|
#include "crypto/rx/RxConfig.h"
|
||||||
|
#include "hw/msr/Msr.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
bool RxMsr::m_cacheQoS = false;
|
||||||
|
bool RxMsr::m_enabled = false;
|
||||||
|
bool RxMsr::m_initialized = false;
|
||||||
|
|
||||||
|
|
||||||
|
static MsrItems items;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_OS_WIN
|
||||||
|
static constexpr inline int32_t get_cpu(int32_t) { return -1; }
|
||||||
|
#else
|
||||||
|
static constexpr inline int32_t get_cpu(int32_t cpu) { return cpu; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static bool wrmsr(const MsrItems &preset, const std::vector<CpuThread> &threads, bool cache_qos, bool save)
|
||||||
|
{
|
||||||
|
auto msr = Msr::get();
|
||||||
|
if (!msr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save) {
|
||||||
|
items.reserve(preset.size());
|
||||||
|
|
||||||
|
for (const auto &i : preset) {
|
||||||
|
auto item = msr->read(i.reg());
|
||||||
|
if (!item.isValid()) {
|
||||||
|
items.clear();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_VERBOSE("%s " CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), Msr::tag(), i.reg(), item.value(), MsrItem::maskedValue(item.value(), i.value(), i.mask()));
|
||||||
|
|
||||||
|
items.emplace_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Which CPU cores will have access to the full L3 cache
|
||||||
|
std::set<int32_t> cacheEnabled;
|
||||||
|
bool cacheQoSDisabled = threads.empty();
|
||||||
|
|
||||||
|
if (cache_qos) {
|
||||||
|
const auto &units = Cpu::info()->units();
|
||||||
|
|
||||||
|
for (const auto &t : threads) {
|
||||||
|
const auto affinity = static_cast<int32_t>(t.affinity());
|
||||||
|
|
||||||
|
// If some thread has no affinity or wrong affinity, disable cache QoS
|
||||||
|
if (affinity < 0 || std::find(units.begin(), units.end(), affinity) == units.end()) {
|
||||||
|
cacheQoSDisabled = true;
|
||||||
|
|
||||||
|
LOG_WARN("%s " YELLOW_BOLD("cache QoS can only be enabled when all mining threads have affinity set"), Msr::tag());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheEnabled.insert(affinity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return msr->write([&msr, &preset, cache_qos, &cacheEnabled, cacheQoSDisabled](int32_t cpu) {
|
||||||
|
for (const auto &item : preset) {
|
||||||
|
if (!msr->write(item, get_cpu(cpu))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cache_qos) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
|
||||||
|
if (cacheQoSDisabled || cacheEnabled.count(cpu)) {
|
||||||
|
return msr->write(0xC8F, 0, get_cpu(cpu));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable L3 cache for Class Of Service 1
|
||||||
|
if (!msr->write(0xC91, 0, get_cpu(cpu))) {
|
||||||
|
// Some CPUs don't let set it to all zeros
|
||||||
|
if (!msr->write(0xC91, 1, get_cpu(cpu))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign Class Of Service 1 to current CPU core
|
||||||
|
return msr->write(0xC8F, 1ULL << 32, get_cpu(cpu));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::RxMsr::init(const RxConfig &config, const std::vector<CpuThread> &threads)
|
||||||
|
{
|
||||||
|
if (isInitialized()) {
|
||||||
|
return isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
|
m_enabled = false;
|
||||||
|
|
||||||
|
const auto &preset = config.msrPreset();
|
||||||
|
if (preset.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t ts = Chrono::steadyMSecs();
|
||||||
|
m_cacheQoS = config.cacheQoS();
|
||||||
|
|
||||||
|
if (m_cacheQoS && !Cpu::info()->hasCatL3()) {
|
||||||
|
LOG_WARN("%s " YELLOW_BOLD("this CPU doesn't support cat_l3, cache QoS is unavailable"), Msr::tag());
|
||||||
|
|
||||||
|
m_cacheQoS = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_enabled = wrmsr(preset, threads, m_cacheQoS, config.rdmsr()))) {
|
||||||
|
LOG_NOTICE("%s " GREEN_BOLD("register values for \"%s\" preset have been set successfully") BLACK_BOLD(" (%" PRIu64 " ms)"), Msr::tag(), config.msrPresetName(), Chrono::steadyMSecs() - ts);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_ERR("%s " RED_BOLD("FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW"), Msr::tag());
|
||||||
|
}
|
||||||
|
|
||||||
|
return isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::RxMsr::destroy()
|
||||||
|
{
|
||||||
|
if (!isInitialized()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_initialized = false;
|
||||||
|
m_enabled = false;
|
||||||
|
|
||||||
|
if (items.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t ts = Chrono::steadyMSecs();
|
||||||
|
|
||||||
|
if (!wrmsr(items, std::vector<CpuThread>(), m_cacheQoS, false)) {
|
||||||
|
LOG_ERR("%s " RED_BOLD("failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)")), Msr::tag(), Chrono::steadyMSecs() - ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/crypto/rx/RxMsr.h
Normal file
54
src/crypto/rx/RxMsr.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||||
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2021 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_RXMSR_H
|
||||||
|
#define XMRIG_RXMSR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class CpuThread;
|
||||||
|
class RxConfig;
|
||||||
|
|
||||||
|
|
||||||
|
class RxMsr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static inline bool isEnabled() { return m_enabled; }
|
||||||
|
static inline bool isInitialized() { return m_initialized; }
|
||||||
|
|
||||||
|
static bool init(const RxConfig &config, const std::vector<CpuThread> &threads);
|
||||||
|
static void destroy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool m_cacheQoS;
|
||||||
|
static bool m_enabled;
|
||||||
|
static bool m_initialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_RXMSR_H */
|
||||||
@@ -1,313 +0,0 @@
|
|||||||
/* XMRig
|
|
||||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
|
||||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
|
||||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright (c) 2016-2020 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 "crypto/rx/Rx.h"
|
|
||||||
#include "backend/cpu/Cpu.h"
|
|
||||||
#include "backend/cpu/CpuThread.h"
|
|
||||||
#include "base/io/log/Log.h"
|
|
||||||
#include "base/tools/Chrono.h"
|
|
||||||
#include "crypto/rx/RxConfig.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cctype>
|
|
||||||
#include <cinttypes>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <ucontext.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
|
||||||
|
|
||||||
|
|
||||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
|
|
||||||
static MsrItems savedState;
|
|
||||||
|
|
||||||
|
|
||||||
static inline int dir_filter(const struct dirent *dirp)
|
|
||||||
{
|
|
||||||
return isdigit(dirp->d_name[0]) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool rdmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t &value)
|
|
||||||
{
|
|
||||||
char msr_file_name[64]{};
|
|
||||||
|
|
||||||
sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu);
|
|
||||||
int fd = open(msr_file_name, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool success = pread(fd, &value, sizeof value, reg) == sizeof value;
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static MsrItem rdmsr(uint32_t reg)
|
|
||||||
{
|
|
||||||
uint64_t value = 0;
|
|
||||||
if (!rdmsr_on_cpu(reg, 0, value)) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot read MSR 0x%08" PRIx32, tag, reg);
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return { reg, value };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint64_t get_masked_value(uint64_t old_value, uint64_t new_value, uint64_t mask)
|
|
||||||
{
|
|
||||||
return (new_value & mask) | (old_value & ~mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool wrmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t value, uint64_t mask)
|
|
||||||
{
|
|
||||||
// If a bit in mask is set to 1, use new value, otherwise use old value
|
|
||||||
if (mask != MsrItem::kNoMask) {
|
|
||||||
uint64_t old_value;
|
|
||||||
if (rdmsr_on_cpu(reg, cpu, old_value)) {
|
|
||||||
value = get_masked_value(old_value, value, mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char msr_file_name[64]{};
|
|
||||||
|
|
||||||
sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu);
|
|
||||||
int fd = open(msr_file_name, O_WRONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool success = pwrite(fd, &value, sizeof value, reg) == sizeof value;
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static bool wrmsr_on_all_cpus(uint32_t reg, uint64_t value, uint64_t mask, T&& callback)
|
|
||||||
{
|
|
||||||
struct dirent **namelist;
|
|
||||||
int dir_entries = scandir("/dev/cpu", &namelist, dir_filter, 0);
|
|
||||||
int errors = 0;
|
|
||||||
|
|
||||||
while (dir_entries--) {
|
|
||||||
if (!callback(reg, strtoul(namelist[dir_entries]->d_name, nullptr, 10), value, mask)) {
|
|
||||||
++errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(namelist[dir_entries]);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(namelist);
|
|
||||||
|
|
||||||
if (errors) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool wrmsr_modprobe()
|
|
||||||
{
|
|
||||||
if (system("/sbin/modprobe msr allow_writes=on > /dev/null 2>&1") != 0) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "msr kernel module is not available", tag);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool wrmsr(const MsrItems& preset, const std::vector<CpuThread>& threads, bool cache_qos, bool save)
|
|
||||||
{
|
|
||||||
if (!wrmsr_modprobe()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save) {
|
|
||||||
for (const auto &i : preset) {
|
|
||||||
auto item = rdmsr(i.reg());
|
|
||||||
LOG_VERBOSE(CLEAR "%s" CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), tag, i.reg(), item.value(), get_masked_value(item.value(), i.value(), i.mask()));
|
|
||||||
|
|
||||||
if (item.isValid()) {
|
|
||||||
savedState.emplace_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &i : preset) {
|
|
||||||
if (!wrmsr_on_all_cpus(i.reg(), i.value(), i.mask(), [](uint32_t reg, uint32_t cpu, uint64_t value, uint64_t mask) { return wrmsr_on_cpu(reg, cpu, value, mask); })) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t n = Cpu::info()->threads();
|
|
||||||
|
|
||||||
// Which CPU cores will have access to the full L3 cache
|
|
||||||
std::vector<bool> cacheEnabled(n, false);
|
|
||||||
bool cacheQoSDisabled = threads.empty();
|
|
||||||
|
|
||||||
for (const CpuThread& t : threads) {
|
|
||||||
// If some thread has no affinity or wrong affinity, disable cache QoS
|
|
||||||
if ((t.affinity() < 0) || (t.affinity() >= n)) {
|
|
||||||
cacheQoSDisabled = true;
|
|
||||||
if (cache_qos) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "Cache QoS can only be enabled when all mining threads have affinity set", tag);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheEnabled[t.affinity()] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache_qos && !Cpu::info()->hasCatL3()) {
|
|
||||||
if (!threads.empty()) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "This CPU doesn't support cat_l3, cache QoS is unavailable", tag);
|
|
||||||
}
|
|
||||||
cache_qos = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
if (cache_qos) {
|
|
||||||
result = wrmsr_on_all_cpus(0xC8F, 0, MsrItem::kNoMask, [&cacheEnabled, cacheQoSDisabled](uint32_t, uint32_t cpu, uint64_t, uint64_t) {
|
|
||||||
if (cacheQoSDisabled || (cpu >= cacheEnabled.size()) || cacheEnabled[cpu]) {
|
|
||||||
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
|
|
||||||
if (!wrmsr_on_cpu(0xC8F, cpu, 0, MsrItem::kNoMask)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Disable L3 cache for Class Of Service 1
|
|
||||||
if (!wrmsr_on_cpu(0xC91, cpu, 0, MsrItem::kNoMask)) {
|
|
||||||
// Some CPUs don't let set it to all zeros
|
|
||||||
if (!wrmsr_on_cpu(0xC91, cpu, 1, MsrItem::kNoMask)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign Class Of Service 1 to current CPU core
|
|
||||||
if (!wrmsr_on_cpu(0xC8F, cpu, 1ULL << 32, MsrItem::kNoMask)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_FIX_RYZEN
|
|
||||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
|
||||||
|
|
||||||
static void MainLoopHandler(int sig, siginfo_t *info, void *ucontext)
|
|
||||||
{
|
|
||||||
ucontext_t *ucp = (ucontext_t*) ucontext;
|
|
||||||
|
|
||||||
LOG_VERBOSE(YELLOW_BOLD("%s at %p"), (sig == SIGSEGV) ? "SIGSEGV" : "SIGILL", ucp->uc_mcontext.gregs[REG_RIP]);
|
|
||||||
|
|
||||||
void* p = reinterpret_cast<void*>(ucp->uc_mcontext.gregs[REG_RIP]);
|
|
||||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
|
||||||
|
|
||||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
|
||||||
ucp->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<size_t>(loopBounds.second);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
|
||||||
{
|
|
||||||
mainLoopBounds = bounds;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace xmrig
|
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread> &threads)
|
|
||||||
{
|
|
||||||
const auto &preset = config.msrPreset();
|
|
||||||
if (preset.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t ts = Chrono::steadyMSecs();
|
|
||||||
|
|
||||||
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
|
|
||||||
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Rx::msrDestroy()
|
|
||||||
{
|
|
||||||
if (savedState.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t ts = Chrono::steadyMSecs();
|
|
||||||
|
|
||||||
if (!wrmsr(savedState, std::vector<CpuThread>(), true, false)) {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
|
||||||
{
|
|
||||||
# ifdef XMRIG_FIX_RYZEN
|
|
||||||
struct sigaction act = {};
|
|
||||||
act.sa_sigaction = MainLoopHandler;
|
|
||||||
act.sa_flags = SA_RESTART | SA_SIGINFO;
|
|
||||||
sigaction(SIGSEGV, &act, nullptr);
|
|
||||||
sigaction(SIGILL, &act, nullptr);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
/* XMRig
|
|
||||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
|
||||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
|
||||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
|
||||||
* Copyright (c) 2007-2009 hiyohiyo <https://openlibsys.org>, <hiyohiyo@crystalmark.info>
|
|
||||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
|
||||||
* Copyright (c) 2016-2020 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 "crypto/rx/Rx.h"
|
|
||||||
#include "backend/cpu/Cpu.h"
|
|
||||||
#include "backend/cpu/CpuThread.h"
|
|
||||||
#include "base/io/log/Log.h"
|
|
||||||
#include "base/kernel/Platform.h"
|
|
||||||
#include "base/tools/Chrono.h"
|
|
||||||
#include "crypto/rx/RxConfig.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <array>
|
|
||||||
#include <string>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
|
|
||||||
#define SERVICE_NAME L"WinRing0_1_2_0"
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
|
||||||
|
|
||||||
|
|
||||||
static bool reuseDriver = false;
|
|
||||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " msr ") " ";
|
|
||||||
static MsrItems savedState;
|
|
||||||
|
|
||||||
|
|
||||||
static SC_HANDLE hManager;
|
|
||||||
static SC_HANDLE hService;
|
|
||||||
|
|
||||||
|
|
||||||
static bool wrmsr_uninstall_driver()
|
|
||||||
{
|
|
||||||
if (!hService) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
if (!reuseDriver) {
|
|
||||||
SERVICE_STATUS serviceStatus;
|
|
||||||
|
|
||||||
if (!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DeleteService(hService)) {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_S "failed to remove WinRing0 driver, error %u", tag, GetLastError());
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseServiceHandle(hService);
|
|
||||||
hService = nullptr;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static HANDLE wrmsr_install_driver()
|
|
||||||
{
|
|
||||||
DWORD err = 0;
|
|
||||||
|
|
||||||
hManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
|
|
||||||
if (!hManager) {
|
|
||||||
err = GetLastError();
|
|
||||||
|
|
||||||
if (err == ERROR_ACCESS_DENIED) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "to write MSR registers Administrator privileges required.", tag);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_S "failed to open service control manager, error %u", tag, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<wchar_t> dir;
|
|
||||||
dir.resize(MAX_PATH);
|
|
||||||
do {
|
|
||||||
dir.resize(dir.size() * 2);
|
|
||||||
GetModuleFileNameW(nullptr, dir.data(), dir.size());
|
|
||||||
err = GetLastError();
|
|
||||||
} while (err == ERROR_INSUFFICIENT_BUFFER);
|
|
||||||
|
|
||||||
if (err != ERROR_SUCCESS) {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_S "failed to get path to driver, error %u", tag, err);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = dir.end() - 1; it != dir.begin(); --it) {
|
|
||||||
if ((*it == L'\\') || (*it == L'/')) {
|
|
||||||
++it;
|
|
||||||
*it = L'\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring driverPath = dir.data();
|
|
||||||
driverPath += L"WinRing0x64.sys";
|
|
||||||
|
|
||||||
hService = OpenServiceW(hManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
|
|
||||||
if (hService) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW("service ") YELLOW_BOLD("WinRing0_1_2_0") YELLOW(" is already exists"), tag);
|
|
||||||
|
|
||||||
SERVICE_STATUS status;
|
|
||||||
const auto rc = QueryServiceStatus(hService, &status);
|
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
DWORD dwBytesNeeded;
|
|
||||||
|
|
||||||
QueryServiceConfigA(hService, nullptr, 0, &dwBytesNeeded);
|
|
||||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
|
||||||
std::vector<BYTE> buffer(dwBytesNeeded);
|
|
||||||
auto config = reinterpret_cast<LPQUERY_SERVICE_CONFIGA>(buffer.data());
|
|
||||||
|
|
||||||
if (QueryServiceConfigA(hService, config, buffer.size(), &dwBytesNeeded)) {
|
|
||||||
LOG_INFO(CLEAR "%s" YELLOW("service path: ") YELLOW_BOLD("\"%s\""), tag, config->lpBinaryPathName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rc && status.dwCurrentState == SERVICE_RUNNING) {
|
|
||||||
reuseDriver = true;
|
|
||||||
}
|
|
||||||
else if (!wrmsr_uninstall_driver()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reuseDriver) {
|
|
||||||
hService = CreateServiceW(hManager, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driverPath.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr);
|
|
||||||
if (!hService) {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_S "failed to install WinRing0 driver, error %u", tag, GetLastError());
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StartService(hService, 0, nullptr)) {
|
|
||||||
err = GetLastError();
|
|
||||||
if (err != ERROR_SERVICE_ALREADY_RUNNING) {
|
|
||||||
if (err == ERROR_FILE_NOT_FOUND) {
|
|
||||||
LOG_ERR(CLEAR "%s" RED("failed to start WinRing0 driver: ") RED_BOLD("\"WinRing0x64.sys not found\""), tag);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_S "failed to start WinRing0 driver, error %u", tag, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
wrmsr_uninstall_driver();
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE hDriver = CreateFileW(L"\\\\.\\" SERVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
|
||||||
if (!hDriver) {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_S "failed to connect to WinRing0 driver, error %u", tag, GetLastError());
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hDriver;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define IOCTL_READ_MSR CTL_CODE(40000, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
||||||
#define IOCTL_WRITE_MSR CTL_CODE(40000, 0x822, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
|
||||||
|
|
||||||
|
|
||||||
static bool rdmsr(HANDLE driver, uint32_t reg, uint64_t &value)
|
|
||||||
{
|
|
||||||
DWORD size = 0;
|
|
||||||
|
|
||||||
return DeviceIoControl(driver, IOCTL_READ_MSR, ®, sizeof(reg), &value, sizeof(value), &size, nullptr) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static MsrItem rdmsr(HANDLE driver, uint32_t reg)
|
|
||||||
{
|
|
||||||
uint64_t value = 0;
|
|
||||||
if (!rdmsr(driver, reg, value)) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot read MSR 0x%08" PRIx32, tag, reg);
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return { reg, value };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint64_t get_masked_value(uint64_t old_value, uint64_t new_value, uint64_t mask)
|
|
||||||
{
|
|
||||||
return (new_value & mask) | (old_value & ~mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool wrmsr(HANDLE driver, uint32_t reg, uint64_t value, uint64_t mask)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
uint32_t reg = 0;
|
|
||||||
uint32_t value[2]{};
|
|
||||||
} input;
|
|
||||||
|
|
||||||
static_assert(sizeof(input) == 12, "Invalid struct size for WinRing0 driver");
|
|
||||||
|
|
||||||
// If a bit in mask is set to 1, use new value, otherwise use old value
|
|
||||||
if (mask != MsrItem::kNoMask) {
|
|
||||||
uint64_t old_value;
|
|
||||||
if (rdmsr(driver, reg, old_value)) {
|
|
||||||
value = get_masked_value(old_value, value, mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input.reg = reg;
|
|
||||||
*(reinterpret_cast<uint64_t*>(input.value)) = value;
|
|
||||||
|
|
||||||
DWORD output;
|
|
||||||
DWORD k;
|
|
||||||
|
|
||||||
if (!DeviceIoControl(driver, IOCTL_WRITE_MSR, &input, sizeof(input), &output, sizeof(output), &k, nullptr)) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "cannot set MSR 0x%08" PRIx32 " to 0x%08" PRIx64, tag, reg, value);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool wrmsr(const MsrItems &preset, const std::vector<CpuThread>& threads, bool cache_qos, bool save)
|
|
||||||
{
|
|
||||||
bool success = true;
|
|
||||||
|
|
||||||
HANDLE driver = wrmsr_install_driver();
|
|
||||||
if (!driver) {
|
|
||||||
wrmsr_uninstall_driver();
|
|
||||||
|
|
||||||
if (hManager) {
|
|
||||||
CloseServiceHandle(hManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (save) {
|
|
||||||
for (const auto &i : preset) {
|
|
||||||
auto item = rdmsr(driver, i.reg());
|
|
||||||
LOG_VERBOSE(CLEAR "%s" CYAN_BOLD("0x%08" PRIx32) CYAN(":0x%016" PRIx64) CYAN_BOLD(" -> 0x%016" PRIx64), tag, i.reg(), item.value(), get_masked_value(item.value(), i.value(), i.mask()));
|
|
||||||
|
|
||||||
if (item.isValid()) {
|
|
||||||
savedState.emplace_back(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t n = Cpu::info()->threads();
|
|
||||||
|
|
||||||
// Which CPU cores will have access to the full L3 cache
|
|
||||||
std::vector<bool> cacheEnabled(n, false);
|
|
||||||
bool cacheQoSDisabled = threads.empty();
|
|
||||||
|
|
||||||
for (const CpuThread& t : threads) {
|
|
||||||
// If some thread has no affinity or wrong affinity, disable cache QoS
|
|
||||||
if ((t.affinity() < 0) || (t.affinity() >= n)) {
|
|
||||||
cacheQoSDisabled = true;
|
|
||||||
if (cache_qos) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "Cache QoS can only be enabled when all mining threads have affinity set", tag);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheEnabled[t.affinity()] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache_qos && !Cpu::info()->hasCatL3()) {
|
|
||||||
if (!threads.empty()) {
|
|
||||||
LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "This CPU doesn't support cat_l3, cache QoS is unavailable", tag);
|
|
||||||
}
|
|
||||||
cache_qos = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::thread wrmsr_thread([n, driver, &preset, &cacheEnabled, cache_qos, cacheQoSDisabled, &success]() {
|
|
||||||
for (uint32_t i = 0; i < n; ++i) {
|
|
||||||
if (!Platform::setThreadAffinity(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &i : preset) {
|
|
||||||
success &= wrmsr(driver, i.reg(), i.value(), i.mask());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cache_qos) {
|
|
||||||
if (cacheQoSDisabled || cacheEnabled[i]) {
|
|
||||||
// Assign Class Of Service 0 to current CPU core (default, full L3 cache available)
|
|
||||||
success &= wrmsr(driver, 0xC8F, 0, MsrItem::kNoMask);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Disable L3 cache for Class Of Service 1
|
|
||||||
if (!wrmsr(driver, 0xC91, 0, MsrItem::kNoMask)) {
|
|
||||||
// Some CPUs don't let set it to all zeros
|
|
||||||
if (!wrmsr(driver, 0xC91, 1, MsrItem::kNoMask)) {
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign Class Of Service 1 to current CPU core
|
|
||||||
success &= wrmsr(driver, 0xC8F, 1ULL << 32, MsrItem::kNoMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
wrmsr_thread.join();
|
|
||||||
|
|
||||||
CloseHandle(driver);
|
|
||||||
|
|
||||||
wrmsr_uninstall_driver();
|
|
||||||
CloseServiceHandle(hManager);
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_FIX_RYZEN
|
|
||||||
static thread_local std::pair<const void*, const void*> mainLoopBounds = { nullptr, nullptr };
|
|
||||||
|
|
||||||
static LONG WINAPI MainLoopHandler(_EXCEPTION_POINTERS *ExceptionInfo)
|
|
||||||
{
|
|
||||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == 0xC0000005) {
|
|
||||||
const char* accessType;
|
|
||||||
switch (ExceptionInfo->ExceptionRecord->ExceptionInformation[0]) {
|
|
||||||
case 0: accessType = "read"; break;
|
|
||||||
case 1: accessType = "write"; break;
|
|
||||||
case 8: accessType = "DEP violation"; break;
|
|
||||||
default: accessType = "unknown"; break;
|
|
||||||
}
|
|
||||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Access violation at 0x%p: %s at address 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionAddress, accessType, ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG_VERBOSE(YELLOW_BOLD("[THREAD %u] Exception 0x%08X at 0x%p"), GetCurrentThreadId(), ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
void* p = reinterpret_cast<void*>(ExceptionInfo->ContextRecord->Rip);
|
|
||||||
const std::pair<const void*, const void*>& loopBounds = mainLoopBounds;
|
|
||||||
|
|
||||||
if ((loopBounds.first <= p) && (p < loopBounds.second)) {
|
|
||||||
ExceptionInfo->ContextRecord->Rip = reinterpret_cast<DWORD64>(loopBounds.second);
|
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rx::setMainLoopBounds(const std::pair<const void*, const void*>& bounds)
|
|
||||||
{
|
|
||||||
mainLoopBounds = bounds;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace xmrig
|
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::Rx::msrInit(const RxConfig &config, const std::vector<CpuThread>& threads)
|
|
||||||
{
|
|
||||||
const auto &preset = config.msrPreset();
|
|
||||||
if (preset.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t ts = Chrono::steadyMSecs();
|
|
||||||
|
|
||||||
if (wrmsr(preset, threads, config.cacheQoS(), config.rdmsr())) {
|
|
||||||
LOG_NOTICE(CLEAR "%s" GREEN_BOLD_S "register values for \"%s\" preset has been set successfully" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, config.msrPresetName(), Chrono::steadyMSecs() - ts);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "FAILED TO APPLY MSR MOD, HASHRATE WILL BE LOW", tag);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Rx::msrDestroy()
|
|
||||||
{
|
|
||||||
if (savedState.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint64_t ts = Chrono::steadyMSecs();
|
|
||||||
|
|
||||||
if (!wrmsr(savedState, std::vector<CpuThread>(), true, false)) {
|
|
||||||
LOG_ERR(CLEAR "%s" RED_BOLD_S "failed to restore initial state" BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Rx::setupMainLoopExceptionFrame()
|
|
||||||
{
|
|
||||||
# ifdef XMRIG_FIX_RYZEN
|
|
||||||
AddVectoredExceptionHandler(1, MainLoopHandler);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
* Example of how it works for the setting of 1%:
|
* Example of how it works for the setting of 1%:
|
||||||
* You miner will mine into your usual pool for random time (in range from 49.5 to 148.5 minutes),
|
* You miner will mine into your usual pool for random time (in range from 49.5 to 148.5 minutes),
|
||||||
* then switch to the developer's pool for 1 minute, then switch again to your pool for 99 minutes
|
* then switch to the developer's pool for 1 minute, then switch again to your pool for 99 minutes
|
||||||
* and then switch agaiin to developer's pool for 1 minute, these rounds will continue until miner working.
|
* and then switch again to developer's pool for 1 minute, these rounds will continue until miner working.
|
||||||
*
|
*
|
||||||
* Randomised only first round, to prevent waves on the donation pool.
|
* Randomised only first round, to prevent waves on the donation pool.
|
||||||
*
|
*
|
||||||
|
|||||||
45
src/hw/api/HwApi.cpp
Normal file
45
src/hw/api/HwApi.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2021 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 "hw/api/HwApi.h"
|
||||||
|
#include "base/api/interfaces/IApiRequest.h"
|
||||||
|
#include "base/tools/String.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_DMI
|
||||||
|
# include "hw/dmi/DmiReader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::HwApi::onRequest(IApiRequest &request)
|
||||||
|
{
|
||||||
|
if (request.method() == IApiRequest::METHOD_GET) {
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
if (request.url() == "/2/dmi") {
|
||||||
|
if (!m_dmi) {
|
||||||
|
m_dmi = std::make_shared<DmiReader>();
|
||||||
|
m_dmi->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
request.accept();
|
||||||
|
m_dmi->toJSON(request.reply(), request.doc());
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/hw/api/HwApi.h
Normal file
53
src/hw/api/HwApi.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* XMRig
|
||||||
|
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright (c) 2016-2021 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_HWAPI_H
|
||||||
|
#define XMRIG_HWAPI_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "base/api/interfaces/IApiListener.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
struct DmiReader;
|
||||||
|
|
||||||
|
|
||||||
|
class HwApi : public IApiListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HwApi() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onRequest(IApiRequest &request) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
# ifdef XMRIG_FEATURE_DMI
|
||||||
|
std::shared_ptr<DmiReader> m_dmi;
|
||||||
|
# endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_HWAPI_H */
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user