Advertisement
Guest User

Untitled

a guest
Mar 30th, 2018
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 177.20 KB | None | 0 0
  1. diff --git a/.gitignore b/.gitignore
  2. index 30ce3a1..3094469 100644
  3. --- a/.gitignore
  4. +++ b/.gitignore
  5. @@ -1,3 +1,2 @@
  6. -/build
  7. -/CMakeLists.txt.user
  8. -/build2
  9. +.DS_Store
  10. +build
  11. diff --git a/.travis.yml b/.travis.yml
  12. new file mode 100644
  13. index 0000000..da46bf0
  14. --- /dev/null
  15. +++ b/.travis.yml
  16. @@ -0,0 +1,12 @@
  17. +sudo: required
  18. +
  19. +language: cpp
  20. +
  21. +services:
  22. +  - docker
  23. +
  24. +before_install:
  25. +  - docker build .
  26. +
  27. +script:
  28. +  - echo Done
  29. diff --git a/CHANGELOG.md b/CHANGELOG.md
  30. index d4f057b..e69de29 100644
  31. --- a/CHANGELOG.md
  32. +++ b/CHANGELOG.md
  33. @@ -1,31 +0,0 @@
  34. -# v2.5.2
  35. -- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect.
  36. -
  37. -# v2.5.1
  38. -- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35.
  39. -- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced.
  40. -- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**.
  41. -
  42. -# v2.5.0
  43. -- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.**
  44. -- Added full IPv6 support.
  45. -- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option.
  46. -- [#51](https://github.com/xmrig/xmrig-amd/issues/51) Fixed multiple pools in initial config was saved incorrectly.
  47. -- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly.
  48. -
  49. -# v2.4.5
  50. - - [#49](https://github.com/xmrig/xmrig-amd/issues/49) Fixed, in some cases, pause was cause an infinite loop.
  51. - - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout.
  52. - - Added libmicrohttpd version to --version output.
  53. - - Fixed bug in singal handler, in some cases miner wasn't shutdown properly.
  54. - - Fixed recent MSVC 2017 version detection.
  55. -
  56. -# v2.4.3-beta2
  57. - - Fixed, auto config wasn't write opencl-platform to config.json.
  58. - - Added command line option `--print-platforms`.
  59. - - Fixed 32 bit build.
  60. - - [#2](https://github.com/xmrig/xmrig-amd/issues/2) Fixed Linux build.
  61. - - [#3](https://github.com/xmrig/xmrig-amd/issues/3) Fixed macOS build.
  62. -
  63. -# v2.4.3-beta1
  64. - - First public release.
  65. diff --git a/CMakeLists.txt b/CMakeLists.txt
  66. index 282288e..941db55 100644
  67. --- a/CMakeLists.txt
  68. +++ b/CMakeLists.txt
  69. @@ -1,5 +1,6 @@
  70.  cmake_minimum_required(VERSION 2.8)
  71. -project(xmrig-amd)
  72. +
  73. +project(xrig)
  74.  
  75.  option(WITH_AEON  "CryptoNight-Lite support" ON)
  76.  option(WITH_HTTPD "HTTP REST API" ON)
  77. @@ -8,7 +9,9 @@ include (CheckIncludeFile)
  78.  
  79.  
  80.  set(HEADERS
  81. +    src/3rdparty/align.h
  82.      src/amd/cryptonight.h
  83. +    src/amd/Adl.h
  84.      src/amd/GpuContext.h
  85.      src/amd/OclCLI.h
  86.      src/amd/OclGPU.h
  87. @@ -29,8 +32,8 @@ set(HEADERS
  88.      src/log/FileLog.h
  89.      src/log/Log.h
  90.      src/net/Client.h
  91. -    src/net/Id.h
  92.      src/net/Job.h
  93. +    src/net/JobId.h
  94.      src/net/JobResult.h
  95.      src/net/Network.h
  96.      src/net/strategies/DonateStrategy.h
  97. @@ -47,7 +50,6 @@ set(HEADERS
  98.      src/workers/OclThread.h
  99.      src/workers/OclWorker.h
  100.      src/workers/Workers.h
  101. -    src/xmrig.h
  102.     )
  103.  
  104.  set(HEADERS_CRYPTO
  105. @@ -84,6 +86,7 @@ set(SOURCES
  106.      src/net/strategies/SinglePoolStrategy.cpp
  107.      src/net/SubmitResult.cpp
  108.      src/net/Url.cpp
  109. +    src/amd/Adl.cpp
  110.      src/amd/OclCLI.cpp
  111.      src/amd/OclGPU.cpp
  112.      src/Options.cpp
  113. @@ -94,7 +97,7 @@ set(SOURCES
  114.      src/workers/Handle.cpp
  115.      src/workers/Hashrate.cpp
  116.      src/workers/Workers.cpp
  117. -    src/xmrig.cpp
  118. +    src/xrig.cpp
  119.     )
  120.  
  121.  set(SOURCES_CRYPTO
  122. @@ -132,7 +135,6 @@ else()
  123.      set(EXTRA_LIBS pthread)
  124.  endif()
  125.  
  126. -add_definitions(/DXMRIG_AMD_PROJECT)
  127.  add_definitions(/DUNICODE)
  128.  add_definitions(/DXMRIG_NO_LIBCPUID)
  129.  add_definitions(/D__STDC_FORMAT_MACROS)
  130. @@ -143,6 +145,10 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
  131.  
  132.  find_package(UV REQUIRED)
  133.  
  134. +if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
  135. +    set(CMAKE_BUILD_TYPE Release)
  136. +endif()
  137. +
  138.  include(cmake/flags.cmake)
  139.  include(cmake/OpenCL.cmake)
  140.  
  141. diff --git a/Dockerfile b/Dockerfile
  142. new file mode 100644
  143. index 0000000..e199a7b
  144. --- /dev/null
  145. +++ b/Dockerfile
  146. @@ -0,0 +1,15 @@
  147. +FROM ubuntu:xenial
  148. +
  149. +# Install utilities
  150. +RUN apt-get update --fix-missing && apt-get -y upgrade &&\
  151. +apt-get install -y build-essential cmake ocl-icd-opencl-dev libuv1-dev libmicrohttpd-dev
  152. +
  153. +# Copy files
  154. +COPY src /src/
  155. +COPY res /res/
  156. +COPY cmake /cmake/
  157. +COPY build.sh /
  158. +COPY CMakeLists.txt /
  159. +RUN chmod +x build.sh
  160. +
  161. +RUN sh build.sh
  162. diff --git a/README.md b/README.md
  163. index 7bb62e6..aa1dcc1 100644
  164. --- a/README.md
  165. +++ b/README.md
  166. @@ -1,94 +1,216 @@
  167. -# XMRig AMD
  168. +| Platform | Build Status |
  169. +| --- | --- |
  170. +| Linux | [![Build Status](https://travis-ci.org/arnesson/xrig.svg?branch=master)](https://travis-ci.org/arnesson/xrig) |
  171. +| Win64 | [![Build Status](https://ci.appveyor.com/api/projects/status/github/arnesson/xrig?branch=master&svg=true)](https://ci.appveyor.com/project/arnesson/xrig) |
  172.  
  173. -:warning: **You must update miners to version 2.5 before April 6 due [Monero PoW change](https://getmonero.org/2018/02/11/PoW-change-and-key-reuse.html).**
  174.  
  175. -[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig-amd/total.svg)](https://github.com/xmrig/xmrig-amd/releases)
  176. -[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig-amd/all.svg)](https://github.com/xmrig/xmrig-amd/releases)
  177. -[![GitHub Release Date](https://img.shields.io/github/release-date-pre/xmrig/xmrig-amd.svg)](https://github.com/xmrig/xmrig-amd/releases)
  178. -[![GitHub license](https://img.shields.io/github/license/xmrig/xmrig-amd.svg)](https://github.com/xmrig/xmrig-amd/blob/master/LICENSE)
  179. -[![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig-amd.svg)](https://github.com/xmrig/xmrig-amd/stargazers)
  180. -[![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig-amd.svg)](https://github.com/xmrig/xmrig-amd/network)
  181. -
  182. -XMRig is high performance Monero (XMR) OpenCL miner, with the official full Windows support.
  183. -
  184. -GPU mining part based on [Wolf9466](https://github.com/OhGodAPet) and [psychocrypt](https://github.com/psychocrypt) code.
  185. -
  186. -* This is the AMD (OpenCL) GPU mining version, there is also a [CPU version](https://github.com/xmrig/xmrig) and [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia).
  187. -* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
  188. -
  189. -:warning: Suggested values for GPU auto configuration can be not optimal or not working, you may need tweak your threads options. Please fell free open an [issue](https://github.com/xmrig/xmrig-amd/issues) if auto configuration suggest wrong values.
  190. +# Xrig
  191. +Xrig is a high performance cryptonight miner for AMD cards. Designed for large-scale use of RX Vega.
  192.  
  193. +GPU mining based on [Wolf9466](https://github.com/OhGodAPet) and [psychocrypt](https://github.com/psychocrypt) code. Forked with love from [XMRig AMD](https://github.com/xmrig/xmrig-amd).
  194. +<!--
  195.  <img src="https://i.imgur.com/TFncsi7.png" width="696" >
  196. -
  197. -#### Table of contents
  198. -* [Features](#features)
  199. -* [Download](#download)
  200. -* [Usage](#usage)
  201. -* [Build](https://github.com/xmrig/xmrig-amd/wiki/Build)
  202. -* [Donations](#donations)
  203. -* [Release checksums](#release-checksums)
  204. -* [Contacts](#contacts)
  205. -
  206. +-->
  207.  ## Features
  208. -* High performance.
  209. -* Official Windows support.
  210. -* Support for backup (failover) mining server.
  211. -* CryptoNight-Lite support for AEON.
  212. -* Automatic GPU configuration.
  213. -* Nicehash support.
  214. -* It's open source software.
  215. -
  216. -## Download
  217. -* Binary releases: https://github.com/xmrig/xmrig-amd/releases
  218. -* Git tree: https://github.com/xmrig/xmrig-amd.git
  219. -  * Clone with `git clone https://github.com/xmrig/xmrig-amd.git`  :hammer: [Build instructions](https://github.com/xmrig/xmrig-amd/wiki/Build).
  220. +* CryptoNightV7 ready
  221. +* High performance
  222. +* Designed for large-scale use of RX Vega, but will run any AMD card
  223. +* High level of automation necessary for managing many cards
  224. +* Rich API
  225. +* Hardware monitoring (fans, temperature, clock speeds, performance levels)
  226. +* OverdriveN capabilities (set your under/overclock profile in config.json - replaces Wattman and OverdriveNTool)
  227. +* Fixes the different shenanigans of mining on the Vega's (e.g. the "underclock toggle" and gpu reset)
  228. +* Windows and Linux support
  229. +* Pre-compiled binary has 1% dev donation (donation runs at start rather than after x minutes)
  230. +
  231. +## Work-in-progress
  232. +* Faster OpenCL compile time (cut startup time in half)
  233. +* Option(s) for automatic fine-tuning of each individual card during mining. This should maximize the utilization of each card and increase the hashrate over time
  234.  
  235.  ## Usage
  236. -Use [config.xmrig.com](https://config.xmrig.com/amd) to generate, edit or share configurations.
  237.  
  238.  ### Command line options
  239.  ```
  240.    -a, --algo=ALGO           cryptonight (default) or cryptonight-lite
  241.    -o, --url=URL             URL of mining server
  242. -  -O, --userpass=U:P        username:password pair for mining server
  243.    -u, --user=USERNAME       username for mining server
  244.    -p, --pass=PASSWORD       password for mining server
  245. -  -k, --keepalive           send keepalived for prevent timeout (need pool support)
  246. -  -r, --retries=N           number of times to retry before switch to backup server (default: 5)
  247. -  -R, --retry-pause=N       time to pause between retries (default: 5)
  248. -      --opencl-devices=N    list of OpenCL devices to use.
  249. -      --opencl-launch=IxW   list of launch config, intensity and worksize
  250. -      --opencl-affinity=N   affine GPU threads to a CPU
  251. -      --opencl-platform=N   OpenCL platform index
  252. -      --no-color            disable colored output
  253. -      --donate-level=N      donate level, default 5% (5 minutes in 100 minutes)
  254. -      --user-agent          set custom user-agent string for pool
  255. -  -B, --background          run the miner in the background
  256. +      --variant=N           PoW variant (defaults to -1 = automatic)
  257. +  -k, --keepalive           send keepalive to prevent timeout (needs pool support)
  258. +      --intensity=N         thread intensity
  259. +      --platform-index=N    OpenCL platform index
  260. +      --colors              enable colored output
  261. +  -b, --background          run the miner in the background
  262.    -c, --config=FILE         load a JSON-format configuration file
  263. -  -l, --log-file=FILE       log all output to a file
  264. +  -l, --log=FILE            log all output to a file
  265.        --nicehash            enable nicehash support
  266. -      --print-time=N        print hashrate report every N seconds
  267. -      --api-port=N          port for the miner API
  268. -      --api-access-token=T  access token for API
  269. -      --api-worker-id=ID    custom worker-id for API
  270. +      --port=N              port for the miner API
  271. +      --token=T             access token for API
  272. +      --id=ID               miner id (defaults to machine name)
  273.    -h, --help                display this help and exit
  274. -  -V, --version             output version information and exit
  275. +  -v, --version             output version information and exit
  276.  ```
  277.  
  278. -## Donations
  279. -Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
  280. -
  281. -* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
  282. -* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
  283. -
  284. -## Release checksums
  285. -### SHA-256
  286. +### Config file
  287. +Sample config for an array of Vega's:
  288. +```js
  289. +{
  290. +    "algo": "cryptonight",
  291. +    "intensity": 1932,
  292. +    "platform_index": 0,
  293. +    "pools": [
  294. +        {
  295. +            "url": "pool.monero.hashvault.pro:5555",
  296. +            "user": "",
  297. +            "pass": "x"
  298. +        }
  299. +    ],
  300. +    "api": {
  301. +        "port": 4444
  302. +    },
  303. +    "profile": {
  304. +        "system": [
  305. +            {"clock": 852,  "vddc": 0.9},
  306. +            {"clock": 991,  "vddc": 0.9},
  307. +            {"clock": 1084, "vddc": 0.9},
  308. +            {"clock": 1138, "vddc": 0.9},
  309. +            {"clock": 1150, "vddc": 0.9},
  310. +            {"clock": 1202, "vddc": 0.9},
  311. +            {"clock": 1350, "vddc": 0.8},
  312. +            {"clock": 1350, "vddc": 0.8}
  313. +        ],
  314. +        "memory": [
  315. +            {"clock": 167, "vddc": 0.8},
  316. +            {"clock": 500, "vddc": 0.8},
  317. +            {"clock": 700, "vddc": 0.9},
  318. +            {"clock": 950, "vddc": 0.9}
  319. +        ],
  320. +        "target_temperature": 75,
  321. +        "power_limit": 0
  322. +    }
  323. +}
  324.  ```
  325. -9587e92b84b28417427d3e3740c61ea12d86291264caf1c4634704211c030713 xmrig-amd-2.5.2-win32.zip/xmrig-amd.exe
  326. -f8f1d869e508a24188531f507f0b9f3552accc55d05ef44ee63a98184eb51f26 xmrig-amd-2.5.2-win64.zip/xmrig-amd.exe
  327. -4ffee947278e7cf5b1fc600d54984cf116cb59658329ef98c341b543770c3389 xmrig-amd-2.5.2-debug-win64/xmrig-amd.exe
  328. +Note: to change all P-states you need to have a soft powerplaytable for all cards in your registry.
  329. +
  330. +You can also configure the threads manually as usual:
  331. +```js
  332. +{
  333. +    "algo": "cryptonight",
  334. +    "platform_index": 0,
  335. +    "pools": [
  336. +        {
  337. +            "url": "pool.monero.hashvault.pro:5555",
  338. +            "user": "",
  339. +            "pass": "x"
  340. +        }
  341. +    ],
  342. +    "api": {
  343. +        "port": 4444
  344. +    },
  345. +    "threads": [
  346. +        {"index": 0, "intensity": 1932},
  347. +        {"index": 0, "intensity": 1932}
  348. +    ],
  349. +    "profile": {
  350. +        // ...
  351. +    }
  352. +}
  353.  ```
  354.  
  355. -## Contacts
  356. -* support@xmrig.com
  357. -* [reddit](https://www.reddit.com/user/XMRig/)
  358. +### Rich API in JSON format
  359. +
  360. +Example output:
  361. +```js
  362. +{
  363. +    "id": "DESKTOP-TEST",
  364. +    "version": "Xrig/0.8.0 (Windows NT 10.0; Win64; x64) libuv/1.14.1 OpenCL/2.0 libmicrohttpd/0.9.58 msvc/2017",
  365. +    "algo": "cryptonight",
  366. +    "uptime": 14729.0,
  367. +    "hashrate_10s": 11454.67,
  368. +    "hashrate_60s": 11456.87,
  369. +    "hashrate_15m": 11451.38,
  370. +    "hashrate_max": 11482.48,
  371. +    "gpus": [
  372. +        {
  373. +            "bus_id": 9,
  374. +            "adapter_index": 23,
  375. +            "device_name": "687F:C3",
  376. +            "temperature": 74,
  377. +            "core_clock": 1350,
  378. +            "memory_clock": 950,
  379. +            "fan_speed": 1934,
  380. +            "profile": {
  381. +                "system": [
  382. +                    {"clock": 852,  "vddc": 0.9},
  383. +                    {"clock": 991,  "vddc": 0.9},
  384. +                    {"clock": 1084, "vddc": 0.9},
  385. +                    {"clock": 1138, "vddc": 0.9},
  386. +                    {"clock": 1150, "vddc": 0.9},
  387. +                    {"clock": 1202, "vddc": 0.9},
  388. +                    {"clock": 1350, "vddc": 0.8},
  389. +                    {"clock": 1350, "vddc": 0.8}
  390. +                ],
  391. +                "memory": [
  392. +                    {"clock": 167, "vddc": 0.8},
  393. +                    {"clock": 500, "vddc": 0.8},
  394. +                    {"clock": 700, "vddc": 0.9},
  395. +                    {"clock": 950, "vddc": 0.9}
  396. +                ],
  397. +                "target_temperature": 75,
  398. +                "power_limit": 0
  399. +            },
  400. +            "threads": [
  401. +                {
  402. +                    "intensity": 1928,
  403. +                    "hashrate_10s": 951.86,
  404. +                    "hashrate_60s": 951.31,
  405. +                    "hashrate_15m": 949.24
  406. +                },
  407. +                {
  408. +                    "intensity": 1928,
  409. +                    "hashrate_10s": 951.39,
  410. +                    "hashrate_60s": 952.29,
  411. +                    "hashrate_15m": 951.5
  412. +                }
  413. +            ],
  414. +            "hashrate_10s": 1903.25,
  415. +            "hashrate_60s": 1903.6,
  416. +            "hashrate_15m": 1900.74
  417. +        },
  418. +        {
  419. +            // ...
  420. +        },
  421. +        {
  422. +            // ...
  423. +        },
  424. +        {
  425. +            // ...
  426. +        },
  427. +        {
  428. +            // ...
  429. +        },
  430. +        {
  431. +            // ...
  432. +        }
  433. +    ],
  434. +    "results": {
  435. +        "diff_current": 526795,
  436. +        "shares_good": 308,
  437. +        "shares_total": 321,
  438. +        "avg_time": 48,
  439. +        "hashes_total": 152108212,
  440. +        "best": [
  441. +            // ...
  442. +        ],
  443. +        "error_log": []
  444. +    },
  445. +    "connection": {
  446. +        "pool": "cryptonight.eu.nicehash.com:3355",
  447. +        "user": "******************************xR7M",
  448. +        "uptime": 7056,
  449. +        "ping": 84,
  450. +        "failures": 2,
  451. +        "error_log": []
  452. +    }
  453. +}
  454. +```
  455. diff --git a/appveyor.yml b/appveyor.yml
  456. new file mode 100644
  457. index 0000000..71ac4e0
  458. --- /dev/null
  459. +++ b/appveyor.yml
  460. @@ -0,0 +1,48 @@
  461. +# Inspired by https://github.com/clMathLibraries/clBLAS/blob/master/appveyor.yml
  462. +version: Build {build}
  463. +
  464. +skip_tags: true
  465. +
  466. +shallow_clone: true
  467. +
  468. +image: Visual Studio 2017
  469. +
  470. +platform: x64
  471. +
  472. +environment:
  473. +  global:
  474. +    OPENCL_ROOT: "%APPVEYOR_BUILD_FOLDER%\\opencl"
  475. +    OPENCL_REGISTRY: "https://www.khronos.org/registry/cl"
  476. +
  477. +init:
  478. +  - C:\"Program Files (x86)"\"Microsoft Visual Studio"\2017\Community\VC\Auxiliary\Build\vcvars64.bat
  479. +
  480. +install:
  481. +  - ps: mkdir $env:OPENCL_ROOT
  482. +  - ps: pushd $env:OPENCL_ROOT
  483. +  - ps: $opencl_registry = $env:OPENCL_REGISTRY
  484. +  # This downloads the source to the Khronos ICD library
  485. +  - git clone --depth 1 https://github.com/KhronosGroup/OpenCL-ICD-Loader.git
  486. +  - ps: mv ./OpenCL-ICD-Loader/* .
  487. +  # This downloads all the opencl header files
  488. +  # The cmake build files expect a directory called inc
  489. +  - ps: mkdir inc/CL
  490. +  - git clone --depth 1 https://github.com/KhronosGroup/OpenCL-Headers.git
  491. +  - ps: mv ./OpenCL-Headers/opencl22/CL/* inc/CL
  492. +  - ps: wget $opencl_registry/api/2.1/cl.hpp -OutFile inc/CL/cl.hpp
  493. +  # Create the static import lib in a directory called lib/x86_64, so FindOpencl() will find it
  494. +  - ps: mkdir lib/x86_64
  495. +  - ps: pushd lib/x86_64
  496. +  - cmake -G "NMake Makefiles" ../..
  497. +  - nmake
  498. +  - ps: popd
  499. +  # Create include directory with OpenCL 2.0 headers, so FindOpencl() will find it
  500. +  - ps: mkdir include/CL
  501. +  - ps: mv ./OpenCL-Headers/opencl20/CL/* include/CL
  502. +  - ps: popd
  503. +
  504. +before_build:
  505. +  - generate_sln.bat
  506. +
  507. +build_script:
  508. +  - build.bat
  509. diff --git a/build.bat b/build.bat
  510. new file mode 100644
  511. index 0000000..efab415
  512. --- /dev/null
  513. +++ b/build.bat
  514. @@ -0,0 +1,26 @@
  515. +set project_dir=%~dp0
  516. +set configuration=MinSizeRel
  517. +call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
  518. +cd %project_dir%
  519. +msbuild build\xrig.sln /p:Configuration=%configuration%
  520. +IF %ERRORLEVEL% NEQ 0 (
  521. +   EXIT /B %ERRORLEVEL%
  522. +)
  523. +xcopy libuv-1.14.1-x64\libuv.dll build\%configuration%\ /Y
  524. +xcopy devcon\devcon.exe build\%configuration%\ /Y
  525. +(
  526. +echo @echo off
  527. +echo cd %%~dp0
  528. +echo xrig.exe
  529. +echo pause
  530. +) > build\%configuration%\run.bat
  531. +(
  532. +echo @echo off
  533. +echo cd %%~dp0
  534. +echo devcon.exe disable "PCI\VEN_1002&DEV_687F"
  535. +echo timeout /t 5
  536. +echo devcon.exe enable "PCI\VEN_1002&DEV_687F"
  537. +echo timeout /t 5
  538. +echo xrig.exe
  539. +echo pause
  540. +) > build\%configuration%\run_with_reset.bat
  541. diff --git a/build.sh b/build.sh
  542. new file mode 100644
  543. index 0000000..93b9049
  544. --- /dev/null
  545. +++ b/build.sh
  546. @@ -0,0 +1,4 @@
  547. +mkdir -p build
  548. +cd build
  549. +cmake ..
  550. +make
  551. diff --git a/cmake/FindMHD.cmake b/cmake/FindMHD.cmake
  552. index 7a598e0..8505b33 100644
  553. --- a/cmake/FindMHD.cmake
  554. +++ b/cmake/FindMHD.cmake
  555. @@ -8,25 +8,15 @@
  556.  find_path(
  557.      MHD_INCLUDE_DIR
  558.      NAMES microhttpd.h
  559. -    PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
  560. -    PATH_SUFFIXES "include"
  561.      DOC "microhttpd include dir"
  562. -    NO_DEFAULT_PATH
  563.  )
  564.  
  565. -find_path(MHD_INCLUDE_DIR NAMES microhttpd.h)
  566. -
  567.  find_library(
  568.      MHD_LIBRARY
  569. -    NAMES libmicrohttpd.a microhttpd libmicrohttpd
  570. -    PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
  571. -    PATH_SUFFIXES "lib"
  572. +    NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
  573.      DOC "microhttpd library"
  574. -    NO_DEFAULT_PATH
  575.  )
  576.  
  577. -find_library(MHD_LIBRARY NAMES microhttpd libmicrohttpd)
  578. -
  579.  set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
  580.  set(MHD_LIBRARIES ${MHD_LIBRARY})
  581.  
  582. @@ -44,6 +34,6 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
  583.  endif()
  584.  
  585.  include(FindPackageHandleStandardArgs)
  586. -find_package_handle_standard_args(MHD DEFAULT_MSG MHD_LIBRARY MHD_INCLUDE_DIR)
  587. +find_package_handle_standard_args(mhd DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
  588.  mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)
  589.  
  590. diff --git a/cmake/FindUV.cmake b/cmake/FindUV.cmake
  591. index ba59d1d..147afdc 100644
  592. --- a/cmake/FindUV.cmake
  593. +++ b/cmake/FindUV.cmake
  594. @@ -1,25 +1,9 @@
  595. -find_path(
  596. -    UV_INCLUDE_DIR
  597. -    NAMES uv.h
  598. -    PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
  599. -    PATH_SUFFIXES "include"
  600. -    NO_DEFAULT_PATH
  601. -)
  602. -
  603.  find_path(UV_INCLUDE_DIR NAMES uv.h)
  604. -
  605. -find_library(
  606. -    UV_LIBRARY
  607. -    NAMES libuv.a uv libuv
  608. -    PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
  609. -    PATH_SUFFIXES "lib"
  610. -    NO_DEFAULT_PATH
  611. -)
  612. -
  613. -find_library(UV_LIBRARY NAMES libuv.a uv libuv)
  614. +find_library(UV_LIBRARY NAMES uv libuv)
  615.  
  616.  set(UV_LIBRARIES ${UV_LIBRARY})
  617.  set(UV_INCLUDE_DIRS ${UV_INCLUDE_DIR})
  618.  
  619.  include(FindPackageHandleStandardArgs)
  620.  find_package_handle_standard_args(UV DEFAULT_MSG UV_LIBRARY UV_INCLUDE_DIR)
  621. +
  622. diff --git a/cmake/flags.cmake b/cmake/flags.cmake
  623. index 4688f95..22f230a 100644
  624. --- a/cmake/flags.cmake
  625. +++ b/cmake/flags.cmake
  626. @@ -1,11 +1,3 @@
  627. -if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
  628. -    set(CMAKE_BUILD_TYPE Release)
  629. -endif()
  630. -
  631. -if (CMAKE_BUILD_TYPE STREQUAL "Release")
  632. -    add_definitions(/DNDEBUG)
  633. -endif()
  634. -
  635.  set(CMAKE_CXX_STANDARD_REQUIRED ON)
  636.  set(CMAKE_CXX_EXTENSIONS OFF)
  637.  set(CMAKE_CXX_STANDARD 11)
  638. @@ -22,6 +14,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
  639.          set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
  640.      else()
  641.          set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
  642. +        set(LIBS ${LIBS} -ldl)
  643.      endif()
  644.  
  645.      add_definitions(/D_GNU_SOURCE)
  646. diff --git a/devcon/devcon.exe b/devcon/devcon.exe
  647. new file mode 100644
  648. index 0000000..2143c53
  649. Binary files /dev/null and b/devcon/devcon.exe differ
  650. diff --git a/generate_sln.bat b/generate_sln.bat
  651. new file mode 100755
  652. index 0000000..3dc0283
  653. --- /dev/null
  654. +++ b/generate_sln.bat
  655. @@ -0,0 +1,10 @@
  656. +set project_dir=%~dp0
  657. +rd /s /q "build"
  658. +mkdir build
  659. +cd build
  660. +cmake .. -G "Visual Studio 15 2017 Win64" -DUV_INCLUDE_DIR="..\libuv-1.14.1-x64\include" -DUV_LIBRARY="..\libuv-1.14.1-x64\libuv.lib" -DMHD_INCLUDE_DIR="..\libmicrohttpd-0.9.58-w32-bin\x86_64\VS2017\Release-static" -DMHD_LIBRARY="..\libmicrohttpd-0.9.58-w32-bin\x86_64\VS2017\Release-static\libmicrohttpd.lib"
  661. +IF %ERRORLEVEL% NEQ 0 (
  662. +   cd %project_dir%
  663. +   EXIT /B %ERRORLEVEL%
  664. +)
  665. +cd %project_dir%
  666. diff --git a/res/app.ico b/res/app.ico
  667. index 8c3d628..7ab97ba 100644
  668. Binary files a/res/app.ico and b/res/app.ico differ
  669. diff --git a/res/app.rc b/res/app.rc
  670. index aa41334..9c77b53 100644
  671. --- a/res/app.rc
  672. +++ b/res/app.rc
  673. @@ -24,7 +24,7 @@ VS_VERSION_INFO VERSIONINFO
  674.          VALUE "FileDescription",  APP_DESC
  675.          VALUE "FileVersion",      APP_VERSION
  676.          VALUE "LegalCopyright",   APP_COPYRIGHT
  677. -        VALUE "OriginalFilename", "xmrig-nvidia.exe"
  678. +        VALUE "OriginalFilename", "xrig.exe"
  679.          VALUE "ProductName",      APP_NAME
  680.          VALUE "ProductVersion",   APP_VERSION
  681.        END
  682. diff --git a/src/3rdparty/align.h b/src/3rdparty/align.h
  683. new file mode 100644
  684. index 0000000..b61179b
  685. --- /dev/null
  686. +++ b/src/3rdparty/align.h
  687. @@ -0,0 +1,33 @@
  688. +/* XMRig
  689. + * Copyright 2010      Jeff Garzik <jgarzik@pobox.com>
  690. + * Copyright 2012-2014 pooler      <pooler@litecoinpool.org>
  691. + * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  692. + * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  693. + * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  694. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  695. + *
  696. + *
  697. + *   This program is free software: you can redistribute it and/or modify
  698. + *   it under the terms of the GNU General Public License as published by
  699. + *   the Free Software Foundation, either version 3 of the License, or
  700. + *   (at your option) any later version.
  701. + *
  702. + *   This program is distributed in the hope that it will be useful,
  703. + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  704. + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  705. + *   GNU General Public License for more details.
  706. + *
  707. + *   You should have received a copy of the GNU General Public License
  708. + *   along with this program. If not, see <http://www.gnu.org/licenses/>.
  709. + */
  710. +
  711. +#ifndef __ALIGN_H__
  712. +#define __ALIGN_H__
  713. +
  714. +#ifdef _MSC_VER
  715. +#   define VAR_ALIGN(x, decl) __declspec(align(x)) decl
  716. +#else
  717. +#   define VAR_ALIGN(x, decl) decl __attribute__ ((aligned(x)))
  718. +#endif
  719. +
  720. +#endif /* __ALIGN_H__ */
  721. diff --git a/src/App.cpp b/src/App.cpp
  722. index 568593a..0c02bf7 100644
  723. --- a/src/App.cpp
  724. +++ b/src/App.cpp
  725. @@ -76,8 +76,8 @@ App::App(int argc, char **argv) :
  726.          m_console = new Console(this);
  727.      }
  728.  
  729. -    if (m_options->logFile()) {
  730. -        Log::add(new FileLog(m_options->logFile()));
  731. +    if (m_options->log()) {
  732. +        Log::add(new FileLog(m_options->log()));
  733.      }
  734.  
  735.  #   ifdef HAVE_SYSLOG_H
  736. @@ -86,7 +86,7 @@ App::App(int argc, char **argv) :
  737.      }
  738.  #   endif
  739.  
  740. -    Platform::init(m_options->userAgent());
  741. +    Platform::init();
  742.  
  743.      m_network = new Network(m_options);
  744.  
  745. @@ -133,7 +133,7 @@ int App::exec()
  746.  #   endif
  747.  
  748.  #   ifndef XMRIG_NO_HTTPD
  749. -    m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken());
  750. +    m_httpd = new Httpd(m_options->port(), m_options->accessToken());
  751.      m_httpd->start();
  752.  #   endif
  753.  
  754. diff --git a/src/App_unix.cpp b/src/App_unix.cpp
  755. index 5c8c3f6..bffca08 100644
  756. --- a/src/App_unix.cpp
  757. +++ b/src/App_unix.cpp
  758. @@ -4,8 +4,8 @@
  759.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  760.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  761.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  762. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  763. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  764. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  765. + *
  766.   *
  767.   *   This program is free software: you can redistribute it and/or modify
  768.   *   it under the terms of the GNU General Public License as published by
  769. @@ -36,8 +36,6 @@
  770.  
  771.  void App::background()
  772.  {
  773. -    signal(SIGPIPE, SIG_IGN);
  774. -
  775.      if (!m_options->background()) {
  776.          return;
  777.      }
  778. diff --git a/src/Options.cpp b/src/Options.cpp
  779. index 3355cf6..c0b173e 100644
  780. --- a/src/Options.cpp
  781. +++ b/src/Options.cpp
  782. @@ -6,6 +6,7 @@
  783.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  784.   * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  785.   * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  786. +
  787.   *
  788.   *   This program is free software: you can redistribute it and/or modify
  789.   *   it under the terms of the GNU General Public License as published by
  790. @@ -32,15 +33,14 @@
  791.  #   include <getopt.h>
  792.  #endif
  793.  
  794. -
  795.  #ifndef XMRIG_NO_HTTPD
  796.  #   include <microhttpd.h>
  797.  #endif
  798.  
  799.  
  800. +#include "amd/Adl.h"
  801.  #include "amd/OclGPU.h"
  802.  #include "Cpu.h"
  803. -#include "donate.h"
  804.  #include "log/Log.h"
  805.  #include "net/Url.h"
  806.  #include "Options.h"
  807. @@ -52,7 +52,6 @@
  808.  #include "rapidjson/prettywriter.h"
  809.  #include "version.h"
  810.  #include "workers/OclThread.h"
  811. -#include "xmrig.h"
  812.  
  813.  
  814.  #ifndef ARRAY_SIZE
  815. @@ -69,87 +68,63 @@ Usage: " APP_ID " [OPTIONS]\n\
  816.  Options:\n\
  817.    -a, --algo=ALGO           cryptonight (default) or cryptonight-lite\n\
  818.    -o, --url=URL             URL of mining server\n\
  819. -  -O, --userpass=U:P        username:password pair for mining server\n\
  820.    -u, --user=USERNAME       username for mining server\n\
  821.    -p, --pass=PASSWORD       password for mining server\n\
  822. -  -k, --keepalive           send keepalived for prevent timeout (need pool support)\n\
  823. -  -r, --retries=N           number of times to retry before switch to backup server (default: 5)\n\
  824. -  -R, --retry-pause=N       time to pause between retries (default: 5)\n\
  825. -      --opencl-devices=N    list of OpenCL devices to use.\n\
  826. -      --opencl-launch=IxW   list of launch config, intensity and worksize\n\
  827. -      --opencl-affinity=N   affine GPU threads to a CPU\n\
  828. -      --opencl-platform=N   OpenCL platform index\n\
  829. -      --print-platforms     print available OpenCL platforms and exit\n\
  830. -      --no-color            disable colored output\n\
  831. -      --variant             algorithm PoW variant\n\
  832. -      --donate-level=N      donate level, default 5%% (5 minutes in 100 minutes)\n\
  833. -      --user-agent          set custom user-agent string for pool\n\
  834. -  -B, --background          run the miner in the background\n\
  835. +      --variant=N           PoW variant (defaults to -1 = automatic)\n\
  836. +  -k, --keepalive           send keepalive to prevent timeout (needs pool support)\n\
  837. +      --intensity=N         thread intensity\n\
  838. +      --platform-index=N    OpenCL platform index\n\
  839. +  -b, --background          run the miner in the background\n\
  840.    -c, --config=FILE         load a JSON-format configuration file\n\
  841. -  -l, --log-file=FILE       log all output to a file\n"
  842. +  -l, --log=FILE            log all output to a file\n"
  843.  # ifdef HAVE_SYSLOG_H
  844.  "\
  845. -  -S, --syslog              use system log for output messages\n"
  846. +  -s, --syslog              use system log for output messages\n"
  847.  # endif
  848.  "\
  849.        --nicehash            enable nicehash support\n\
  850. -      --print-time=N        print hashrate report every N seconds\n\
  851. -      --api-port=N          port for the miner API\n\
  852. -      --api-access-token=T  access token for API\n\
  853. -      --api-worker-id=ID    custom worker-id for API\n\
  854. +      --port=N              port for the miner API\n\
  855. +      --token=T             access token for API\n\
  856. +      --id=ID               miner id (defaults to machine name)\n\
  857.    -h, --help                display this help and exit\n\
  858. -  -V, --version             output version information and exit\n\
  859. +  -v, --version             output version information and exit\n\
  860.  ";
  861.  
  862.  
  863. -static char const short_options[] = "a:c:khBp:Px:r:R:s:T:o:u:O:Vl:S";
  864. +static char const short_options[] = "a:c:khbp:o:u:vl:s";
  865.  
  866.  
  867.  static struct option const options[] = {
  868.      { "algo",             1, nullptr, 'a'  },
  869. -    { "api-access-token", 1, nullptr, 4001 },
  870. -    { "api-port",         1, nullptr, 4000 },
  871. -    { "api-worker-id",    1, nullptr, 4002 },
  872. -    { "background",       0, nullptr, 'B'  },
  873. +    { "token",            1, nullptr, 4001 },
  874. +    { "port",             1, nullptr, 4000 },
  875. +    { "id",               1, nullptr, 4002 },
  876. +    { "background",       0, nullptr, 'b'  },
  877.      { "config",           1, nullptr, 'c'  },
  878. -    { "donate-level",     1, nullptr, 1003 },
  879.      { "help",             0, nullptr, 'h'  },
  880.      { "keepalive",        0, nullptr ,'k'  },
  881. -    { "log-file",         1, nullptr, 'l'  },
  882. +    { "log",              1, nullptr, 'l'  },
  883.      { "nicehash",         0, nullptr, 1006 },
  884.      { "no-color",         0, nullptr, 1002 },
  885.      { "variant",          1, nullptr, 1010 },
  886. -    { "opencl-affinity",  1, nullptr, 1401 },
  887. -    { "opencl-devices",   1, nullptr, 1402 },
  888. -    { "opencl-launch",    1, nullptr, 1403 },
  889. -    { "opencl-platform",  1, nullptr, 1400 },
  890. +    { "intensity",        1, nullptr, 1401 },
  891. +    { "platform-index",   1, nullptr, 1400 },
  892.      { "pass",             1, nullptr, 'p'  },
  893. -    { "print-platforms",  0, nullptr, 1404 },
  894. -    { "print-time",       1, nullptr, 1007 },
  895. -    { "retries",          1, nullptr, 'r'  },
  896. -    { "retry-pause",      1, nullptr, 'R'  },
  897. -    { "syslog",           0, nullptr, 'S'  },
  898. +    { "syslog",           0, nullptr, 's'  },
  899.      { "url",              1, nullptr, 'o'  },
  900.      { "user",             1, nullptr, 'u'  },
  901. -    { "user-agent",       1, nullptr, 1008 },
  902. -    { "userpass",         1, nullptr, 'O'  },
  903. -    { "version",          0, nullptr, 'V'  },
  904. +    { "version",          0, nullptr, 'v'  },
  905.      { 0, 0, 0, 0 }
  906.  };
  907.  
  908.  
  909.  static struct option const config_options[] = {
  910.      { "algo",             1, nullptr, 'a'  },
  911. -    { "background",       0, nullptr, 'B'  },
  912. -    { "colors",           0, nullptr, 2000 },
  913. -    { "donate-level",     1, nullptr, 1003 },
  914. -    { "log-file",         1, nullptr, 'l'  },
  915. -    { "opencl-platform",  1, nullptr, 1400 },
  916. -    { "print-time",       1, nullptr, 1007 },
  917. -    { "retries",          1, nullptr, 'r'  },
  918. -    { "retry-pause",      1, nullptr, 'R'  },
  919. -    { "syslog",           0, nullptr, 'S'  },
  920. -    { "user-agent",       1, nullptr, 1008 },
  921. +    { "background",       0, nullptr, 'b'  },
  922. +    { "log",              1, nullptr, 'l'  },
  923. +    { "platform_index",   1, nullptr, 1400 },
  924. +    { "intensity",        1, nullptr, 1401 },
  925. +    { "syslog",           0, nullptr, 's'  },
  926.      { 0, 0, 0, 0 }
  927.  };
  928.  
  929. @@ -158,7 +133,6 @@ static struct option const pool_options[] = {
  930.      { "url",           1, nullptr, 'o'  },
  931.      { "pass",          1, nullptr, 'p'  },
  932.      { "user",          1, nullptr, 'u'  },
  933. -    { "userpass",      1, nullptr, 'O'  },
  934.      { "keepalive",     0, nullptr ,'k'  },
  935.      { "nicehash",      0, nullptr, 1006 },
  936.      { "variant",       1, nullptr, 1010 },
  937. @@ -168,8 +142,16 @@ static struct option const pool_options[] = {
  938.  
  939.  static struct option const api_options[] = {
  940.      { "port",          1, nullptr, 4000 },
  941. -    { "access-token",  1, nullptr, 4001 },
  942. -    { "worker-id",     1, nullptr, 4002 },
  943. +    { "token",         1, nullptr, 4001 },
  944. +    { "id",            1, nullptr, 4002 },
  945. +    { 0, 0, 0, 0 }
  946. +};
  947. +
  948. +static struct option const profile_options[] = {
  949. +    { "system",               1, nullptr, 5000 },
  950. +    { "memory",               1, nullptr, 5001 },
  951. +    { "target_temperature",   1, nullptr, 5002 },
  952. +    { "power_limit",          1, nullptr, 5003 },
  953.      { 0, 0, 0, 0 }
  954.  };
  955.  
  956. @@ -197,110 +179,16 @@ Options *Options::parse(int argc, char **argv)
  957.  
  958.  bool Options::oclInit()
  959.  {
  960. -    LOG_WARN("compiling code and initializing GPUs. This will take a while...");
  961. +    LOG_WARN("Compiling code and initializing GPUs...");
  962.  
  963.      if (m_threads.empty() && !m_oclCLI.setup(m_threads)) {
  964. -        m_autoConf   = true;
  965. -        m_shouldSave = true;
  966. -        m_oclCLI.autoConf(m_threads, &m_platformIndex);
  967. +        m_oclCLI.autoConf(m_threads, &m_platformIndex, &m_intensity);
  968.      }
  969.  
  970.      return true;
  971.  }
  972.  
  973.  
  974. -bool Options::save()
  975. -{
  976. -    if (!m_shouldSave || m_configName == nullptr) {
  977. -        return false;
  978. -    }
  979. -
  980. -    uv_fs_t req;
  981. -    const int fd = uv_fs_open(uv_default_loop(), &req, m_configName, O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr);
  982. -    if (fd < 0) {
  983. -        return false;
  984. -    }
  985. -
  986. -    uv_fs_req_cleanup(&req);
  987. -
  988. -    rapidjson::Document doc;
  989. -    doc.SetObject();
  990. -
  991. -    auto &allocator = doc.GetAllocator();
  992. -
  993. -    doc.AddMember("algo",         rapidjson::StringRef(algoName()), allocator);
  994. -    doc.AddMember("background",   m_background, allocator);
  995. -    doc.AddMember("colors",       m_colors, allocator);
  996. -    doc.AddMember("donate-level", m_donateLevel, allocator);
  997. -    doc.AddMember("log-file",     m_logFile ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
  998. -    doc.AddMember("print-time",   m_printTime, allocator);
  999. -    doc.AddMember("retries",      m_retries, allocator);
  1000. -    doc.AddMember("retry-pause",  m_retryPause, allocator);
  1001. -
  1002. -#   ifdef HAVE_SYSLOG_H
  1003. -    doc.AddMember("syslog", m_syslog, allocator);
  1004. -#   endif
  1005. -
  1006. -    doc.AddMember("opencl-platform", m_platformIndex, allocator);
  1007. -
  1008. -    rapidjson::Value threads(rapidjson::kArrayType);
  1009. -    for (const OclThread *thread : m_threads) {
  1010. -        rapidjson::Value obj(rapidjson::kObjectType);
  1011. -
  1012. -        obj.AddMember("index",     (uint64_t) thread->index(), allocator);
  1013. -        obj.AddMember("intensity", (uint64_t) thread->intensity(), allocator);
  1014. -        obj.AddMember("worksize",  (uint64_t) thread->worksize(), allocator);
  1015. -
  1016. -        if (thread->affinity() >= 0) {
  1017. -            obj.AddMember("affine_to_cpu", thread->affinity(), allocator);
  1018. -        }
  1019. -        else {
  1020. -            obj.AddMember("affine_to_cpu", false, allocator);
  1021. -        }
  1022. -
  1023. -        threads.PushBack(obj, allocator);
  1024. -    }
  1025. -
  1026. -    rapidjson::Value pools(rapidjson::kArrayType);
  1027. -
  1028. -    for (const Url *url : m_pools) {
  1029. -        rapidjson::Value obj(rapidjson::kObjectType);
  1030. -        obj.AddMember("url",       rapidjson::StringRef(url->url()), allocator);
  1031. -        obj.AddMember("user",      rapidjson::StringRef(url->user()), allocator);
  1032. -        obj.AddMember("pass",      rapidjson::StringRef(url->password()), allocator);
  1033. -        obj.AddMember("keepalive", url->isKeepAlive(), allocator);
  1034. -        obj.AddMember("nicehash",  url->isNicehash(), allocator);
  1035. -        obj.AddMember("variant",   url->variant(), allocator);
  1036. -
  1037. -        pools.PushBack(obj, allocator);
  1038. -    }
  1039. -
  1040. -    rapidjson::Value api(rapidjson::kObjectType);
  1041. -    api.AddMember("port",         m_apiPort, allocator);
  1042. -    api.AddMember("access-token", m_apiToken ? rapidjson::Value(rapidjson::StringRef(m_apiToken)).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
  1043. -    api.AddMember("worker-id",    m_apiWorkerId ? rapidjson::Value(rapidjson::StringRef(m_apiWorkerId)).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator);
  1044. -
  1045. -    doc.AddMember("threads", threads, allocator);
  1046. -    doc.AddMember("pools",   pools, allocator);
  1047. -    doc.AddMember("api",     api, allocator);
  1048. -
  1049. -    FILE *fp = fdopen(fd, "w");
  1050. -
  1051. -    char buf[4096];
  1052. -    rapidjson::FileWriteStream os(fp, buf, sizeof(buf));
  1053. -    rapidjson::PrettyWriter<rapidjson::FileWriteStream> writer(os);
  1054. -    doc.Accept(writer);
  1055. -
  1056. -    fclose(fp);
  1057. -
  1058. -    uv_fs_close(uv_default_loop(), &req, fd, nullptr);
  1059. -    uv_fs_req_cleanup(&req);
  1060. -
  1061. -    LOG_NOTICE("Configuration saved to: %s", configName());
  1062. -    return true;
  1063. -}
  1064. -
  1065. -
  1066.  const char *Options::algoName() const
  1067.  {
  1068.      return algo_names[m_algo];
  1069. @@ -308,26 +196,24 @@ const char *Options::algoName() const
  1070.  
  1071.  
  1072.  Options::Options(int argc, char **argv) :
  1073. -    m_autoConf(false),
  1074.      m_background(false),
  1075.      m_colors(true),
  1076.      m_ready(false),
  1077. -    m_shouldSave(false),
  1078.      m_syslog(false),
  1079. -    m_apiToken(nullptr),
  1080. -    m_apiWorkerId(nullptr),
  1081. -    m_configName(nullptr),
  1082. -    m_logFile(nullptr),
  1083. -    m_userAgent(nullptr),
  1084. +    m_accessToken(nullptr),
  1085. +    m_id(nullptr),
  1086. +    m_config(nullptr),
  1087. +    m_log(nullptr),
  1088.      m_algo(0),
  1089.      m_algoVariant(0),
  1090. -    m_apiPort(0),
  1091. -    m_donateLevel(kDonateLevel),
  1092. +    m_port(0),
  1093. +    m_intensity(0),
  1094.      m_platformIndex(0),
  1095. -    m_printTime(60),
  1096. -    m_retries(5),
  1097. -    m_retryPause(5),
  1098. -    m_threads(0)
  1099. +    m_threads(0),
  1100. +    m_systemClocks(0),
  1101. +    m_memoryClocks(0),
  1102. +    m_targetTemperature(0),
  1103. +    m_powerLimit(0)
  1104.  {
  1105.      m_pools.push_back(new Url());
  1106.  
  1107. @@ -350,17 +236,20 @@ Options::Options(int argc, char **argv) :
  1108.      }
  1109.  
  1110.      if (!m_pools[0]->isValid()) {
  1111. -        parseConfig(Platform::defaultConfigName());
  1112. +        parseConfig(Platform::defaultConfig());
  1113.      }
  1114.  
  1115.      if (!m_pools[0]->isValid()) {
  1116. -        fprintf(stderr, "No pool URL supplied. Exiting.\n");
  1117. -        return;
  1118. +        Url *url = new Url("cryptonight.eu.nicehash.com", 3355, "3EXnQ9TLnco6hqjL8S7685YF7mgkaN4LFq", nullptr, false, true);
  1119. +        m_pools[0] = url;
  1120.      }
  1121.  
  1122.      m_algoVariant = Cpu::hasAES() ? AV1_AESNI : AV3_SOFT_AES;
  1123.  
  1124. -    adjust();
  1125. +    for (Url *url : m_pools) {
  1126. +        url->setAlgo(m_algo);
  1127. +        url->applyExceptions();
  1128. +    }
  1129.  
  1130.      m_ready = true;
  1131.  }
  1132. @@ -428,12 +317,6 @@ bool Options::parseArg(int key, const char *arg)
  1133.          }
  1134.          break;
  1135.  
  1136. -    case 'O': /* --userpass */
  1137. -        if (!m_pools.back()->setUserpass(arg)) {
  1138. -            return false;
  1139. -        }
  1140. -        break;
  1141. -
  1142.      case 'u': /* --user */
  1143.          m_pools.back()->setUser(arg);
  1144.          break;
  1145. @@ -442,56 +325,36 @@ bool Options::parseArg(int key, const char *arg)
  1146.          m_pools.back()->setPassword(arg);
  1147.          break;
  1148.  
  1149. -    case 'l': /* --log-file */
  1150. -        free(m_logFile);
  1151. -        m_logFile = strdup(arg);
  1152. -        m_colors = false;
  1153. -        break;
  1154. -
  1155. -    case 4001: /* --access-token */
  1156. -        free(m_apiToken);
  1157. -        m_apiToken = strdup(arg);
  1158. -        break;
  1159. -
  1160. -    case 4002: /* --worker-id */
  1161. -        free(m_apiWorkerId);
  1162. -        m_apiWorkerId = strdup(arg);
  1163. +    case 'l': /* --log */
  1164. +        free(m_log);
  1165. +        m_log = strdup(arg);
  1166.          break;
  1167.  
  1168. -    case 1402: /* --opencl-devices */
  1169. -        m_oclCLI.parseDevices(arg);
  1170. +    case 4001: /* --token */
  1171. +        free(m_accessToken);
  1172. +        m_accessToken = strdup(arg);
  1173.          break;
  1174.  
  1175. -    case 1403: /* --opencl-launch */
  1176. -        m_oclCLI.parseLaunch(arg);
  1177. +    case 4002: /* --id */
  1178. +        free(m_id);
  1179. +        m_id = strdup(arg);
  1180.          break;
  1181.  
  1182. -    case 1401: /* --opencl-affinity */
  1183. -        m_oclCLI.parseAffinity(arg);
  1184. -        break;
  1185. +    case 4000: /* --port */
  1186. +    case 1400: /* --platform-index */
  1187. +    case 1401: /* --intensity */
  1188. +        return parseArg(key, (uint64_t) strtol(arg, nullptr, 10));
  1189.  
  1190. -    case 'r':  /* --retries */
  1191. -    case 'R':  /* --retry-pause */
  1192. -    case 't':  /* --threads */
  1193. -    case 'v':  /* --av */
  1194. -    case 1003: /* --donate-level */
  1195. -    case 1007: /* --print-time */
  1196. -    case 4000: /* --api-port */
  1197. -    case 1400: /* --opencl-platform */
  1198.      case 1010: /* --variant */
  1199. -        return parseArg(key, strtol(arg, nullptr, 10));
  1200. +        return parseArg(key, (int64_t) strtol(arg, nullptr, 10));
  1201.  
  1202. -    case 'B':  /* --background */
  1203. +    case 'b':  /* --background */
  1204.      case 'k':  /* --keepalive */
  1205. -    case 'S':  /* --syslog */
  1206. -    case 1005: /* --safe */
  1207. +    case 's':  /* --syslog */
  1208.      case 1006: /* --nicehash */
  1209.          return parseBoolean(key, true);
  1210.  
  1211. -    case 1002: /* --no-color */
  1212. -        return parseBoolean(key, false);
  1213. -
  1214. -    case 'V': /* --version */
  1215. +    case 'v': /* --version */
  1216.          showVersion();
  1217.          return false;
  1218.  
  1219. @@ -499,19 +362,10 @@ bool Options::parseArg(int key, const char *arg)
  1220.          showUsage(0);
  1221.          return false;
  1222.  
  1223. -    case 1404: /* --print-platforms */
  1224. -        printPlatforms();
  1225. -        return false;
  1226. -
  1227.      case 'c': /* --config */
  1228.          parseConfig(arg);
  1229.          break;
  1230.  
  1231. -    case 1008: /* --user-agent */
  1232. -        free(m_userAgent);
  1233. -        m_userAgent = strdup(arg);
  1234. -        break;
  1235. -
  1236.      default:
  1237.          showUsage(1);
  1238.          return false;
  1239. @@ -524,64 +378,28 @@ bool Options::parseArg(int key, const char *arg)
  1240.  bool Options::parseArg(int key, uint64_t arg)
  1241.  {
  1242.      switch (key) {
  1243. -        case 'r': /* --retries */
  1244. -        if (arg < 1 || arg > 1000) {
  1245. -            showUsage(1);
  1246. -            return false;
  1247. -        }
  1248. -
  1249. -        m_retries = (int) arg;
  1250. -        break;
  1251. -
  1252. -    case 'R': /* --retry-pause */
  1253. -        if (arg < 1 || arg > 3600) {
  1254. -            showUsage(1);
  1255. -            return false;
  1256. -        }
  1257. -
  1258. -        m_retryPause = (int) arg;
  1259. -        break;
  1260. -
  1261. -    case 't': /* --threads */
  1262. -        if (arg < 1 || arg > 1024) {
  1263. -            showUsage(1);
  1264. -            return false;
  1265. -        }
  1266. -
  1267. -        //m_threads = arg;
  1268. -        break;
  1269. -
  1270. -    case 1003: /* --donate-level */
  1271. -        if (arg < 1 || arg > 99) {
  1272. -            return true;
  1273. -        }
  1274. -
  1275. -        m_donateLevel = (int) arg;
  1276. -        break;
  1277. -
  1278. -    case 1007: /* --print-time */
  1279. -        if (arg > 1000) {
  1280. -            showUsage(1);
  1281. -            return false;
  1282. -        }
  1283. -
  1284. -        m_printTime = (int) arg;
  1285. -        break;
  1286. -
  1287.      case 1010: /* --variant */
  1288.          m_pools.back()->setVariant((int) arg);
  1289.          break;
  1290.  
  1291. -    case 1400: /* --opencl-platform */
  1292. +    case 1400: /* --platform-index */
  1293.          m_platformIndex = (int) arg;
  1294.          break;
  1295.  
  1296. -    case 4000: /* --api-port */
  1297. +    case 1401: /* --intensity */
  1298. +        m_intensity = (size_t) arg;
  1299. +        break;
  1300. +
  1301. +    case 4000: /* --port */
  1302.          if (arg <= 65536) {
  1303. -            m_apiPort = (int) arg;
  1304. +            m_port = (int) arg;
  1305.          }
  1306.          break;
  1307.  
  1308. +    case 5002: /* profile.target_temperature */
  1309. +        m_targetTemperature = (int) arg;
  1310. +        break;
  1311. +
  1312.      default:
  1313.          break;
  1314.      }
  1315. @@ -590,6 +408,21 @@ bool Options::parseArg(int key, uint64_t arg)
  1316.  }
  1317.  
  1318.  
  1319. +bool Options::parseArg(int key, int64_t arg)
  1320. +{
  1321. +   switch (key) {
  1322. +   case 5003: /* profile.power_limit */
  1323. +       m_powerLimit = (int)arg;
  1324. +       break;
  1325. +      
  1326. +   default:
  1327. +       break;
  1328. +   }
  1329. +
  1330. +   return true;
  1331. +}
  1332. +
  1333. +
  1334.  bool Options::parseBoolean(int key, bool enable)
  1335.  {
  1336.      switch (key) {
  1337. @@ -597,28 +430,18 @@ bool Options::parseBoolean(int key, bool enable)
  1338.          m_pools.back()->setKeepAlive(enable);
  1339.          break;
  1340.  
  1341. -    case 'B': /* --background */
  1342. +    case 'b': /* --background */
  1343.          m_background = enable;
  1344. -        m_colors = enable ? false : m_colors;
  1345.          break;
  1346.  
  1347. -    case 'S': /* --syslog */
  1348. +    case 's': /* --syslog */
  1349.          m_syslog = enable;
  1350. -        m_colors = enable ? false : m_colors;
  1351. -        break;
  1352. -
  1353. -    case 1002: /* --no-color */
  1354. -        m_colors = enable;
  1355.          break;
  1356.  
  1357.      case 1006: /* --nicehash */
  1358.          m_pools.back()->setNicehash(enable);
  1359.          break;
  1360.  
  1361. -    case 2000: /* colors */
  1362. -        m_colors = enable;
  1363. -        break;
  1364. -
  1365.      default:
  1366.          break;
  1367.      }
  1368. @@ -639,14 +462,6 @@ Url *Options::parseUrl(const char *arg) const
  1369.  }
  1370.  
  1371.  
  1372. -void Options::adjust()
  1373. -{
  1374. -    for (Url *url : m_pools) {
  1375. -        url->adjust(m_algo);
  1376. -    }
  1377. -}
  1378. -
  1379. -
  1380.  void Options::parseConfig(const char *fileName)
  1381.  {
  1382.      rapidjson::Document doc;
  1383. @@ -654,7 +469,7 @@ void Options::parseConfig(const char *fileName)
  1384.          return;
  1385.      }
  1386.  
  1387. -    m_configName = strdup(fileName);
  1388. +    m_config = strdup(fileName);
  1389.  
  1390.      for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) {
  1391.          parseJSON(&config_options[i], doc);
  1392. @@ -674,7 +489,7 @@ void Options::parseConfig(const char *fileName)
  1393.      }
  1394.  
  1395.      const rapidjson::Value &threads = doc["threads"];
  1396. -    if (pools.IsArray()) {
  1397. +    if (threads.IsArray()) {
  1398.          for (const rapidjson::Value &value : threads.GetArray()) {
  1399.              if (!value.IsObject()) {
  1400.                  continue;
  1401. @@ -690,6 +505,45 @@ void Options::parseConfig(const char *fileName)
  1402.              parseJSON(&api_options[i], api);
  1403.          }
  1404.      }
  1405. +
  1406. +    const rapidjson::Value &profile = doc["profile"];
  1407. +    if (profile.IsObject()) {
  1408. +        for (size_t i = 0; i < ARRAY_SIZE(profile_options); i++) {
  1409. +            parseProfile(&profile_options[i], profile);
  1410. +        }
  1411. +    }
  1412. +}
  1413. +
  1414. +
  1415. +void Options::parseProfile(const struct option *option, const rapidjson::Value &object)
  1416. +{
  1417. +    if (!option->name || !object.HasMember(option->name)) {
  1418. +        return;
  1419. +    }
  1420. +
  1421. +    const rapidjson::Value &value = object[option->name];
  1422. +
  1423. +    if (option->has_arg && value.IsArray()) {
  1424. +        for (const rapidjson::Value &level : value.GetArray()) {
  1425. +            if (!level.IsObject()) {
  1426. +                continue;
  1427. +            }
  1428. +
  1429. +            parseLevel(option->val, level);
  1430. +        }
  1431. +    }
  1432. +    else if (option->has_arg && value.IsString()) {
  1433. +        parseArg(option->val, value.GetString());
  1434. +    }
  1435. +    else if (option->has_arg && value.IsUint64()) {
  1436. +        parseArg(option->val, value.GetUint64());
  1437. +   }
  1438. +   else if (option->has_arg && value.IsInt64()) {
  1439. +       parseArg(option->val, value.GetInt64());
  1440. +   }
  1441. +    else if (!option->has_arg && value.IsBool()) {
  1442. +        parseBoolean(option->val, value.IsTrue());
  1443. +    }
  1444.  }
  1445.  
  1446.  
  1447. @@ -704,21 +558,61 @@ void Options::parseJSON(const struct option *option, const rapidjson::Value &obj
  1448.      if (option->has_arg && value.IsString()) {
  1449.          parseArg(option->val, value.GetString());
  1450.      }
  1451. -    else if (option->has_arg && value.IsInt64()) {
  1452. +    else if (option->has_arg && value.IsUint64()) {
  1453.          parseArg(option->val, value.GetUint64());
  1454.      }
  1455. +    else if (option->has_arg && value.IsInt64()) {
  1456. +        parseArg(option->val, value.GetInt64());
  1457. +    }
  1458.      else if (!option->has_arg && value.IsBool()) {
  1459.          parseBoolean(option->val, value.IsTrue());
  1460.      }
  1461.  }
  1462.  
  1463.  
  1464. +void Options::parseLevel(int key, const rapidjson::Value &object)
  1465. +{
  1466. +    ADLODNPerformanceLevelX2 *odNPerformanceLevel = new ADLODNPerformanceLevelX2();
  1467. +
  1468. +    const rapidjson::Value &clock = object["clock"];
  1469. +    if (clock.IsInt()) {
  1470. +        odNPerformanceLevel->iClock = clock.GetInt() * 100;
  1471. +    }
  1472. +
  1473. +    const rapidjson::Value &vddc = object["vddc"];
  1474. +    if (vddc.IsDouble()) {
  1475. +        odNPerformanceLevel->iVddc = (int) (vddc.GetDouble() * 1000);
  1476. +    }
  1477. +
  1478. +    switch (key) {
  1479. +    case 5000: /* profile.system */
  1480. +        m_systemClocks.push_back(odNPerformanceLevel);
  1481. +        break;
  1482. +
  1483. +    case 5001: /* profile.memory */
  1484. +        m_memoryClocks.push_back(odNPerformanceLevel);
  1485. +        break;
  1486. +
  1487. +    default:
  1488. +        break;
  1489. +    }
  1490. +}
  1491. +
  1492. +
  1493.  void Options::parseThread(const rapidjson::Value &object)
  1494.  {
  1495.      OclThread *thread = new OclThread();
  1496.      thread->setIndex(object["index"].GetInt());
  1497. -    thread->setIntensity(object["intensity"].GetUint());
  1498. -    thread->setWorksize(object["worksize"].GetUint());
  1499. +
  1500. +   const rapidjson::Value &intensity = object["intensity"];
  1501. +   if (intensity.IsUint()) {
  1502. +       thread->setRawIntensity(intensity.GetUint());
  1503. +   }
  1504. +
  1505. +   const rapidjson::Value &worksize = object["worksize"];
  1506. +   if (worksize.IsUint()) {
  1507. +       thread->setWorksize(worksize.GetUint());
  1508. +   }
  1509.  
  1510.      const rapidjson::Value &affinity = object["affine_to_cpu"];
  1511.      if (affinity.IsInt()) {
  1512. @@ -729,7 +623,6 @@ void Options::parseThread(const rapidjson::Value &object)
  1513.  }
  1514.  
  1515.  
  1516. -
  1517.  void Options::showUsage(int status) const
  1518.  {
  1519.      if (status) {
  1520. @@ -743,37 +636,7 @@ void Options::showUsage(int status) const
  1521.  
  1522.  void Options::showVersion()
  1523.  {
  1524. -    printf(APP_NAME " " APP_VERSION "\n built on " __DATE__
  1525. -
  1526. -#   if defined(__clang__)
  1527. -    " with clang " __clang_version__);
  1528. -#   elif defined(__GNUC__)
  1529. -    " with GCC");
  1530. -    printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
  1531. -#   elif defined(_MSC_VER)
  1532. -    " with MSVC");
  1533. -    printf(" %d", MSVC_VERSION);
  1534. -#   else
  1535. -    );
  1536. -#   endif
  1537. -
  1538. -    printf("\n features:"
  1539. -#   if defined(__i386__) || defined(_M_IX86)
  1540. -    " i386"
  1541. -#   elif defined(__x86_64__) || defined(_M_AMD64)
  1542. -    " x86_64"
  1543. -#   endif
  1544. -
  1545. -#   if defined(__AES__) || defined(_MSC_VER)
  1546. -    " AES-NI"
  1547. -#   endif
  1548. -    "\n");
  1549. -
  1550. -    printf("\nlibuv/%s\n", uv_version_string());
  1551. -
  1552. -#   ifndef XMRIG_NO_HTTPD
  1553. -    printf("libmicrohttpd/%s\n", MHD_get_version());
  1554. -#   endif
  1555. +    printf("%s\n", Platform::versionString());
  1556.  }
  1557.  
  1558.  
  1559. @@ -787,7 +650,7 @@ bool Options::setAlgo(const char *algo)
  1560.  
  1561.  #       ifndef XMRIG_NO_AEON
  1562.          if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light")) {
  1563. -            m_algo = xmrig::ALGO_CRYPTONIGHT_LITE;
  1564. +            m_algo = ALGO_CRYPTONIGHT_LITE;
  1565.              break;
  1566.          }
  1567.  #       endif
  1568. diff --git a/src/Options.h b/src/Options.h
  1569. index defee60..be80562 100644
  1570. --- a/src/Options.h
  1571. +++ b/src/Options.h
  1572. @@ -6,6 +6,7 @@
  1573.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  1574.   * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  1575.   * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  1576. +
  1577.   *
  1578.   *   This program is free software: you can redistribute it and/or modify
  1579.   *   it under the terms of the GNU General Public License as published by
  1580. @@ -29,6 +30,7 @@
  1581.  #include <vector>
  1582.  
  1583.  
  1584. +#include "amd/Adl.h"
  1585.  #include "amd/OclCLI.h"
  1586.  #include "rapidjson/fwd.h"
  1587.  
  1588. @@ -37,10 +39,20 @@ class OclThread;
  1589.  class Url;
  1590.  struct option;
  1591.  
  1592. -
  1593.  class Options
  1594.  {
  1595.  public:
  1596. +    enum Algo {
  1597. +        ALGO_CRYPTONIGHT,      /* CryptoNight (Monero) */
  1598. +        ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
  1599. +    };
  1600. +
  1601. +    enum Variant {
  1602. +        VARIANT_AUTO = -1,
  1603. +        VARIANT_NONE = 0,
  1604. +        VARIANT_V1   = 1
  1605. +    };
  1606. +
  1607.      enum AlgoVariant {
  1608.          AV0_AUTO,
  1609.          AV1_AESNI,
  1610. @@ -55,29 +67,30 @@ public:
  1611.  
  1612.      inline bool background() const                        { return m_background; }
  1613.      inline bool colors() const                            { return m_colors; }
  1614. -    inline bool isAutoConf() const                        { return m_autoConf; }
  1615.      inline bool syslog() const                            { return m_syslog; }
  1616. -    inline const char *apiToken() const                   { return m_apiToken; }
  1617. -    inline const char *apiWorkerId() const                { return m_apiWorkerId; }
  1618. -    inline const char *configName() const                 { return m_configName; }
  1619. -    inline const char *logFile() const                    { return m_logFile; }
  1620. -    inline const char *userAgent() const                  { return m_userAgent; }
  1621. +    inline const char *accessToken() const                { return m_accessToken; }
  1622. +    inline const char *id() const                         { return m_id; }
  1623. +    inline const char *log() const                        { return m_log; }
  1624.      inline const std::vector<OclThread*> &threads() const { return m_threads; }
  1625.      inline const std::vector<Url*> &pools() const         { return m_pools; }
  1626.      inline int algo() const                               { return m_algo; }
  1627.      inline int algoVariant() const                        { return m_algoVariant; }
  1628. -    inline int apiPort() const                            { return m_apiPort; }
  1629. -    inline int donateLevel() const                        { return m_donateLevel; }
  1630. +    inline int port() const                               { return m_port; }
  1631. +    inline size_t intensity() const                       { return m_intensity; }
  1632.      inline int platformIndex() const                      { return m_platformIndex; }
  1633. -    inline int printTime() const                          { return m_printTime; }
  1634. -    inline int retries() const                            { return m_retries; }
  1635. -    inline int retryPause() const                         { return m_retryPause; }
  1636. +    inline int printTime() const                          { return 60; }
  1637. +    inline int retries() const                            { return 5; }
  1638. +    inline int retryPause() const                         { return 5; }
  1639.      inline void setColors(bool colors)                    { m_colors = colors; }
  1640. +    inline const std::vector<ADLODNPerformanceLevelX2*> &systemClocks() const { return m_systemClocks; }
  1641. +    inline const std::vector<ADLODNPerformanceLevelX2*> &memoryClocks() const { return m_memoryClocks; }
  1642. +    inline int targetTemperature() const                  { return m_targetTemperature; }
  1643. +    inline int powerLimit() const                         { return m_powerLimit; }
  1644.  
  1645.      inline static void release()                          { delete m_self; }
  1646.  
  1647.      bool oclInit();
  1648. -    bool save();
  1649. +
  1650.      const char *algoName() const;
  1651.  
  1652.  private:
  1653. @@ -91,39 +104,39 @@ private:
  1654.      bool getJSON(const char *fileName, rapidjson::Document &doc);
  1655.      bool parseArg(int key, const char *arg);
  1656.      bool parseArg(int key, uint64_t arg);
  1657. +   bool parseArg(int key, int64_t arg);
  1658.      bool parseBoolean(int key, bool enable);
  1659.      Url *parseUrl(const char *arg) const;
  1660. -    void adjust();
  1661.      void parseConfig(const char *fileName);
  1662. +    void parseProfile(const struct option *option, const rapidjson::Value &object);
  1663.      void parseJSON(const struct option *option, const rapidjson::Value &object);
  1664. +    void parseLevel(int key, const rapidjson::Value &object);
  1665.      void parseThread(const rapidjson::Value &object);
  1666.      void showUsage(int status) const;
  1667.      void showVersion(void);
  1668.  
  1669.      bool setAlgo(const char *algo);
  1670.  
  1671. -    bool m_autoConf;
  1672.      bool m_background;
  1673.      bool m_colors;
  1674.      bool m_ready;
  1675. -    bool m_shouldSave;
  1676.      bool m_syslog;
  1677. -    char *m_apiToken;
  1678. -    char *m_apiWorkerId;
  1679. -    char *m_configName;
  1680. -    char *m_logFile;
  1681. -    char *m_userAgent;
  1682. +    char *m_accessToken;
  1683. +    char *m_id;
  1684. +    char *m_config;
  1685. +    char *m_log;
  1686.      int m_algo;
  1687.      int m_algoVariant;
  1688. -    int m_apiPort;
  1689. -    int m_donateLevel;
  1690. +    int m_port;
  1691. +    size_t m_intensity;
  1692.      int m_platformIndex;
  1693. -    int m_printTime;
  1694. -    int m_retries;
  1695. -    int m_retryPause;
  1696.      OclCLI m_oclCLI;
  1697.      std::vector<OclThread*> m_threads;
  1698.      std::vector<Url*> m_pools;
  1699. +    std::vector<ADLODNPerformanceLevelX2*> m_systemClocks;
  1700. +    std::vector<ADLODNPerformanceLevelX2*> m_memoryClocks;
  1701. +    int m_targetTemperature;
  1702. +    int m_powerLimit;
  1703.  };
  1704.  
  1705.  #endif /* __OPTIONS_H__ */
  1706. diff --git a/src/Platform.cpp b/src/Platform.cpp
  1707. index 4ddb142..c6826c8 100644
  1708. --- a/src/Platform.cpp
  1709. +++ b/src/Platform.cpp
  1710. @@ -29,34 +29,34 @@
  1711.  #include "Platform.h"
  1712.  
  1713.  
  1714. -char *Platform::m_defaultConfigName = nullptr;
  1715. -char *Platform::m_userAgent         = nullptr;
  1716. +char *Platform::m_defaultConfig = nullptr;
  1717. +char *Platform::m_versionString     = nullptr;
  1718.  
  1719.  
  1720. -const char *Platform::defaultConfigName()
  1721. +const char *Platform::defaultConfig()
  1722.  {
  1723.      size_t size = 520;
  1724.  
  1725. -    if (m_defaultConfigName == nullptr) {
  1726. -        m_defaultConfigName = new char[size];
  1727. +    if (m_defaultConfig == nullptr) {
  1728. +        m_defaultConfig = new char[size];
  1729.      }
  1730.  
  1731. -    if (uv_exepath(m_defaultConfigName, &size) < 0) {
  1732. +    if (uv_exepath(m_defaultConfig, &size) < 0) {
  1733.          return nullptr;
  1734.      }
  1735.  
  1736.      if (size < 500) {
  1737.  #       ifdef WIN32
  1738. -        char *p = strrchr(m_defaultConfigName, '\\');
  1739. +        char *p = strrchr(m_defaultConfig, '\\');
  1740.  #       else
  1741. -        char *p = strrchr(m_defaultConfigName, '/');
  1742. +        char *p = strrchr(m_defaultConfig, '/');
  1743.  #       endif
  1744.  
  1745.          if (p) {
  1746.              strcpy(p + 1, "config.json");
  1747. -            return m_defaultConfigName;
  1748. +            return m_defaultConfig;
  1749.          }
  1750.      }
  1751.  
  1752.      return nullptr;
  1753. -}
  1754. +}
  1755. \ No newline at end of file
  1756. diff --git a/src/Platform.h b/src/Platform.h
  1757. index 4abbba7..92df63d 100644
  1758. --- a/src/Platform.h
  1759. +++ b/src/Platform.h
  1760. @@ -28,19 +28,19 @@
  1761.  class Platform
  1762.  {
  1763.  public:
  1764. -    static const char *defaultConfigName();
  1765. -    static void init(const char *userAgent);
  1766. +    static const char *defaultConfig();
  1767. +    static void init();
  1768.      static void release();
  1769.      static void setProcessPriority(int priority);
  1770.      static void setThreadAffinity(uint64_t cpu_id);
  1771.      static void setThreadPriority(int priority);
  1772.  
  1773. -    static inline const char *userAgent() { return m_userAgent; }
  1774. +    static inline const char *versionString() { return m_versionString; }
  1775.  
  1776.  private:
  1777. -    static char *m_defaultConfigName;
  1778. -    static char *m_userAgent;
  1779. +    static char *m_defaultConfig;
  1780. +    static char *m_versionString;
  1781.  };
  1782.  
  1783.  
  1784. -#endif /* __PLATFORM_H__ */
  1785. +#endif /* __PLATFORM_H__ */
  1786. \ No newline at end of file
  1787. diff --git a/src/Platform_mac.cpp b/src/Platform_mac.cpp
  1788. index 61246bc..aa3188f 100644
  1789. --- a/src/Platform_mac.cpp
  1790. +++ b/src/Platform_mac.cpp
  1791. @@ -36,33 +36,56 @@
  1792.  #   include "nvidia/cryptonight.h"
  1793.  #endif
  1794.  
  1795. +#ifndef XMRIG_NO_HTTPD
  1796. +#   include <microhttpd.h>
  1797. +#endif
  1798. +
  1799. +#include <OpenCL/cl.h>
  1800. +
  1801. +#if CL_VERSION_2_0
  1802. +#    define CL_VERSION_STRING "2.0"
  1803. +#elif CL_VERSION_1_2
  1804. +#    define CL_VERSION_STRING "1.2"
  1805. +#elif CL_VERSION_1_1
  1806. +#    define CL_VERSION_STRING "1.1"
  1807. +#elif CL_VERSION_1_0
  1808. +#    define CL_VERSION_STRING "1.0"
  1809. +#endif
  1810. +
  1811.  
  1812. -static inline char *createUserAgent()
  1813. +
  1814. +static inline char *createVersionString()
  1815.  {
  1816.      const size_t max = 160;
  1817.  
  1818.      char *buf = new char[max];
  1819. +    int length = snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s OpenCL/%s", APP_NAME, APP_VERSION, uv_version_string(), CL_VERSION_STRING);
  1820. +
  1821. +#   ifndef XMRIG_NO_HTTPD
  1822. +    length += snprintf(buf + length, max - length, " libmicrohttpd/%s", MHD_get_version());
  1823. +#   endif
  1824.  
  1825.  #   ifdef XMRIG_NVIDIA_PROJECT
  1826.      const int cudaVersion = cuda_get_runtime_version();
  1827. -    snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__, __clang_patchlevel__);
  1828. -#   else
  1829. -    snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION, uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
  1830. +    length += snprintf(buf + length, max - length, " CUDA/%d.%d", cudaVersion / 1000, cudaVersion % 100);
  1831.  #   endif
  1832.  
  1833. +    length += snprintf(buf + length, max - length, " clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
  1834. +
  1835.      return buf;
  1836.  }
  1837.  
  1838.  
  1839. -void Platform::init(const char *userAgent)
  1840. +void Platform::init()
  1841.  {
  1842. -    m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
  1843. +    m_versionString = createVersionString();
  1844.  }
  1845.  
  1846.  
  1847.  void Platform::release()
  1848.  {
  1849. -    delete [] m_userAgent;
  1850. +    delete [] m_defaultConfig;
  1851. +    delete [] m_versionString;
  1852.  }
  1853.  
  1854.  
  1855. @@ -115,4 +138,3 @@ void Platform::setThreadPriority(int priority)
  1856.  
  1857.      setpriority(PRIO_PROCESS, 0, prio);
  1858.  }
  1859. -
  1860. diff --git a/src/Platform_unix.cpp b/src/Platform_unix.cpp
  1861. index f47b6c4..d62002a 100644
  1862. --- a/src/Platform_unix.cpp
  1863. +++ b/src/Platform_unix.cpp
  1864. @@ -46,13 +46,28 @@
  1865.  #   include "nvidia/cryptonight.h"
  1866.  #endif
  1867.  
  1868. +#ifndef XMRIG_NO_HTTPD
  1869. +#   include <microhttpd.h>
  1870. +#endif
  1871. +
  1872. +#include <CL/cl.h>
  1873. +
  1874. +#if CL_VERSION_2_0
  1875. +#    define CL_VERSION_STRING "2.0"
  1876. +#elif CL_VERSION_1_2
  1877. +#    define CL_VERSION_STRING "1.2"
  1878. +#elif CL_VERSION_1_1
  1879. +#    define CL_VERSION_STRING "1.1"
  1880. +#elif CL_VERSION_1_0
  1881. +#    define CL_VERSION_STRING "1.0"
  1882. +#endif
  1883.  
  1884.  #ifdef __FreeBSD__
  1885.  typedef cpuset_t cpu_set_t;
  1886.  #endif
  1887.  
  1888.  
  1889. -static inline char *createUserAgent()
  1890. +static inline char *createVersionString()
  1891.  {
  1892.      const size_t max = 160;
  1893.  
  1894. @@ -60,9 +75,13 @@ static inline char *createUserAgent()
  1895.      int length = snprintf(buf, max, "%s/%s (Linux ", APP_NAME, APP_VERSION);
  1896.  
  1897.  #   if defined(__x86_64__)
  1898. -    length += snprintf(buf + length, max - length, "x86_64) libuv/%s", uv_version_string());
  1899. +    length += snprintf(buf + length, max - length, "x86_64) libuv/%s OpenCL/%s", uv_version_string(), CL_VERSION_STRING);
  1900.  #   else
  1901. -    length += snprintf(buf + length, max - length, "i686) libuv/%s", uv_version_string());
  1902. +    length += snprintf(buf + length, max - length, "i686) libuv/%s OpenCL/%s", uv_version_string(), CL_VERSION_STRING);
  1903. +#   endif
  1904. +
  1905. +#   ifndef XMRIG_NO_HTTPD
  1906. +    length += snprintf(buf + length, max - length, " libmicrohttpd/%s", MHD_get_version());
  1907.  #   endif
  1908.  
  1909.  #   ifdef XMRIG_NVIDIA_PROJECT
  1910. @@ -78,15 +97,16 @@ static inline char *createUserAgent()
  1911.  }
  1912.  
  1913.  
  1914. -void Platform::init(const char *userAgent)
  1915. +void Platform::init()
  1916.  {
  1917. -    m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
  1918. +    m_versionString = createVersionString();
  1919.  }
  1920.  
  1921.  
  1922.  void Platform::release()
  1923.  {
  1924. -    delete [] m_userAgent;
  1925. +    delete [] m_defaultConfig;
  1926. +    delete [] m_versionString;
  1927.  }
  1928.  
  1929.  
  1930. @@ -149,4 +169,4 @@ void Platform::setThreadPriority(int priority)
  1931.          }
  1932.      }
  1933.  #   endif
  1934. -}
  1935. +}
  1936. \ No newline at end of file
  1937. diff --git a/src/Platform_win.cpp b/src/Platform_win.cpp
  1938. index ae12581..2615885 100644
  1939. --- a/src/Platform_win.cpp
  1940. +++ b/src/Platform_win.cpp
  1941. @@ -34,6 +34,37 @@
  1942.  #   include "nvidia/cryptonight.h"
  1943.  #endif
  1944.  
  1945. +#ifndef XMRIG_NO_HTTPD
  1946. +#   include <microhttpd.h>
  1947. +#endif
  1948. +
  1949. +#include <CL/cl.h>
  1950. +
  1951. +#if CL_VERSION_2_0
  1952. +#    define CL_VERSION_STRING "2.0"
  1953. +#elif CL_VERSION_1_2
  1954. +#    define CL_VERSION_STRING "1.2"
  1955. +#elif CL_VERSION_1_1
  1956. +#    define CL_VERSION_STRING "1.1"
  1957. +#elif CL_VERSION_1_0
  1958. +#    define CL_VERSION_STRING "1.0"
  1959. +#endif
  1960. +
  1961. +#ifdef _MSC_VER
  1962. +#   if (_MSC_VER >= 1910)
  1963. +#       define MSVC_VERSION 2017
  1964. +#   elif _MSC_VER == 1900
  1965. +#       define MSVC_VERSION 2015
  1966. +#   elif _MSC_VER == 1800
  1967. +#       define MSVC_VERSION 2013
  1968. +#   elif _MSC_VER == 1700
  1969. +#       define MSVC_VERSION 2012
  1970. +#   elif _MSC_VER == 1600
  1971. +#       define MSVC_VERSION 2010
  1972. +#   else
  1973. +#       define MSVC_VERSION 0
  1974. +#   endif
  1975. +#endif
  1976.  
  1977.  static inline OSVERSIONINFOEX winOsVersion()
  1978.  {
  1979. @@ -53,7 +84,7 @@ static inline OSVERSIONINFOEX winOsVersion()
  1980.  }
  1981.  
  1982.  
  1983. -static inline char *createUserAgent()
  1984. +static inline char *createVersionString()
  1985.  {
  1986.      const auto osver = winOsVersion();
  1987.      const size_t max = 160;
  1988. @@ -62,9 +93,13 @@ static inline char *createUserAgent()
  1989.      int length = snprintf(buf, max, "%s/%s (Windows NT %lu.%lu", APP_NAME, APP_VERSION, osver.dwMajorVersion, osver.dwMinorVersion);
  1990.  
  1991.  #   if defined(__x86_64__) || defined(_M_AMD64)
  1992. -    length += snprintf(buf + length, max - length, "; Win64; x64) libuv/%s", uv_version_string());
  1993. +    length += snprintf(buf + length, max - length, "; Win64; x64) libuv/%s OpenCL/%s", uv_version_string(), CL_VERSION_STRING);
  1994.  #   else
  1995. -    length += snprintf(buf + length, max - length, ") libuv/%s", uv_version_string());
  1996. +    length += snprintf(buf + length, max - length, ") libuv/%s OpenCL/%s", uv_version_string(), CL_VERSION_STRING);
  1997. +#   endif
  1998. +
  1999. +#   ifndef XMRIG_NO_HTTPD
  2000. +    length += snprintf(buf + length, max - length, " libmicrohttpd/%s", MHD_get_version());
  2001.  #   endif
  2002.  
  2003.  #   ifdef XMRIG_NVIDIA_PROJECT
  2004. @@ -82,16 +117,16 @@ static inline char *createUserAgent()
  2005.  }
  2006.  
  2007.  
  2008. -void Platform::init(const char *userAgent)
  2009. +void Platform::init()
  2010.  {
  2011. -    m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
  2012. +    m_versionString = createVersionString();
  2013.  }
  2014.  
  2015.  
  2016.  void Platform::release()
  2017.  {
  2018. -    delete [] m_defaultConfigName;
  2019. -    delete [] m_userAgent;
  2020. +    delete [] m_defaultConfig;
  2021. +    delete [] m_versionString;
  2022.  }
  2023.  
  2024.  
  2025. @@ -172,4 +207,3 @@ void Platform::setThreadPriority(int priority)
  2026.  
  2027.      SetThreadPriority(GetCurrentThread(), prio);
  2028.  }
  2029. -
  2030. diff --git a/src/Summary.cpp b/src/Summary.cpp
  2031. index 8e7b3ff..affa668 100644
  2032. --- a/src/Summary.cpp
  2033. +++ b/src/Summary.cpp
  2034. @@ -23,54 +23,20 @@
  2035.  
  2036.  
  2037.  #include <inttypes.h>
  2038. -#include <uv.h>
  2039. -
  2040. -
  2041. -#if defined(__APPLE__)
  2042. -#   include <OpenCL/cl.h>
  2043. -#else
  2044. -#   include <CL/cl.h>
  2045. -#endif
  2046. -
  2047.  
  2048.  #include "Cpu.h"
  2049.  #include "log/Log.h"
  2050.  #include "net/Url.h"
  2051.  #include "Options.h"
  2052.  #include "Summary.h"
  2053. -#include "version.h"
  2054. +#include "Platform.h"
  2055.  #include "workers/OclThread.h"
  2056.  
  2057.  
  2058. -static void print_versions()
  2059. +static void print_version()
  2060.  {
  2061. -    char buf[16];
  2062. -
  2063. -#   if defined(__clang__)
  2064. -    snprintf(buf, 16, " clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__);
  2065. -#   elif defined(__GNUC__)
  2066. -    snprintf(buf, 16, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
  2067. -#   elif defined(_MSC_VER)
  2068. -    snprintf(buf, 16, " MSVC/%d", MSVC_VERSION);
  2069. -#   else
  2070. -    buf[0] = '\0';
  2071. -#   endif
  2072. -
  2073. -
  2074. -#   if CL_VERSION_2_0
  2075. -    const char *ocl = "2.0";
  2076. -#   elif CL_VERSION_1_2
  2077. -    const char *ocl = "1.2";
  2078. -#   elif CL_VERSION_1_1
  2079. -    const char *ocl = "1.1";
  2080. -#   elif CL_VERSION_1_0
  2081. -    const char *ocl = "1.0";
  2082. -#   else
  2083. -    const char *ocl = "0.0";
  2084. -#   endif
  2085. -
  2086. -    Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS:     \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s OpenCL/%s%s" : " * VERSIONS:     XMRig/%s libuv/%s OpenCL/%s%s",
  2087. -                   APP_VERSION, uv_version_string(), ocl, buf);
  2088. +    Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mVERSION:      %s" : " * VERSION:      %s",
  2089. +                   Platform::versionString());
  2090.  }
  2091.  
  2092.  
  2093. @@ -90,10 +56,8 @@ static void print_cpu()
  2094.  
  2095.  static void print_algo()
  2096.  {
  2097. -    Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mALGO:         %s, %sdonate=%d%%" : " * ALGO:         %s, %sdonate=%d%%",
  2098. -                   Options::i()->algoName(),
  2099. -                   Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
  2100. -                   Options::i()->donateLevel()
  2101. +    Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mALGO:         %s" : " * ALGO:         %s",
  2102. +                   Options::i()->algoName()
  2103.      );
  2104.  }
  2105.  
  2106. @@ -120,11 +84,11 @@ static void print_pools()
  2107.  #ifndef XMRIG_NO_API
  2108.  static void print_api()
  2109.  {
  2110. -    if (Options::i()->apiPort() == 0) {
  2111. +    if (Options::i()->port() == 0) {
  2112.          return;
  2113.      }
  2114.  
  2115. -    Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT:     \x1B[01;36m%d" : " * API PORT:     %d", Options::i()->apiPort());
  2116. +    Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT:     \x1B[01;36m%d" : " * API PORT:     %d", Options::i()->port());
  2117.  }
  2118.  #endif
  2119.  
  2120. @@ -142,7 +106,7 @@ static void print_commands()
  2121.  
  2122.  void Summary::print()
  2123.  {
  2124. -    print_versions();
  2125. +    print_version();
  2126.      print_cpu();
  2127.      print_algo();
  2128.      print_pools();
  2129. @@ -155,4 +119,3 @@ void Summary::print()
  2130.  }
  2131.  
  2132.  
  2133. -
  2134. diff --git a/src/amd/GpuContext.h b/src/amd/GpuContext.h
  2135. index 8587b52..fc7f49c 100644
  2136. --- a/src/amd/GpuContext.h
  2137. +++ b/src/amd/GpuContext.h
  2138. @@ -46,28 +46,32 @@ struct GpuContext
  2139.          CommandQueues(nullptr),
  2140.          InputBuffer(nullptr),
  2141.          OutputBuffer(nullptr),
  2142. -        ExtraBuffers{ nullptr },
  2143. +        ExtraBuffers{nullptr},
  2144.          Program(nullptr),
  2145. -        Kernels{ nullptr },
  2146. +        Kernels{nullptr},
  2147.          freeMem(0),
  2148.          computeUnits(0),
  2149. +        threadId(0),
  2150. +        busId(0),
  2151.          Nonce(0)
  2152.      {}
  2153.  
  2154.  
  2155. -    inline GpuContext(size_t index, size_t intensity, size_t worksize) :
  2156. +    inline GpuContext(size_t index, size_t rawIntensity, size_t worksize) :
  2157.          deviceIdx(index),
  2158. -        rawIntensity(intensity),
  2159. +        rawIntensity(rawIntensity),
  2160.          workSize(worksize),
  2161.          DeviceID(nullptr),
  2162.          CommandQueues(nullptr),
  2163.          InputBuffer(nullptr),
  2164.          OutputBuffer(nullptr),
  2165. -        ExtraBuffers{ nullptr },
  2166. +        ExtraBuffers{nullptr},
  2167.          Program(nullptr),
  2168. -        Kernels{ nullptr },
  2169. +        Kernels{nullptr},
  2170.          freeMem(0),
  2171.          computeUnits(0),
  2172. +        threadId(0),
  2173. +        busId(0),
  2174.          Nonce(0)
  2175.      {}
  2176.  
  2177. @@ -86,7 +90,9 @@ struct GpuContext
  2178.      cl_kernel Kernels[7];
  2179.      size_t freeMem;
  2180.      int computeUnits;
  2181. -    std::string name;
  2182. +    int threadId;
  2183. +    int busId;
  2184. +    std::string deviceName;
  2185.  
  2186.      uint32_t Nonce;
  2187.  };
  2188. diff --git a/src/amd/OclCLI.cpp b/src/amd/OclCLI.cpp
  2189. index 7e47e69..e5b1880 100644
  2190. --- a/src/amd/OclCLI.cpp
  2191. +++ b/src/amd/OclCLI.cpp
  2192. @@ -34,7 +34,6 @@
  2193.  #include "log/Log.h"
  2194.  #include "Options.h"
  2195.  #include "workers/OclThread.h"
  2196. -#include "xmrig.h"
  2197.  
  2198.  
  2199.  OclCLI::OclCLI()
  2200. @@ -56,75 +55,42 @@ bool OclCLI::setup(std::vector<OclThread*> &threads)
  2201.  }
  2202.  
  2203.  
  2204. -void OclCLI::autoConf(std::vector<OclThread*> &threads, int *platformIndex)
  2205. +void OclCLI::autoConf(std::vector<OclThread*> &threads, int *platformIndex, size_t *intensity)
  2206.  {
  2207.      *platformIndex = getAMDPlatformIdx();
  2208.      if (*platformIndex == -1) {
  2209. -        LOG_ERR("No AMD OpenCL platform found. Possible driver issues or wrong vendor driver.");
  2210. +        LOG_ERR("No AMD OpenCL platform found");
  2211.          return;
  2212.      }
  2213.  
  2214.      std::vector<GpuContext> devices = getAMDDevices(*platformIndex);
  2215.      if (devices.empty()) {
  2216. -        LOG_ERR("No AMD device found.");
  2217. +        LOG_ERR("No AMD devices found.");
  2218.          return;
  2219.      }
  2220.  
  2221.      constexpr size_t byteToMiB = 1024u * 1024u;
  2222. -    const size_t hashMemSize   = Options::i()->algo() == xmrig::ALGO_CRYPTONIGHT ? MONERO_MEMORY : AEON_MEMORY;
  2223. +    const size_t hashMemSize   = Options::i()->algo() == Options::ALGO_CRYPTONIGHT ? MONERO_MEMORY : AEON_MEMORY;
  2224.  
  2225.      for (GpuContext &ctx : devices) {
  2226.          size_t maxThreads = 1000u;
  2227. -        if (ctx.name.compare("gfx901") == 0) {
  2228. +        int gpuThreads = 1;
  2229. +
  2230. +        // rx vega
  2231. +        if (ctx.deviceName.find("687F") == 0 || ctx.deviceName.find("Radeon RX Vega") == 0) {
  2232.              maxThreads = 2024u;
  2233. +            gpuThreads = 2;
  2234.          }
  2235.  
  2236.          const size_t availableMem      = ctx.freeMem - (128u * byteToMiB);
  2237.          const size_t perThread         = hashMemSize + 224u;
  2238. -        const size_t maxIntensity      = availableMem / perThread;
  2239. -        const size_t possibleIntensity = std::min(maxThreads, maxIntensity);
  2240. -        const size_t intensity         = (possibleIntensity / (8 * ctx.computeUnits)) * ctx.computeUnits * 8;
  2241. -
  2242. -        threads.push_back(new OclThread(ctx.deviceIdx, intensity, 8));
  2243. -    }
  2244. -}
  2245. -
  2246. +        const size_t maxIntensity      = std::min(maxThreads, availableMem / perThread);
  2247. +        const size_t rawIntensity      = (maxIntensity / (8 * ctx.computeUnits)) * ctx.computeUnits * 8;
  2248.  
  2249. -void OclCLI::parseLaunch(const char *arg)
  2250. -{
  2251. -    char *value = strdup(arg);
  2252. -    char *pch   = strtok(value, ",");
  2253. -    std::vector<char *> tmp;
  2254. -
  2255. -    while (pch != nullptr) {
  2256. -        tmp.push_back(pch);
  2257. -        pch = strtok(nullptr, ",");
  2258. -    }
  2259. -
  2260. -    for (char *config : tmp) {
  2261. -        pch       = strtok(config, "x");
  2262. -        int count = 0;
  2263. -
  2264. -        while (pch != nullptr && count < 2) {
  2265. -            count++;
  2266. -
  2267. -            const int v = (int) strtoul(pch, nullptr, 10);
  2268. -            if (count == 1) {
  2269. -                m_intensity.push_back(v > 0 ? v : 0);
  2270. -            }
  2271. -            else if (count == 2) {
  2272. -                m_worksize.push_back(v > 0 ? v : 8);
  2273. -            }
  2274. -
  2275. -            pch = strtok(nullptr, "x");
  2276. -        }
  2277. -
  2278. -        if (count == 1) {
  2279. -            m_worksize.push_back(8);
  2280. +        for (int i = 0; i < gpuThreads; i++) {
  2281. +            threads.push_back(new OclThread(ctx.deviceIdx, *intensity ? *intensity : std::min(rawIntensity, maxIntensity), 8));
  2282.          }
  2283.      }
  2284. -
  2285. -    free(value);
  2286.  }
  2287.  
  2288.  
  2289. @@ -154,4 +120,4 @@ void OclCLI::parse(std::vector<int> &vector, const char *arg) const
  2290.      }
  2291.  
  2292.      free(value);
  2293. -}
  2294. +}
  2295. \ No newline at end of file
  2296. diff --git a/src/amd/OclCLI.h b/src/amd/OclCLI.h
  2297. index 4aac45a..6768216 100644
  2298. --- a/src/amd/OclCLI.h
  2299. +++ b/src/amd/OclCLI.h
  2300. @@ -37,11 +37,7 @@ public:
  2301.      OclCLI();
  2302.  
  2303.      bool setup(std::vector<OclThread*> &threads);
  2304. -    void autoConf(std::vector<OclThread*> &threads, int *platformIndex);
  2305. -    void parseLaunch(const char *arg);
  2306. -
  2307. -    inline void parseAffinity(const char *arg) { parse(m_affinity, arg); }
  2308. -    inline void parseDevices(const char *arg)  { parse(m_devices, arg); }
  2309. +    void autoConf(std::vector<OclThread*> &threads, int *platformIndex, size_t *intensity);
  2310.  
  2311.  private:
  2312.      inline bool isEmpty() const           { return m_devices.empty() && m_intensity.empty(); }
  2313. @@ -59,4 +55,4 @@ private:
  2314.  };
  2315.  
  2316.  
  2317. -#endif /* __OCLCLI_H__ */
  2318. +#endif /* __OCLCLI_H__ */
  2319. \ No newline at end of file
  2320. diff --git a/src/amd/OclGPU.cpp b/src/amd/OclGPU.cpp
  2321. index c200b1e..ba8a2ea 100644
  2322. --- a/src/amd/OclGPU.cpp
  2323. +++ b/src/amd/OclGPU.cpp
  2324. @@ -56,7 +56,16 @@ static inline void port_sleep(size_t sec)
  2325.  #include "cryptonight.h"
  2326.  #include "log/Log.h"
  2327.  #include "Options.h"
  2328. -#include "xmrig.h"
  2329. +
  2330. +#if defined(__APPLE__)
  2331. +#   include <OpenCL/cl_ext.h>
  2332. +#else
  2333. +#   include <CL/cl_ext.h>
  2334. +#endif
  2335. +
  2336. +#ifndef CL_MEM_USE_PERSISTENT_MEM_AMD
  2337. +#define CL_MEM_USE_PERSISTENT_MEM_AMD 0
  2338. +#endif
  2339.  
  2340.  
  2341.  constexpr const char *kSetKernelArgErr = "Error %s when calling clSetKernelArg for kernel %d, argument %d.";
  2342. @@ -205,13 +214,36 @@ inline static int getDeviceMaxComputeUnits(cl_device_id id)
  2343.  }
  2344.  
  2345.  
  2346. -inline static void getDeviceName(cl_device_id id, char *buf, size_t size)
  2347. +inline static std::string getDeviceName(cl_device_id id)
  2348.  {
  2349. -    if (clGetDeviceInfo(id, 0x4038 /* CL_DEVICE_BOARD_NAME_AMD */, size, buf, nullptr) == CL_SUCCESS) {
  2350. -        return;
  2351. +    char buf[128] = { 0 };
  2352. +
  2353. +    if (clGetDeviceInfo(id, 0x4038 /* CL_DEVICE_BOARD_NAME_AMD */, sizeof(buf), buf, nullptr) == CL_SUCCESS) {
  2354. +        return buf;
  2355. +    }
  2356. +
  2357. +    if (clGetDeviceInfo(id, CL_DEVICE_NAME, sizeof(buf), buf, nullptr) == CL_SUCCESS) {
  2358. +        return buf;
  2359.      }
  2360.  
  2361. -    clGetDeviceInfo(id, CL_DEVICE_NAME, size, buf, nullptr);
  2362. +    return "";
  2363. +}
  2364. +
  2365. +
  2366. +inline static int getBusId(cl_device_id id)
  2367. +{
  2368. +#if defined(CL_DEVICE_TOPOLOGY_AMD)
  2369. +    cl_device_topology_amd topology;
  2370. +    if(clGetDeviceInfo(id, CL_DEVICE_TOPOLOGY_AMD,
  2371. +        sizeof(cl_device_topology_amd), &topology, nullptr) != CL_SUCCESS) {
  2372. +        // handle error
  2373. +    }
  2374. +
  2375. +    if (topology.raw.type == CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD) {
  2376. +        return (int)topology.pcie.bus;
  2377. +    }
  2378. +#endif
  2379. +    return -1;
  2380.  }
  2381.  
  2382.  
  2383. @@ -228,7 +260,7 @@ inline static bool setKernelArgFromExtraBuffers(GpuContext *ctx, size_t kernel,
  2384.  }
  2385.  
  2386.  
  2387. -size_t InitOpenCLGpu(int index, cl_context opencl_ctx, GpuContext* ctx, const char* source_code)
  2388. +size_t InitOpenCLGpu(int index, cl_context opencl_ctx, GpuContext* ctx)
  2389.  {
  2390.      size_t MaximumWorkSize;
  2391.      cl_int ret;
  2392. @@ -238,12 +270,12 @@ size_t InitOpenCLGpu(int index, cl_context opencl_ctx, GpuContext* ctx, const ch
  2393.          return OCL_ERR_API;
  2394.      }
  2395.  
  2396. -    char buf[128] = { 0 };
  2397. -    getDeviceName(ctx->DeviceID, buf, sizeof(buf));
  2398.      ctx->computeUnits = getDeviceMaxComputeUnits(ctx->DeviceID);
  2399. +    ctx->busId = getBusId(ctx->DeviceID);
  2400. +    ctx->deviceName = getDeviceName(ctx->DeviceID);
  2401.  
  2402.      LOG_INFO(Options::i()->colors() ? "\x1B[01;37m#%d\x1B[0m, GPU \x1B[01;37m#%zu\x1B[0m \x1B[01;32m%s\x1B[0m, intensity: \x1B[01;37m%zu\x1B[0m (%zu/%zu), cu: \x1B[01;37m%d"  : "#%d, GPU #%zu (%s), intensity: %zu (%zu/%zu), cu: %d",
  2403. -        index, ctx->deviceIdx, buf, ctx->rawIntensity, ctx->workSize, MaximumWorkSize, ctx->computeUnits);
  2404. +        index, ctx->deviceIdx, ctx->deviceName.c_str(), ctx->rawIntensity, ctx->workSize, MaximumWorkSize, ctx->computeUnits);
  2405.  
  2406.  #   ifdef CL_VERSION_2_0
  2407.      const cl_queue_properties CommandQueueProperties[] = { 0, 0, 0 };
  2408. @@ -253,29 +285,25 @@ size_t InitOpenCLGpu(int index, cl_context opencl_ctx, GpuContext* ctx, const ch
  2409.      ctx->CommandQueues = clCreateCommandQueue(opencl_ctx, ctx->DeviceID, CommandQueueProperties, &ret);
  2410.  #   endif
  2411.  
  2412. +    size_t hashMemSize = MONERO_MEMORY;
  2413. +
  2414. +#   if !defined(XMRIG_NO_AEON)
  2415. +    if (Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE) {
  2416. +        hashMemSize   = AEON_MEMORY;
  2417. +    }
  2418. +#   endif
  2419. +
  2420.      if (ret != CL_SUCCESS) {
  2421.          LOG_ERR("Error %s when calling clCreateCommandQueueWithProperties.", err_to_str(ret));
  2422.          return OCL_ERR_API;
  2423.      }
  2424.  
  2425. -    ctx->InputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_ONLY, 88, NULL, &ret);
  2426. +    ctx->InputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_ONLY | CL_MEM_USE_PERSISTENT_MEM_AMD, 88, NULL, &ret);
  2427.      if (ret != CL_SUCCESS) {
  2428.          LOG_ERR("Error %s when calling clCreateBuffer to create input buffer.", err_to_str(ret));
  2429.          return OCL_ERR_API;
  2430.      }
  2431.  
  2432. -    size_t hashMemSize = MONERO_MEMORY;
  2433. -    int threadMemMask  = MONERO_MASK;
  2434. -    int hasIterations  = MONERO_ITER;
  2435. -
  2436. -#   if !defined(XMRIG_NO_AEON)
  2437. -    if (Options::i()->algo() == xmrig::ALGO_CRYPTONIGHT_LITE) {
  2438. -        hashMemSize   = AEON_MEMORY;
  2439. -        threadMemMask = AEON_MASK;
  2440. -        hasIterations = AEON_ITER;
  2441. -    }
  2442. -#   endif
  2443. -
  2444.      size_t g_thd = ctx->rawIntensity;
  2445.      ctx->ExtraBuffers[0] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, hashMemSize * g_thd, NULL, &ret);
  2446.      if (ret != CL_SUCCESS) {
  2447. @@ -283,101 +311,47 @@ size_t InitOpenCLGpu(int index, cl_context opencl_ctx, GpuContext* ctx, const ch
  2448.          return OCL_ERR_API;
  2449.      }
  2450.  
  2451. -    ctx->ExtraBuffers[1] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, 200 * g_thd, NULL, &ret);
  2452. +    ctx->ExtraBuffers[1] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_PERSISTENT_MEM_AMD, 200 * g_thd, NULL, &ret);
  2453.      if(ret != CL_SUCCESS) {
  2454.          LOG_ERR("Error %s when calling clCreateBuffer to create hash states buffer.", err_to_str(ret));
  2455.          return OCL_ERR_API;
  2456.      }
  2457.  
  2458.      // Blake-256 branches
  2459. -    ctx->ExtraBuffers[2] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2460. +    ctx->ExtraBuffers[2] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_PERSISTENT_MEM_AMD, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2461.      if (ret != CL_SUCCESS){
  2462.          LOG_ERR("Error %s when calling clCreateBuffer to create Branch 0 buffer.", err_to_str(ret));
  2463.          return OCL_ERR_API;
  2464.      }
  2465.  
  2466.      // Groestl-256 branches
  2467. -    ctx->ExtraBuffers[3] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2468. +    ctx->ExtraBuffers[3] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_PERSISTENT_MEM_AMD, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2469.      if(ret != CL_SUCCESS) {
  2470.          LOG_ERR("Error %s when calling clCreateBuffer to create Branch 1 buffer.", err_to_str(ret));
  2471.          return OCL_ERR_API;
  2472.      }
  2473.  
  2474.      // JH-256 branches
  2475. -    ctx->ExtraBuffers[4] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2476. +    ctx->ExtraBuffers[4] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_PERSISTENT_MEM_AMD, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2477.      if (ret != CL_SUCCESS) {
  2478.          LOG_ERR("Error %s when calling clCreateBuffer to create Branch 2 buffer.", err_to_str(ret));
  2479.          return OCL_ERR_API;
  2480.      }
  2481.  
  2482.      // Skein-512 branches
  2483. -    ctx->ExtraBuffers[5] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2484. +    ctx->ExtraBuffers[5] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_PERSISTENT_MEM_AMD, sizeof(cl_uint) * (g_thd + 2), NULL, &ret);
  2485.      if (ret != CL_SUCCESS) {
  2486.          LOG_ERR("Error %s when calling clCreateBuffer to create Branch 3 buffer.", err_to_str(ret));
  2487.          return OCL_ERR_API;
  2488.      }
  2489.  
  2490.      // Assume we may find up to 0xFF nonces in one run - it's reasonable
  2491. -    ctx->OutputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * 0x100, NULL, &ret);
  2492. +    ctx->OutputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_PERSISTENT_MEM_AMD, sizeof(cl_uint) * 0x100, NULL, &ret);
  2493.      if (ret != CL_SUCCESS) {
  2494.          LOG_ERR("Error %s when calling clCreateBuffer to create output buffer.", err_to_str(ret));
  2495.          return OCL_ERR_API;
  2496.      }
  2497.  
  2498. -    ctx->Program = clCreateProgramWithSource(opencl_ctx, 1, (const char**)&source_code, NULL, &ret);
  2499. -    if (ret != CL_SUCCESS) {
  2500. -        LOG_ERR("Error %s when calling clCreateProgramWithSource on the contents of cryptonight.cl", err_to_str(ret));
  2501. -        return OCL_ERR_API;
  2502. -    }
  2503. -
  2504. -    char options[256];
  2505. -    snprintf(options, sizeof(options), "-DITERATIONS=%d -DMASK=%d -DWORKSIZE=%zu", hasIterations, threadMemMask, ctx->workSize);
  2506. -    ret = clBuildProgram(ctx->Program, 1, &ctx->DeviceID, options, NULL, NULL);
  2507. -    if (ret != CL_SUCCESS) {
  2508. -        size_t len;
  2509. -        LOG_ERR("Error %s when calling clBuildProgram.", err_to_str(ret));
  2510. -
  2511. -        if ((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, 0, NULL, &len)) != CL_SUCCESS) {
  2512. -            LOG_ERR("Error %s when calling clGetProgramBuildInfo for length of build log output.", err_to_str(ret));
  2513. -            return OCL_ERR_API;
  2514. -        }
  2515. -
  2516. -        char* BuildLog = (char*)malloc(len + 1);
  2517. -        BuildLog[0] = '\0';
  2518. -
  2519. -        if ((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, len, BuildLog, NULL)) != CL_SUCCESS) {
  2520. -            free(BuildLog);
  2521. -            LOG_ERR("Error %s when calling clGetProgramBuildInfo for build log.", err_to_str(ret));
  2522. -            return OCL_ERR_API;
  2523. -        }
  2524. -        
  2525. -        Log::i()->text("Build log:");
  2526. -        std::cerr << BuildLog << std::endl;
  2527. -
  2528. -        free(BuildLog);
  2529. -        return OCL_ERR_API;
  2530. -    }
  2531. -
  2532. -    cl_build_status status;
  2533. -    do
  2534. -    {
  2535. -        if ((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL)) != CL_SUCCESS) {
  2536. -            LOG_ERR("Error %s when calling clGetProgramBuildInfo for status of build.", err_to_str(ret));
  2537. -            return OCL_ERR_API;
  2538. -        }
  2539. -        port_sleep(1);
  2540. -    }
  2541. -    while(status == CL_BUILD_IN_PROGRESS);
  2542. -
  2543. -    const char *KernelNames[] = { "cn0", "cn1", "cn2", "Blake", "Groestl", "JH", "Skein" };
  2544. -    for(int i = 0; i < 7; ++i) {
  2545. -        ctx->Kernels[i] = clCreateKernel(ctx->Program, KernelNames[i], &ret);
  2546. -        if (ret != CL_SUCCESS) {
  2547. -            LOG_ERR("Error %s when calling clCreateKernel for kernel %s.", err_to_str(ret), KernelNames[i]);
  2548. -            return OCL_ERR_API;
  2549. -        }
  2550. -    }
  2551. -
  2552.      ctx->Nonce = 0;
  2553.      return 0;
  2554.  }
  2555. @@ -426,6 +400,8 @@ std::vector<GpuContext> getAMDDevices(int index)
  2556.          ctx.deviceIdx = i;
  2557.          ctx.DeviceID = device_list[i];
  2558.          ctx.computeUnits = getDeviceMaxComputeUnits(ctx.DeviceID);
  2559. +        ctx.busId = getBusId(ctx.DeviceID);
  2560. +        ctx.deviceName = getDeviceName(ctx.DeviceID);
  2561.  
  2562.          size_t maxMem;
  2563.          clGetDeviceInfo(ctx.DeviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(size_t), &(maxMem), nullptr);
  2564. @@ -433,12 +409,7 @@ std::vector<GpuContext> getAMDDevices(int index)
  2565.          // if environment variable GPU_SINGLE_ALLOC_PERCENT is not set we can not allocate the full memory
  2566.          ctx.freeMem = std::min(ctx.freeMem, maxMem);
  2567.  
  2568. -        getDeviceName(ctx.DeviceID, buf, sizeof(buf));
  2569. -
  2570. -        LOG_INFO(Options::i()->colors() ? "\x1B[01;32mfound\x1B[0m OpenCL GPU: \x1B[01;37m%s\x1B[0m, cu: \x1B[01;37m%d" : "found OpenCL GPU: %s, cu:", buf, ctx.computeUnits);
  2571. -
  2572. -        clGetDeviceInfo(ctx.DeviceID, CL_DEVICE_NAME, sizeof(buf), buf, nullptr);
  2573. -        ctx.name = buf;
  2574. +        LOG_INFO(Options::i()->colors() ? "\x1B[01;32mfound\x1B[0m OpenCL GPU: \x1B[01;37m%s\x1B[0m, cu: \x1B[01;37m%d" : "found OpenCL GPU: %s, cu:", ctx.deviceName.c_str(), ctx.computeUnits);
  2575.  
  2576.          ctxVec.push_back(ctx);
  2577.      }
  2578. @@ -616,8 +587,77 @@ size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx)
  2579.      source_code = std::regex_replace(source_code, std::regex("XMRIG_INCLUDE_BLAKE256"), blake256CL);
  2580.      source_code = std::regex_replace(source_code, std::regex("XMRIG_INCLUDE_GROESTL256"), groestl256CL);
  2581.  
  2582. +    ctx[0].Program = clCreateProgramWithSource(opencl_ctx, 1, (const char**)&source_code, NULL, &ret);
  2583. +    if (ret != CL_SUCCESS) {
  2584. +        LOG_ERR("Error %s when calling clCreateProgramWithSource on the contents of cryptonight.cl", err_to_str(ret));
  2585. +        return OCL_ERR_API;
  2586. +    }
  2587. +
  2588. +    int threadMemMask  = MONERO_MASK;
  2589. +    int hasIterations  = MONERO_ITER;
  2590. +
  2591. +#   if !defined(XMRIG_NO_AEON)
  2592. +    if (Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE) {
  2593. +        threadMemMask = AEON_MASK;
  2594. +        hasIterations = AEON_ITER;
  2595. +    }
  2596. +#   endif
  2597. +
  2598. +    char options[256];
  2599. +    snprintf(options, sizeof(options), "-DITERATIONS=%d -DMASK=%d -DWORKSIZE=%zu", hasIterations, threadMemMask, ctx[0].workSize);
  2600. +    ret = clBuildProgram(ctx[0].Program, 0, NULL, options, NULL, NULL);
  2601. +    if (ret != CL_SUCCESS) {
  2602. +        size_t len;
  2603. +        LOG_ERR("Error %s when calling clBuildProgram.", err_to_str(ret));
  2604. +
  2605. +        if ((ret = clGetProgramBuildInfo(ctx[0].Program, ctx[0].DeviceID, CL_PROGRAM_BUILD_LOG, 0, NULL, &len)) != CL_SUCCESS) {
  2606. +            LOG_ERR("Error %s when calling clGetProgramBuildInfo for length of build log output.", err_to_str(ret));
  2607. +            return OCL_ERR_API;
  2608. +        }
  2609. +
  2610. +        char* BuildLog = (char*)malloc(len + 1);
  2611. +        BuildLog[0] = '\0';
  2612. +
  2613. +        if ((ret = clGetProgramBuildInfo(ctx[0].Program, ctx[0].DeviceID, CL_PROGRAM_BUILD_LOG, len, BuildLog, NULL)) != CL_SUCCESS) {
  2614. +            free(BuildLog);
  2615. +            LOG_ERR("Error %s when calling clGetProgramBuildInfo for build log.", err_to_str(ret));
  2616. +            return OCL_ERR_API;
  2617. +        }
  2618. +        
  2619. +        Log::i()->text("Build log:");
  2620. +        std::cerr << BuildLog << std::endl;
  2621. +
  2622. +        free(BuildLog);
  2623. +        return OCL_ERR_API;
  2624. +    }
  2625. +
  2626. +    cl_build_status status;
  2627. +    do
  2628. +    {
  2629. +        if ((ret = clGetProgramBuildInfo(ctx[0].Program, ctx[0].DeviceID, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL)) != CL_SUCCESS) {
  2630. +            LOG_ERR("Error %s when calling clGetProgramBuildInfo for status of build.", err_to_str(ret));
  2631. +            return OCL_ERR_API;
  2632. +        }
  2633. +        port_sleep(1);
  2634. +    }
  2635. +    while(status == CL_BUILD_IN_PROGRESS);
  2636. +
  2637. +    const char *KernelNames[] = { "cn0", "cn1", "cn2", "Blake", "Groestl", "JH", "Skein" };
  2638. +
  2639.      for (int i = 0; i < num_gpus; ++i) {
  2640. -        if ((ret = InitOpenCLGpu(i, opencl_ctx, &ctx[i], source_code.c_str())) != OCL_ERR_SUCCESS) {
  2641. +        if (i > 0) {
  2642. +           ctx[i].Program = ctx[0].Program;
  2643. +        }
  2644. +
  2645. +       for (int k = 0; k < 7; ++k) {
  2646. +           ctx[i].Kernels[k] = clCreateKernel(ctx[i].Program, KernelNames[k], &ret);
  2647. +           if (ret != CL_SUCCESS) {
  2648. +               LOG_ERR("Error %s when calling clCreateKernel for kernel %s.", err_to_str(ret), KernelNames[k]);
  2649. +               return OCL_ERR_API;
  2650. +           }
  2651. +       }
  2652. +
  2653. +        if ((ret = InitOpenCLGpu(i, opencl_ctx, &ctx[i])) != OCL_ERR_SUCCESS) {
  2654.              return ret;
  2655.          }
  2656.      }
  2657. @@ -841,4 +881,4 @@ size_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput)
  2658.      ctx->Nonce += (uint32_t) g_intensity;
  2659.  
  2660.      return OCL_ERR_SUCCESS;
  2661. -}
  2662. +}
  2663. \ No newline at end of file
  2664. diff --git a/src/amd/OclGPU.h b/src/amd/OclGPU.h
  2665. index e912823..1c5fdda 100644
  2666. --- a/src/amd/OclGPU.h
  2667. +++ b/src/amd/OclGPU.h
  2668. @@ -39,7 +39,6 @@
  2669.  
  2670.  
  2671.  uint32_t getNumPlatforms();
  2672. -void printPlatforms();
  2673.  int getAMDPlatformIdx();
  2674.  std::vector<GpuContext> getAMDDevices(int index);
  2675.  
  2676. diff --git a/src/api/ApiState.cpp b/src/api/ApiState.cpp
  2677. index f0ee803..3f21f59 100644
  2678. --- a/src/api/ApiState.cpp
  2679. +++ b/src/api/ApiState.cpp
  2680. @@ -23,7 +23,10 @@
  2681.  
  2682.  #include <math.h>
  2683.  #include <string.h>
  2684. +#include <time.h>
  2685.  #include <uv.h>
  2686. +#include <map>
  2687. +#include <vector>
  2688.  
  2689.  #if _WIN32
  2690.  #   include "winsock2.h"
  2691. @@ -32,17 +35,19 @@
  2692.  #endif
  2693.  
  2694.  
  2695. +#include "amd/Adl.h"
  2696.  #include "api/ApiState.h"
  2697.  #include "Cpu.h"
  2698.  #include "net/Job.h"
  2699. +#include "net/Url.h"
  2700.  #include "Options.h"
  2701.  #include "Platform.h"
  2702.  #include "rapidjson/document.h"
  2703.  #include "rapidjson/stringbuffer.h"
  2704.  #include "rapidjson/prettywriter.h"
  2705. -#include "version.h"
  2706. +#include "workers/Workers.h"
  2707.  #include "workers/Hashrate.h"
  2708. -
  2709. +#include "workers/Handle.h"
  2710.  
  2711.  extern "C"
  2712.  {
  2713. @@ -50,7 +55,7 @@ extern "C"
  2714.  }
  2715.  
  2716.  
  2717. -static inline double normalize(double d)
  2718. +static inline double normalize2(double d)
  2719.  {
  2720.      if (!isnormal(d)) {
  2721.          return 0.0;
  2722. @@ -60,25 +65,37 @@ static inline double normalize(double d)
  2723.  }
  2724.  
  2725.  
  2726. +static inline double normalize3(double d)
  2727. +{
  2728. +    if (!isnormal(d)) {
  2729. +        return 0.0;
  2730. +    }
  2731. +
  2732. +    return floor(d * 1000.0) / 1000.0;
  2733. +}
  2734. +
  2735. +
  2736. +static inline time_t now()
  2737. +{
  2738. +    auto now = std::chrono::system_clock::now();
  2739. +    return std::chrono::system_clock::to_time_t( now );
  2740. +}
  2741. +
  2742. +
  2743.  ApiState::ApiState()
  2744.  {
  2745.      m_threads  = (int) Options::i()->threads().size();
  2746.      m_hashrate = new double[m_threads * 3]();
  2747. +    m_start = now();
  2748.  
  2749.      memset(m_totalHashrate, 0, sizeof(m_totalHashrate));
  2750. -    memset(m_workerId, 0, sizeof(m_workerId));
  2751. +    memset(m_id, 0, sizeof(m_id));
  2752.  
  2753. -    if (Options::i()->apiWorkerId()) {
  2754. -        strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1);
  2755. +    if (Options::i()->id()) {
  2756. +        strncpy(m_id, Options::i()->id(), sizeof(m_id) - 1);
  2757.      }
  2758.      else {
  2759. -        gethostname(m_workerId, sizeof(m_workerId) - 1);
  2760. -    }
  2761. -
  2762. -    genId();
  2763. -
  2764. -    for (const OclThread *thread : Options::i()->threads()) {
  2765. -        m_gpuThreads.push_back(*thread);
  2766. +        gethostname(m_id, sizeof(m_id) - 1);
  2767.      }
  2768.  }
  2769.  
  2770. @@ -94,9 +111,10 @@ char *ApiState::get(const char *url, int *status) const
  2771.      rapidjson::Document doc;
  2772.      doc.SetObject();
  2773.  
  2774. -    getIdentify(doc);
  2775. +    getId(doc);
  2776.      getMiner(doc);
  2777.      getHashrate(doc);
  2778. +    getGpus(doc);
  2779.      getResults(doc);
  2780.      getConnection(doc);
  2781.  
  2782. @@ -136,45 +154,13 @@ char *ApiState::finalize(rapidjson::Document &doc) const
  2783.  }
  2784.  
  2785.  
  2786. -void ApiState::genId()
  2787. -{
  2788. -    memset(m_id, 0, sizeof(m_id));
  2789. -
  2790. -    uv_interface_address_t *interfaces;
  2791. -    int count = 0;
  2792. -
  2793. -    if (uv_interface_addresses(&interfaces, &count) < 0) {
  2794. -        return;
  2795. -    }
  2796. -
  2797. -    for (int i = 0; i < count; i++) {
  2798. -        if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
  2799. -            uint8_t hash[200];
  2800. -            const size_t addrSize = sizeof(interfaces[i].phys_addr);
  2801. -            const size_t inSize   = strlen(APP_KIND) + addrSize;
  2802. -
  2803. -            uint8_t *input = new uint8_t[inSize]();
  2804. -            memcpy(input, interfaces[i].phys_addr, addrSize);
  2805. -            memcpy(input + addrSize, APP_KIND, strlen(APP_KIND));
  2806. -
  2807. -            keccak(input, static_cast<int>(inSize), hash, sizeof(hash));
  2808. -            Job::toHex(hash, 8, m_id);
  2809. -
  2810. -            delete [] input;
  2811. -            break;
  2812. -        }
  2813. -    }
  2814. -
  2815. -    uv_free_interface_addresses(interfaces, count);
  2816. -}
  2817. -
  2818. -
  2819.  void ApiState::getConnection(rapidjson::Document &doc) const
  2820.  {
  2821.      auto &allocator = doc.GetAllocator();
  2822.  
  2823.      rapidjson::Value connection(rapidjson::kObjectType);
  2824.      connection.AddMember("pool",      rapidjson::StringRef(m_network.pool), allocator);
  2825. +    connection.AddMember("user",      rapidjson::StringRef(m_network.userMask), allocator);
  2826.      connection.AddMember("uptime",    m_network.connectionTime(), allocator);
  2827.      connection.AddMember("ping",      m_network.latency(), allocator);
  2828.      connection.AddMember("failures",  m_network.failures, allocator);
  2829. @@ -184,38 +170,114 @@ void ApiState::getConnection(rapidjson::Document &doc) const
  2830.  }
  2831.  
  2832.  
  2833. -void ApiState::getHashrate(rapidjson::Document &doc) const
  2834. +void ApiState::getGpus(rapidjson::Document &doc) const
  2835.  {
  2836.      auto &allocator = doc.GetAllocator();
  2837.  
  2838. -    rapidjson::Value hashrate(rapidjson::kObjectType);
  2839. -    rapidjson::Value total(rapidjson::kArrayType);
  2840. -    rapidjson::Value threads(rapidjson::kArrayType);
  2841. +    rapidjson::Value gpus(rapidjson::kArrayType);
  2842.  
  2843. -    for (int i = 0; i < 3; ++i) {
  2844. -        total.PushBack(normalize(m_totalHashrate[i]), allocator);
  2845. -    }
  2846. +    for (const auto& map : Workers::gpus()) {
  2847. +        std::vector<Handle*> handles = map.second;
  2848. +
  2849. +        rapidjson::Value gpu(rapidjson::kObjectType);
  2850. +        gpu.AddMember("bus_id", handles[0]->ctx()->busId, allocator);
  2851. +        gpu.AddMember("adapter_index", Adl::i()->getAdapterIndex(handles[0]->ctx()->busId), allocator);
  2852. +        gpu.AddMember("device_name", rapidjson::StringRef(handles[0]->ctx()->deviceName.c_str()), allocator);
  2853. +        gpu.AddMember("temperature", Adl::i()->getTemperature(handles[0]->ctx()->busId) / 1000, allocator);
  2854. +
  2855. +        const ADLODNPerformanceStatus* odNPerformanceStatus = Adl::i()->getPerformanceStatus(handles[0]->ctx()->busId);
  2856. +        gpu.AddMember("core_clock", odNPerformanceStatus->iCoreClock / 100, allocator);
  2857. +        gpu.AddMember("memory_clock", odNPerformanceStatus->iMemoryClock / 100, allocator);
  2858. +
  2859. +        const ADLODNFanControl* odNFanControl = Adl::i()->getFanControl(handles[0]->ctx()->busId);
  2860. +        gpu.AddMember("fan_speed", odNFanControl->iCurrentFanSpeed, allocator);
  2861. +
  2862. +        const ADLODNPowerLimitSetting* odNPowerControl = Adl::i()->getPowerLimit(handles[0]->ctx()->busId);
  2863. +
  2864. +        const ADLODNPerformanceLevelsX2* odNSystemClocks = Adl::i()->getSystemClocks(handles[0]->ctx()->busId);
  2865. +        const ADLODNPerformanceLevelsX2* odNMemoryClocks = Adl::i()->getMemoryClocks(handles[0]->ctx()->busId);
  2866. +        rapidjson::Value profile(rapidjson::kObjectType);
  2867. +        rapidjson::Value system(rapidjson::kArrayType);
  2868. +        rapidjson::Value memory(rapidjson::kArrayType);
  2869. +
  2870. +        for (int i=0 ;i <ADL_PERFORMANCE_LEVELS; i++) {
  2871. +            if (odNSystemClocks->aLevels[i].iEnabled) {
  2872. +                rapidjson::Value level(rapidjson::kObjectType);
  2873. +                level.AddMember("clock", odNSystemClocks->aLevels[i].iClock / 100, allocator);
  2874. +                level.AddMember("vddc", normalize3(odNSystemClocks->aLevels[i].iVddc / 1000.0), allocator);
  2875. +                system.PushBack(level, allocator);
  2876. +            }
  2877. +        }
  2878. +
  2879. +        for (int i=0 ;i <ADL_PERFORMANCE_LEVELS; i++) {
  2880. +            if (odNMemoryClocks->aLevels[i].iEnabled) {
  2881. +                rapidjson::Value level(rapidjson::kObjectType);
  2882. +                level.AddMember("clock", odNMemoryClocks->aLevels[i].iClock / 100, allocator);
  2883. +                level.AddMember("vddc", normalize3(odNMemoryClocks->aLevels[i].iVddc / 1000.0), allocator);
  2884. +                memory.PushBack(level, allocator);
  2885. +            }
  2886. +        }
  2887. +
  2888. +        profile.AddMember("system", system, allocator);
  2889. +        profile.AddMember("memory", memory, allocator);
  2890. +        profile.AddMember("target_temperature", odNFanControl->iTargetTemperature, allocator);
  2891. +        profile.AddMember("power_limit", odNPowerControl->iTDPLimit, allocator);
  2892. +
  2893. +        gpu.AddMember("profile", profile, allocator);
  2894. +
  2895. +        rapidjson::Value threads(rapidjson::kArrayType);
  2896. +
  2897. +        double sum_hashrate_10s = 0.0;
  2898. +        double sum_hashrate_60s = 0.0;
  2899. +        double sum_hashrate_15m = 0.0;    
  2900. +
  2901. +        for (const Handle *handle : handles) {
  2902. +            rapidjson::Value thread(rapidjson::kObjectType);
  2903. +            thread.AddMember("intensity", (uint64_t)handle->ctx()->rawIntensity, allocator);
  2904.  
  2905. -    for (int i = 0; i < m_threads * 3; i += 3) {
  2906. -        rapidjson::Value thread(rapidjson::kArrayType);
  2907. -        thread.PushBack(normalize(m_hashrate[i]),     allocator);
  2908. -        thread.PushBack(normalize(m_hashrate[i + 1]), allocator);
  2909. -        thread.PushBack(normalize(m_hashrate[i + 2]), allocator);
  2910. +            int i = handle->threadId() * 3;
  2911. +            double hashrate_10s = normalize2(m_hashrate[i]);
  2912. +            double hashrate_60s = normalize2(m_hashrate[i + 1]);
  2913. +            double hashrate_15m = normalize2(m_hashrate[i + 2]);  
  2914.  
  2915. -        threads.PushBack(thread, allocator);
  2916. +            thread.AddMember("hashrate_10s", hashrate_10s, allocator);
  2917. +            thread.AddMember("hashrate_60s", hashrate_60s, allocator);
  2918. +            thread.AddMember("hashrate_15m", hashrate_15m, allocator);
  2919. +
  2920. +            sum_hashrate_10s += hashrate_10s;
  2921. +            sum_hashrate_60s += hashrate_60s;
  2922. +            sum_hashrate_15m += hashrate_15m;
  2923. +
  2924. +            threads.PushBack(thread, allocator);
  2925. +        }
  2926. +
  2927. +        gpu.AddMember("threads", threads, allocator);
  2928. +
  2929. +        gpu.AddMember("hashrate_10s", sum_hashrate_10s, allocator);
  2930. +        gpu.AddMember("hashrate_60s", sum_hashrate_60s, allocator);
  2931. +        gpu.AddMember("hashrate_15m", sum_hashrate_15m, allocator);
  2932. +
  2933. +        gpus.PushBack(gpu, allocator);
  2934.      }
  2935.  
  2936. -    hashrate.AddMember("total",   total, allocator);
  2937. -    hashrate.AddMember("highest", normalize(m_highestHashrate), allocator);
  2938. -    hashrate.AddMember("threads", threads, allocator);
  2939. -    doc.AddMember("hashrate",     hashrate, allocator);
  2940. +    doc.AddMember("gpus", gpus, allocator);
  2941.  }
  2942.  
  2943.  
  2944. -void ApiState::getIdentify(rapidjson::Document &doc) const
  2945. +void ApiState::getHashrate(rapidjson::Document &doc) const
  2946.  {
  2947. -    doc.AddMember("id",        rapidjson::StringRef(m_id),       doc.GetAllocator());
  2948. -    doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator());
  2949. +    auto &allocator = doc.GetAllocator();
  2950. +
  2951. +    doc.AddMember("hashrate_10s", normalize2(m_totalHashrate[0]), allocator);
  2952. +    doc.AddMember("hashrate_60s", normalize2(m_totalHashrate[1]), allocator);
  2953. +    doc.AddMember("hashrate_15m", normalize2(m_totalHashrate[2]), allocator);
  2954. +    doc.AddMember("hashrate_max", normalize2(m_highestHashrate), allocator);
  2955. +}
  2956. +
  2957. +
  2958. +void ApiState::getId(rapidjson::Document &doc) const
  2959. +{
  2960. +    doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator());
  2961.  }
  2962.  
  2963.  
  2964. @@ -223,19 +285,9 @@ void ApiState::getMiner(rapidjson::Document &doc) const
  2965.  {
  2966.      auto &allocator = doc.GetAllocator();
  2967.  
  2968. -    rapidjson::Value cpu(rapidjson::kObjectType);
  2969. -    cpu.AddMember("brand",   rapidjson::StringRef(Cpu::brand()), allocator);
  2970. -    cpu.AddMember("aes",     Cpu::hasAES(), allocator);
  2971. -    cpu.AddMember("x64",     Cpu::isX64(), allocator);
  2972. -    cpu.AddMember("sockets", Cpu::sockets(), allocator);
  2973. -
  2974. -    doc.AddMember("version",      APP_VERSION, allocator);
  2975. -    doc.AddMember("kind",         APP_KIND, allocator);
  2976. -    doc.AddMember("ua",           rapidjson::StringRef(Platform::userAgent()), allocator);
  2977. -    doc.AddMember("cpu",          cpu, allocator);
  2978. +    doc.AddMember("version",      rapidjson::StringRef(Platform::versionString()), allocator);
  2979.      doc.AddMember("algo",         rapidjson::StringRef(Options::i()->algoName()), allocator);
  2980. -    doc.AddMember("hugepages",    false, allocator);
  2981. -    doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
  2982. +    doc.AddMember("uptime",       difftime(now(), m_start), allocator);
  2983.  }
  2984.  
  2985.  
  2986. @@ -260,4 +312,4 @@ void ApiState::getResults(rapidjson::Document &doc) const
  2987.      results.AddMember("error_log", rapidjson::Value(rapidjson::kArrayType), allocator);
  2988.  
  2989.      doc.AddMember("results", results, allocator);
  2990. -}
  2991. +}
  2992. \ No newline at end of file
  2993. diff --git a/src/api/ApiState.h b/src/api/ApiState.h
  2994. index 3fc641b..479b6a6 100644
  2995. --- a/src/api/ApiState.h
  2996. +++ b/src/api/ApiState.h
  2997. @@ -26,6 +26,8 @@
  2998.  
  2999.  
  3000.  #include <vector>
  3001. +#include <chrono>
  3002. +#include <time.h>
  3003.  
  3004.  
  3005.  #include "api/NetworkState.h"
  3006. @@ -48,21 +50,20 @@ public:
  3007.  
  3008.  private:
  3009.      char *finalize(rapidjson::Document &doc) const;
  3010. -    void genId();
  3011.      void getConnection(rapidjson::Document &doc) const;
  3012. +    void getGpus(rapidjson::Document &doc) const;
  3013.      void getHashrate(rapidjson::Document &doc) const;
  3014. -    void getIdentify(rapidjson::Document &doc) const;
  3015. +    void getId(rapidjson::Document &doc) const;
  3016.      void getMiner(rapidjson::Document &doc) const;
  3017.      void getResults(rapidjson::Document &doc) const;
  3018.  
  3019. -    char m_id[17];
  3020. -    char m_workerId[128];
  3021. +    char m_id[128];
  3022.      double *m_hashrate;
  3023.      double m_highestHashrate;
  3024.      double m_totalHashrate[3];
  3025. +    time_t m_start;
  3026.      int m_threads;
  3027.      NetworkState m_network;
  3028. -    std::vector<OclThread> m_gpuThreads;
  3029.  };
  3030.  
  3031. -#endif /* __APISTATE_H__ */
  3032. +#endif /* __APISTATE_H__ */
  3033. \ No newline at end of file
  3034. diff --git a/src/api/Httpd.cpp b/src/api/Httpd.cpp
  3035. index 861086e..99bb9d1 100644
  3036. --- a/src/api/Httpd.cpp
  3037. +++ b/src/api/Httpd.cpp
  3038. @@ -4,8 +4,8 @@
  3039.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  3040.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  3041.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  3042. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  3043. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  3044. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  3045. + *
  3046.   *
  3047.   *   This program is free software: you can redistribute it and/or modify
  3048.   *   it under the terms of the GNU General Public License as published by
  3049. @@ -45,19 +45,7 @@ bool Httpd::start()
  3050.          return false;
  3051.      }
  3052.  
  3053. -    unsigned int flags = MHD_USE_SELECT_INTERNALLY;
  3054. -
  3055. -#   if MHD_VERSION >= 0x00093500
  3056. -    if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) {
  3057. -        flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
  3058. -    }
  3059. -
  3060. -    if (MHD_is_feature_supported(MHD_FEATURE_IPv6)) {
  3061. -        flags |= MHD_USE_DUAL_STACK;
  3062. -    }
  3063. -#   endif
  3064. -
  3065. -    m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
  3066. +    m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
  3067.      if (!m_daemon) {
  3068.          LOG_ERR("HTTP Daemon failed to start.");
  3069.          return false;
  3070. @@ -123,6 +111,6 @@ int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url
  3071.          return MHD_NO;
  3072.      }
  3073.  
  3074. -    MHD_Response *rsp = MHD_create_response_from_buffer(strlen(buf), (void*) buf, MHD_RESPMEM_MUST_FREE);
  3075. +    MHD_Response *rsp = MHD_create_response_from_buffer(strlen(buf), (void*)buf, MHD_RESPMEM_MUST_FREE);
  3076.      return done(connection, status, rsp);
  3077.  }
  3078. diff --git a/src/api/Httpd.h b/src/api/Httpd.h
  3079. index 30618e2..7a4dd93 100644
  3080. --- a/src/api/Httpd.h
  3081. +++ b/src/api/Httpd.h
  3082. @@ -4,8 +4,8 @@
  3083.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  3084.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  3085.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  3086. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  3087. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  3088. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  3089. + *
  3090.   *
  3091.   *   This program is free software: you can redistribute it and/or modify
  3092.   *   it under the terms of the GNU General Public License as published by
  3093. diff --git a/src/api/NetworkState.cpp b/src/api/NetworkState.cpp
  3094. index d3ffddd..f918c95 100644
  3095. --- a/src/api/NetworkState.cpp
  3096. +++ b/src/api/NetworkState.cpp
  3097. @@ -23,8 +23,8 @@
  3098.  
  3099.  
  3100.  #include <algorithm>
  3101. -#include <stdio.h>
  3102.  #include <string.h>
  3103. +#include <string>
  3104.  #include <uv.h>
  3105.  
  3106.  
  3107. @@ -40,13 +40,14 @@ NetworkState::NetworkState() :
  3108.      total(0),
  3109.      m_active(false)
  3110.  {
  3111. +    memset(userMask, 0, sizeof(userMask));
  3112.      memset(pool, 0, sizeof(pool));
  3113.  }
  3114.  
  3115.  
  3116.  int NetworkState::connectionTime() const
  3117.  {
  3118. -    return m_active ? (int)((uv_now(uv_default_loop()) - m_connectionTime) / 1000) : 0;
  3119. +    return m_active ? ((uv_now(uv_default_loop()) - m_connectionTime) / 1000) : 0;
  3120.  }
  3121.  
  3122.  
  3123. @@ -56,7 +57,7 @@ uint32_t NetworkState::avgTime() const
  3124.          return 0;
  3125.      }
  3126.  
  3127. -    return connectionTime() / (uint32_t)m_latency.size();
  3128. +    return (uint32_t) connectionTime() / m_latency.size();
  3129.  }
  3130.  
  3131.  
  3132. @@ -94,6 +95,12 @@ void NetworkState::add(const SubmitResult &result, const char *error)
  3133.  }
  3134.  
  3135.  
  3136. +void NetworkState::setUserMask(const char *user)
  3137. +{
  3138. +    snprintf(userMask, sizeof(userMask) - 1, "%s%s", std::string(strlen(user) - 4, '*').c_str(), std::string(user).substr(strlen(user) - 4).c_str());
  3139. +}
  3140. +
  3141. +
  3142.  void NetworkState::setPool(const char *host, int port, const char *ip)
  3143.  {
  3144.      snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port);
  3145. diff --git a/src/api/NetworkState.h b/src/api/NetworkState.h
  3146. index d099807..cbd516a 100644
  3147. --- a/src/api/NetworkState.h
  3148. +++ b/src/api/NetworkState.h
  3149. @@ -41,9 +41,11 @@ public:
  3150.      uint32_t avgTime() const;
  3151.      uint32_t latency() const;
  3152.      void add(const SubmitResult &result, const char *error);
  3153. +    void setUserMask(const char *user);
  3154.      void setPool(const char *host, int port, const char *ip);
  3155.      void stop();
  3156.  
  3157. +    char userMask[256];
  3158.      char pool[256];
  3159.      std::array<uint64_t, 10> topDiff { { } };
  3160.      uint32_t diff;
  3161. diff --git a/src/config.json b/src/config.json
  3162. index 750f17b..66497a7 100644
  3163. --- a/src/config.json
  3164. +++ b/src/config.json
  3165. @@ -12,12 +12,11 @@
  3166.      "threads": null,
  3167.      "pools": [
  3168.          {
  3169. -            "url": "failover.xmrig.com:443",
  3170. -            "user": "YOUR_WALLET",
  3171. +            "url": "pool.monero.hashvault.pro:5555",
  3172. +            "user": "",
  3173.              "pass": "x",
  3174.              "keepalive": true,
  3175. -            "nicehash": false,
  3176. -            "variant": -1
  3177. +            "nicehash": false
  3178.          }
  3179.      ],
  3180.      "api": {
  3181. diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp
  3182. index d4b0a39..c6fecad 100644
  3183. --- a/src/crypto/CryptoNight.cpp
  3184. +++ b/src/crypto/CryptoNight.cpp
  3185. @@ -29,47 +29,46 @@
  3186.  #include "net/Job.h"
  3187.  #include "net/JobResult.h"
  3188.  #include "Options.h"
  3189. -#include "xmrig.h"
  3190.  
  3191.  
  3192. -void (*cryptonight_hash_ctx)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = nullptr;
  3193. +void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) = nullptr;
  3194.  
  3195.  
  3196.  #define CRYPTONIGHT_HASH(NAME, ITERATIONS, MEM, MASK, SOFT_AES) \
  3197.      switch (variant) { \
  3198. -    case xmrig::VARIANT_V1: \
  3199. -        return cryptonight_##NAME##_hash<ITERATIONS, MEM, MASK, SOFT_AES, xmrig::VARIANT_V1>(input, size, output, ctx); \
  3200. +    case Options::VARIANT_V1: \
  3201. +        return cryptonight_##NAME##_hash<ITERATIONS, MEM, MASK, SOFT_AES, Options::VARIANT_V1>(input, size, output, ctx); \
  3202.      \
  3203. -    case xmrig::VARIANT_NONE: \
  3204. -        return cryptonight_##NAME##_hash<ITERATIONS, MEM, MASK, SOFT_AES, xmrig::VARIANT_NONE>(input, size, output, ctx); \
  3205. +    case Options::VARIANT_NONE: \
  3206. +        return cryptonight_##NAME##_hash<ITERATIONS, MEM, MASK, SOFT_AES, Options::VARIANT_NONE>(input, size, output, ctx); \
  3207.      \
  3208.      default: \
  3209.          break; \
  3210.      }
  3211.  
  3212.  
  3213. -static void cryptonight_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx *ctx, int variant) {
  3214. +static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx, int variant) {
  3215.      CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, false)
  3216.  }
  3217.  
  3218.  
  3219. -static void cryptonight_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
  3220. +static void cryptonight_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) {
  3221.      CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, true)
  3222.  }
  3223.  
  3224.  
  3225.  #ifndef XMRIG_NO_AEON
  3226. -static void cryptonight_lite_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
  3227. +static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) {
  3228.      CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, false)
  3229.  }
  3230.  
  3231.  
  3232. -static void cryptonight_lite_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) {
  3233. +static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) {
  3234.      CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, true)
  3235.  }
  3236.  
  3237.  
  3238. -void (*cryptonight_variations[8])(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = {
  3239. +void (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) = {
  3240.              cryptonight_av1_aesni,
  3241.              nullptr,
  3242.              cryptonight_av3_softaes,
  3243. @@ -80,7 +79,7 @@ void (*cryptonight_variations[8])(const uint8_t *input, size_t size, uint8_t *ou
  3244.              nullptr
  3245.          };
  3246.  #else
  3247. -void (*cryptonight_variations[4])(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = {
  3248. +void (*cryptonight_variations[4])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) = {
  3249.              cryptonight_av1_aesni,
  3250.              nullptr,
  3251.              cryptonight_av3_softaes,
  3252. @@ -104,7 +103,7 @@ bool CryptoNight::init(int algo, int variant)
  3253.      }
  3254.  
  3255.  #   ifndef XMRIG_NO_AEON
  3256. -    const int index = algo == xmrig::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1);
  3257. +    const int index = algo == Options::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1);
  3258.  #   else
  3259.      const int index = variant - 1;
  3260.  #   endif
  3261. @@ -126,14 +125,14 @@ bool CryptoNight::selfTest(int algo) {
  3262.          return false;
  3263.      }
  3264.  
  3265. -    uint8_t output[32];
  3266. +    char output[32];
  3267.  
  3268.      cryptonight_ctx *ctx = static_cast<cryptonight_ctx *>(_mm_malloc(sizeof(cryptonight_ctx), 16));
  3269.  
  3270.      cryptonight_hash_ctx(test_input, 76, output, ctx, 0);
  3271.  
  3272.  #   ifndef XMRIG_NO_AEON
  3273. -    bool rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output_v0_lite : test_output_v0, 32) == 0;
  3274. +    bool rc = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_v0_lite : test_output_v0, 32) == 0;
  3275.  #   else
  3276.      bool rc = memcmp(output, test_output_v0, 32) == 0;
  3277.  #   endif
  3278. @@ -142,7 +141,7 @@ bool CryptoNight::selfTest(int algo) {
  3279.          cryptonight_hash_ctx(test_input, 76, output, ctx, 1);
  3280.  
  3281.  #       ifndef XMRIG_NO_AEON
  3282. -        rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output_v1_lite : test_output_v1, 32) == 0;
  3283. +        rc = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output_v1_lite : test_output_v1, 32) == 0;
  3284.  #       else
  3285.          rc = memcmp(output, test_output_v1, 32) == 0;
  3286.  #       endif
  3287. @@ -151,4 +150,4 @@ bool CryptoNight::selfTest(int algo) {
  3288.      _mm_free(ctx);
  3289.  
  3290.      return rc;
  3291. -}
  3292. +}
  3293. \ No newline at end of file
  3294. diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h
  3295. index a667a3b..3c6146a 100644
  3296. --- a/src/crypto/CryptoNight_monero.h
  3297. +++ b/src/crypto/CryptoNight_monero.h
  3298. @@ -27,22 +27,12 @@
  3299.  
  3300.  
  3301.  // VARIANT ALTERATIONS
  3302. -#ifndef XMRIG_ARM
  3303. -#   define VARIANT1_INIT(part) \
  3304. +#define VARIANT1_INIT(part) \
  3305.      uint64_t tweak1_2_##part = 0; \
  3306.      if (VARIANT > 0) { \
  3307. -        tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(input + 35 + part * size) ^ \
  3308. +        tweak1_2_##part = (*reinterpret_cast<const uint64_t*>(reinterpret_cast<const uint8_t*>(input) + 35 + part * size) ^ \
  3309.                            *(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24)); \
  3310.      }
  3311. -#else
  3312. -#   define VARIANT1_INIT(part) \
  3313. -    uint64_t tweak1_2_##part = 0; \
  3314. -    if (VARIANT > 0) { \
  3315. -        volatile const uint64_t a = *reinterpret_cast<const uint64_t*>(input + 35 + part * size); \
  3316. -        volatile const uint64_t b = *(reinterpret_cast<const uint64_t*>(ctx->state##part) + 24); \
  3317. -        tweak1_2_##part = a ^ b; \
  3318. -    }
  3319. -#endif
  3320.  
  3321.  #define VARIANT1_1(p) \
  3322.      if (VARIANT > 0) { \
  3323. diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h
  3324. index 059163c..b1bff94 100644
  3325. --- a/src/crypto/CryptoNight_x86.h
  3326. +++ b/src/crypto/CryptoNight_x86.h
  3327. @@ -49,27 +49,27 @@ extern "C"
  3328.  }
  3329.  
  3330.  
  3331. -static inline void do_blake_hash(const uint8_t *input, size_t len, uint8_t *output) {
  3332. -    blake256_hash(output, input, len);
  3333. +static inline void do_blake_hash(const void* input, size_t len, char* output) {
  3334. +    blake256_hash(reinterpret_cast<uint8_t*>(output), static_cast<const uint8_t*>(input), len);
  3335.  }
  3336.  
  3337.  
  3338. -static inline void do_groestl_hash(const uint8_t *input, size_t len, uint8_t *output) {
  3339. -    groestl(input, len * 8, output);
  3340. +static inline void do_groestl_hash(const void* input, size_t len, char* output) {
  3341. +    groestl(static_cast<const uint8_t*>(input), len * 8, reinterpret_cast<uint8_t*>(output));
  3342.  }
  3343.  
  3344.  
  3345. -static inline void do_jh_hash(const uint8_t *input, size_t len, uint8_t *output) {
  3346. -    jh_hash(32 * 8, input, 8 * len, output);
  3347. +static inline void do_jh_hash(const void* input, size_t len, char* output) {
  3348. +    jh_hash(32 * 8, static_cast<const uint8_t*>(input), 8 * len, reinterpret_cast<uint8_t*>(output));
  3349.  }
  3350.  
  3351.  
  3352. -static inline void do_skein_hash(const uint8_t *input, size_t len, uint8_t *output) {
  3353. -    xmr_skein(input, output);
  3354. +static inline void do_skein_hash(const void* input, size_t len, char* output) {
  3355. +    xmr_skein(static_cast<const uint8_t*>(input), reinterpret_cast<uint8_t*>(output));
  3356.  }
  3357.  
  3358.  
  3359. -void (* const extra_hashes[4])(const uint8_t *, size_t, uint8_t *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
  3360. +void (* const extra_hashes[4])(const void *, size_t, char *) = {do_blake_hash, do_groestl_hash, do_jh_hash, do_skein_hash};
  3361.  
  3362.  
  3363.  
  3364. @@ -310,9 +310,9 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output)
  3365.  
  3366.  
  3367.  template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES, int VARIANT>
  3368. -inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
  3369. +inline void cryptonight_single_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx)
  3370.  {
  3371. -    keccak(input, (int) size, ctx->state0, 200);
  3372. +    keccak(static_cast<const uint8_t*>(input), (int) size, ctx->state0, 200);
  3373.  
  3374.      VARIANT1_INIT(0);
  3375.  
  3376. @@ -363,8 +363,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
  3377.      cn_implode_scratchpad<MEM, SOFT_AES>((__m128i*) ctx->memory, (__m128i*) ctx->state0);
  3378.  
  3379.      keccakf(h0, 24);
  3380. -    extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output);
  3381. +    extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, static_cast<char*>(output));
  3382.  }
  3383.  
  3384. -
  3385.  #endif /* __CRYPTONIGHT_X86_H__ */
  3386. diff --git a/src/interfaces/IStrategy.h b/src/interfaces/IStrategy.h
  3387. index 9f2795f..660529e 100644
  3388. --- a/src/interfaces/IStrategy.h
  3389. +++ b/src/interfaces/IStrategy.h
  3390. @@ -4,8 +4,8 @@
  3391.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  3392.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  3393.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  3394. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  3395. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  3396. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  3397. + *
  3398.   *
  3399.   *   This program is free software: you can redistribute it and/or modify
  3400.   *   it under the terms of the GNU General Public License as published by
  3401. diff --git a/src/interfaces/IStrategyListener.h b/src/interfaces/IStrategyListener.h
  3402. index 9f2c448..60f9573 100644
  3403. --- a/src/interfaces/IStrategyListener.h
  3404. +++ b/src/interfaces/IStrategyListener.h
  3405. @@ -4,8 +4,8 @@
  3406.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  3407.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  3408.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  3409. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  3410. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  3411. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  3412. + *
  3413.   *
  3414.   *   This program is free software: you can redistribute it and/or modify
  3415.   *   it under the terms of the GNU General Public License as published by
  3416. @@ -39,10 +39,10 @@ class IStrategyListener
  3417.  public:
  3418.      virtual ~IStrategyListener() {}
  3419.  
  3420. -    virtual void onActive(IStrategy *strategy, Client *client)                                                        = 0;
  3421. -    virtual void onJob(IStrategy *strategy, Client *client, const Job &job)                                           = 0;
  3422. -    virtual void onPause(IStrategy *strategy)                                                                         = 0;
  3423. -    virtual void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) = 0;
  3424. +    virtual void onActive(Client *client)                                                        = 0;
  3425. +    virtual void onJob(Client *client, const Job &job)                                           = 0;
  3426. +    virtual void onPause(IStrategy *strategy)                                                    = 0;
  3427. +    virtual void onResultAccepted(Client *client, const SubmitResult &result, const char *error) = 0;
  3428.  };
  3429.  
  3430.  
  3431. diff --git a/src/net/Client.cpp b/src/net/Client.cpp
  3432. index c8a93f2..f6543b4 100644
  3433. --- a/src/net/Client.cpp
  3434. +++ b/src/net/Client.cpp
  3435. @@ -21,7 +21,6 @@
  3436.   *   along with this program. If not, see <http://www.gnu.org/licenses/>.
  3437.   */
  3438.  
  3439. -#include <assert.h>
  3440.  #include <inttypes.h>
  3441.  #include <iterator>
  3442.  #include <stdio.h>
  3443. @@ -66,7 +65,6 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
  3444.      m_recvBufPos(0),
  3445.      m_state(UnconnectedState),
  3446.      m_expire(0),
  3447. -    m_jobs(0),
  3448.      m_stream(nullptr),
  3449.      m_socket(nullptr)
  3450.  {
  3451. @@ -113,20 +111,6 @@ void Client::connect(const Url *url)
  3452.  }
  3453.  
  3454.  
  3455. -void Client::deleteLater()
  3456. -{
  3457. -    if (!m_listener) {
  3458. -        return;
  3459. -    }
  3460. -
  3461. -    m_listener = nullptr;
  3462. -
  3463. -    if (!disconnect()) {
  3464. -        delete this;
  3465. -    }
  3466. -}
  3467. -
  3468. -
  3469.  void Client::setUrl(const Url *url)
  3470.  {
  3471.      if (!url || !url->isValid()) {
  3472. @@ -187,12 +171,7 @@ int64_t Client::submit(const JobResult &result)
  3473.      const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
  3474.                                   m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
  3475.  
  3476. -#   ifdef XMRIG_PROXY_PROJECT
  3477. -    m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
  3478. -#   else
  3479.      m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
  3480. -#   endif
  3481. -
  3482.      return send(size);
  3483.  }
  3484.  
  3485. @@ -205,28 +184,7 @@ bool Client::close()
  3486.  
  3487.      setState(ClosingState);
  3488.  
  3489. -    uv_stream_t *stream = reinterpret_cast<uv_stream_t*>(m_socket);
  3490. -
  3491. -    if (uv_is_readable(stream) == 1) {
  3492. -        uv_read_stop(stream);
  3493. -    }
  3494. -
  3495. -    if (uv_is_writable(stream) == 1) {
  3496. -        const int rc = uv_shutdown(new uv_shutdown_t, stream, [](uv_shutdown_t* req, int status) {
  3497. -            if (uv_is_closing(reinterpret_cast<uv_handle_t*>(req->handle)) == 0) {
  3498. -                uv_close(reinterpret_cast<uv_handle_t*>(req->handle), Client::onClose);
  3499. -            }
  3500. -
  3501. -            delete req;
  3502. -        });
  3503. -
  3504. -        assert(rc == 0);
  3505. -
  3506. -        if (rc != 0) {
  3507. -            onClose();
  3508. -        }
  3509. -    }
  3510. -    else {
  3511. +    if (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_socket)) == 0) {
  3512.          uv_close(reinterpret_cast<uv_handle_t*>(m_socket), Client::onClose);
  3513.      }
  3514.  
  3515. @@ -263,14 +221,7 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
  3516.          return false;
  3517.      }
  3518.  
  3519. -#   ifdef XMRIG_PROXY_PROJECT
  3520. -    Job job(m_id, m_url.variant());
  3521. -    job.setClientId(m_rpcId);
  3522. -    job.setCoin(m_url.coin());
  3523. -#   else
  3524.      Job job(m_id, m_nicehash, m_url.algo(), m_url.variant());
  3525. -#   endif
  3526. -
  3527.      if (!job.setId(params["job_id"].GetString())) {
  3528.          *code = 3;
  3529.          return false;
  3530. @@ -294,22 +245,17 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
  3531.          job.setVariant(params["variant"].GetInt());
  3532.      }
  3533.  
  3534. -    if (m_job != job) {
  3535. -        m_jobs++;
  3536. -        m_job = std::move(job);
  3537. -        return true;
  3538. -    }
  3539. +    if (m_job == job) {
  3540. +        if (!m_quiet) {
  3541. +            LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
  3542. +        }
  3543.  
  3544. -    if (m_jobs == 0) { // https://github.com/xmrig/xmrig/issues/459
  3545. +        close();
  3546.          return false;
  3547.      }
  3548.  
  3549. -    if (!m_quiet) {
  3550. -        LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
  3551. -    }
  3552. -
  3553. -    close();
  3554. -    return false;
  3555. +    m_job = std::move(job);
  3556. +    return true;
  3557.  }
  3558.  
  3559.  
  3560. @@ -320,18 +266,13 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
  3561.          return false;
  3562.      }
  3563.  
  3564. -#   ifndef XMRIG_PROXY_PROJECT
  3565.      m_nicehash = m_url.isNicehash();
  3566. -#   endif
  3567.  
  3568.      if (result.HasMember("extensions")) {
  3569.          parseExtensions(result["extensions"]);
  3570.      }
  3571.  
  3572. -    const bool rc = parseJob(result["job"], code);
  3573. -    m_jobs = 0;
  3574. -
  3575. -    return rc;
  3576. +    return parseJob(result["job"], code);
  3577.  }
  3578.  
  3579.  
  3580. @@ -346,7 +287,7 @@ int Client::resolve(const char *host)
  3581.          m_failures = 0;
  3582.      }
  3583.  
  3584. -    const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints);
  3585. +    const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
  3586.      if (r) {
  3587.          if (!m_quiet) {
  3588.              LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r));
  3589. @@ -457,18 +398,6 @@ void Client::login()
  3590.  }
  3591.  
  3592.  
  3593. -void Client::onClose()
  3594. -{
  3595. -    delete m_socket;
  3596. -
  3597. -    m_stream = nullptr;
  3598. -    m_socket = nullptr;
  3599. -    setState(UnconnectedState);
  3600. -
  3601. -    reconnect();
  3602. -}
  3603. -
  3604. -
  3605.  void Client::parse(char *line, size_t len)
  3606.  {
  3607.      startTimeout();
  3608. @@ -478,10 +407,7 @@ void Client::parse(char *line, size_t len)
  3609.      LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
  3610.  
  3611.      if (len < 32 || line[0] != '{') {
  3612. -        if (!m_quiet) {
  3613. -            LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
  3614. -        }
  3615. -
  3616. +        LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
  3617.          return;
  3618.      }
  3619.  
  3620. @@ -612,12 +538,6 @@ void Client::ping()
  3621.  
  3622.  void Client::reconnect()
  3623.  {
  3624. -    if (!m_listener) {
  3625. -        delete this;
  3626. -
  3627. -        return;
  3628. -    }
  3629. -
  3630.      setState(ConnectingState);
  3631.  
  3632.  #   ifndef XMRIG_PROXY_PROJECT
  3633. @@ -666,9 +586,6 @@ void Client::startTimeout()
  3634.  void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
  3635.  {
  3636.      auto client = getClient(handle->data);
  3637. -    if (!client) {
  3638. -        return;
  3639. -    }
  3640.  
  3641.      buf->base = &client->m_recvBuf.base[client->m_recvBufPos];
  3642.      buf->len  = client->m_recvBuf.len - client->m_recvBufPos;
  3643. @@ -678,21 +595,20 @@ void Client::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
  3644.  void Client::onClose(uv_handle_t *handle)
  3645.  {
  3646.      auto client = getClient(handle->data);
  3647. -    if (!client) {
  3648. -        return;
  3649. -    }
  3650.  
  3651. -    client->onClose();
  3652. +    delete client->m_socket;
  3653. +
  3654. +    client->m_stream = nullptr;
  3655. +    client->m_socket = nullptr;
  3656. +    client->setState(UnconnectedState);
  3657. +
  3658. +    client->reconnect();
  3659.  }
  3660.  
  3661.  
  3662.  void Client::onConnect(uv_connect_t *req, int status)
  3663.  {
  3664.      auto client = getClient(req->data);
  3665. -    if (!client) {
  3666. -        return;
  3667. -    }
  3668. -
  3669.      if (status < 0) {
  3670.          if (!client->m_quiet) {
  3671.              LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
  3672. @@ -717,10 +633,6 @@ void Client::onConnect(uv_connect_t *req, int status)
  3673.  void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
  3674.  {
  3675.      auto client = getClient(stream->data);
  3676. -    if (!client) {
  3677. -        return;
  3678. -    }
  3679. -
  3680.      if (nread < 0) {
  3681.          if (nread != UV_EOF && !client->m_quiet) {
  3682.              LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread));
  3683. @@ -767,15 +679,8 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
  3684.  void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
  3685.  {
  3686.      auto client = getClient(req->data);
  3687. -    if (!client) {
  3688. -        return;
  3689. -    }
  3690. -
  3691.      if (status < 0) {
  3692. -        if (!client->m_quiet) {
  3693. -            LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
  3694. -        }
  3695. -
  3696. +        LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
  3697.          return client->reconnect();
  3698.      }
  3699.  
  3700. @@ -796,9 +701,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res)
  3701.      }
  3702.  
  3703.      if (ipv4.empty() && ipv6.empty()) {
  3704. -        if (!client->m_quiet) {
  3705. -            LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port());
  3706. -        }
  3707. +        LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port());
  3708.  
  3709.          uv_freeaddrinfo(res);
  3710.          return client->reconnect();
  3711. diff --git a/src/net/Client.h b/src/net/Client.h
  3712. index fff7a15..f5cb91f 100644
  3713. --- a/src/net/Client.h
  3714. +++ b/src/net/Client.h
  3715. @@ -30,7 +30,7 @@
  3716.  #include <vector>
  3717.  
  3718.  
  3719. -#include "net/Id.h"
  3720. +#include "net/JobId.h"
  3721.  #include "net/Job.h"
  3722.  #include "net/SubmitResult.h"
  3723.  #include "net/Url.h"
  3724. @@ -56,16 +56,17 @@ public:
  3725.      constexpr static int kKeepAliveTimeout = 60 * 1000;
  3726.  
  3727.      Client(int id, const char *agent, IClientListener *listener);
  3728. +    ~Client();
  3729.  
  3730.      bool disconnect();
  3731.      int64_t submit(const JobResult &result);
  3732.      void connect();
  3733.      void connect(const Url *url);
  3734. -    void deleteLater();
  3735.      void setUrl(const Url *url);
  3736.      void tick(uint64_t now);
  3737.  
  3738.      inline bool isReady() const              { return m_state == ConnectedState && m_failures == 0; }
  3739. +    inline const char *user() const          { return m_url.user(); }
  3740.      inline const char *host() const          { return m_url.host(); }
  3741.      inline const char *ip() const            { return m_ip; }
  3742.      inline const Job &job() const            { return m_job; }
  3743. @@ -76,8 +77,6 @@ public:
  3744.      inline void setRetryPause(int ms)        { m_retryPause = ms; }
  3745.  
  3746.  private:
  3747. -    ~Client();
  3748. -
  3749.      bool close();
  3750.      bool isCriticalError(const char *message);
  3751.      bool parseJob(const rapidjson::Value &params, int *code);
  3752. @@ -87,7 +86,6 @@ private:
  3753.      void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
  3754.      void connect(sockaddr *addr);
  3755.      void login();
  3756. -    void onClose();
  3757.      void parse(char *line, size_t len);
  3758.      void parseExtensions(const rapidjson::Value &value);
  3759.      void parseNotification(const char *method, const rapidjson::Value &params, const rapidjson::Value &error);
  3760. @@ -123,13 +121,12 @@ private:
  3761.      static int64_t m_sequence;
  3762.      std::map<int64_t, SubmitResult> m_results;
  3763.      uint64_t m_expire;
  3764. -    uint64_t m_jobs;
  3765.      Url m_url;
  3766.      uv_buf_t m_recvBuf;
  3767.      uv_getaddrinfo_t m_resolver;
  3768.      uv_stream_t *m_stream;
  3769.      uv_tcp_t *m_socket;
  3770. -    xmrig::Id m_rpcId;
  3771. +    JobId m_rpcId;
  3772.  
  3773.  #   ifndef XMRIG_PROXY_PROJECT
  3774.      uv_timer_t m_keepAliveTimer;
  3775. @@ -137,4 +134,4 @@ private:
  3776.  };
  3777.  
  3778.  
  3779. -#endif /* __CLIENT_H__ */
  3780. +#endif /* __CLIENT_H__ */
  3781. \ No newline at end of file
  3782. diff --git a/src/net/Job.cpp b/src/net/Job.cpp
  3783. index 7d137fa..93a3d4e 100644
  3784. --- a/src/net/Job.cpp
  3785. +++ b/src/net/Job.cpp
  3786. @@ -59,10 +59,10 @@ static inline char hf_bin2hex(unsigned char c)
  3787.  Job::Job() :
  3788.      m_nicehash(false),
  3789.      m_coin(),
  3790. -    m_algo(xmrig::ALGO_CRYPTONIGHT),
  3791. +    m_algo(Options::ALGO_CRYPTONIGHT),
  3792.      m_poolId(-2),
  3793.      m_threadId(-1),
  3794. -    m_variant(xmrig::VARIANT_AUTO),
  3795. +    m_variant(Options::VARIANT_AUTO),
  3796.      m_size(0),
  3797.      m_diff(0),
  3798.      m_target(0),
  3799. @@ -164,16 +164,16 @@ void Job::setCoin(const char *coin)
  3800.      }
  3801.  
  3802.      strncpy(m_coin, coin, sizeof(m_coin));
  3803. -    m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::ALGO_CRYPTONIGHT_LITE : xmrig::ALGO_CRYPTONIGHT;
  3804. +    m_algo = strcmp(m_coin, "AEON") == 0 ? Options::ALGO_CRYPTONIGHT_LITE : Options::ALGO_CRYPTONIGHT;
  3805.  }
  3806.  
  3807.  
  3808.  void Job::setVariant(int variant)
  3809.  {
  3810.      switch (variant) {
  3811. -    case xmrig::VARIANT_AUTO:
  3812. -    case xmrig::VARIANT_NONE:
  3813. -    case xmrig::VARIANT_V1:
  3814. +    case Options::VARIANT_AUTO:
  3815. +    case Options::VARIANT_NONE:
  3816. +    case Options::VARIANT_V1:
  3817.          m_variant = variant;
  3818.          break;
  3819.  
  3820. @@ -210,9 +210,3 @@ bool Job::operator==(const Job &other) const
  3821.  {
  3822.      return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0;
  3823.  }
  3824. -
  3825. -
  3826. -bool Job::operator!=(const Job &other) const
  3827. -{
  3828. -    return m_id != other.m_id || memcmp(m_blob, other.m_blob, sizeof(m_blob)) != 0;
  3829. -}
  3830. diff --git a/src/net/Job.h b/src/net/Job.h
  3831. index b8b9d6b..e1718df 100644
  3832. --- a/src/net/Job.h
  3833. +++ b/src/net/Job.h
  3834. @@ -30,8 +30,8 @@
  3835.  #include <stdint.h>
  3836.  
  3837.  
  3838. -#include "net/Id.h"
  3839. -#include "xmrig.h"
  3840. +#include "net/JobId.h"
  3841. +#include "Options.h"
  3842.  
  3843.  
  3844.  class Job
  3845. @@ -52,16 +52,15 @@ public:
  3846.      inline const char *coin() const        { return m_coin; }
  3847.      inline const uint32_t *nonce() const   { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
  3848.      inline const uint8_t *blob() const     { return m_blob; }
  3849. -    inline const xmrig::Id &id() const     { return m_id; }
  3850. +    inline const JobId &id() const         { return m_id; }
  3851.      inline int poolId() const              { return m_poolId; }
  3852.      inline int threadId() const            { return m_threadId; }
  3853. -    inline int variant() const             { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? 1 : 0) : m_variant); }
  3854. +    inline int variant() const             { return (m_variant == Options::VARIANT_AUTO ? (m_blob[0] > 6 ? 1 : 0) : m_variant); }
  3855.      inline size_t size() const             { return m_size; }
  3856.      inline uint32_t *nonce()               { return reinterpret_cast<uint32_t*>(m_blob + 39); }
  3857.      inline uint32_t diff() const           { return (uint32_t) m_diff; }
  3858.      inline uint64_t target() const         { return m_target; }
  3859.      inline void setNicehash(bool nicehash) { m_nicehash = nicehash; }
  3860. -    inline void setPoolId(int poolId)      { m_poolId = poolId; }
  3861.      inline void setThreadId(int threadId)  { m_threadId = threadId; }
  3862.  
  3863.      static bool fromHex(const char* in, unsigned int len, unsigned char* out);
  3864. @@ -70,7 +69,6 @@ public:
  3865.      static void toHex(const unsigned char* in, unsigned int len, char* out);
  3866.  
  3867.      bool operator==(const Job &other) const;
  3868. -    bool operator!=(const Job &other) const;
  3869.  
  3870.  private:
  3871.      bool m_nicehash;
  3872. @@ -83,7 +81,7 @@ private:
  3873.      uint64_t m_diff;
  3874.      uint64_t m_target;
  3875.      uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk.
  3876. -    xmrig::Id m_id;
  3877. +    JobId m_id;
  3878.  };
  3879.  
  3880.  #endif /* __JOB_H__ */
  3881. diff --git a/src/net/JobId.h b/src/net/JobId.h
  3882. new file mode 100644
  3883. index 0000000..0618977
  3884. --- /dev/null
  3885. +++ b/src/net/JobId.h
  3886. @@ -0,0 +1,83 @@
  3887. +/* XMRig
  3888. + * Copyright 2010      Jeff Garzik <jgarzik@pobox.com>
  3889. + * Copyright 2012-2014 pooler      <pooler@litecoinpool.org>
  3890. + * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  3891. + * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  3892. + * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  3893. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  3894. + *
  3895. + *
  3896. + *   This program is free software: you can redistribute it and/or modify
  3897. + *   it under the terms of the GNU General Public License as published by
  3898. + *   the Free Software Foundation, either version 3 of the License, or
  3899. + *   (at your option) any later version.
  3900. + *
  3901. + *   This program is distributed in the hope that it will be useful,
  3902. + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  3903. + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  3904. + *   GNU General Public License for more details.
  3905. + *
  3906. + *   You should have received a copy of the GNU General Public License
  3907. + *   along with this program. If not, see <http://www.gnu.org/licenses/>.
  3908. + */
  3909. +
  3910. +#ifndef __JOBID_H__
  3911. +#define __JOBID_H__
  3912. +
  3913. +
  3914. +#include <string.h>
  3915. +
  3916. +
  3917. +class JobId
  3918. +{
  3919. +public:
  3920. +    inline JobId()
  3921. +    {
  3922. +        memset(m_data, 0, sizeof(m_data));
  3923. +    }
  3924. +
  3925. +
  3926. +    inline JobId(const char *id, size_t sizeFix = 0)
  3927. +    {
  3928. +        setId(id, sizeFix);
  3929. +    }
  3930. +
  3931. +
  3932. +    inline bool operator==(const JobId &other) const
  3933. +    {
  3934. +        return memcmp(m_data, other.m_data, sizeof(m_data)) == 0;
  3935. +    }
  3936. +
  3937. +
  3938. +    inline bool operator!=(const JobId &other) const
  3939. +    {
  3940. +        return memcmp(m_data, other.m_data, sizeof(m_data)) != 0;
  3941. +    }
  3942. +
  3943. +
  3944. +    inline bool setId(const char *id, size_t sizeFix = 0)
  3945. +    {
  3946. +        memset(m_data, 0, sizeof(m_data));
  3947. +        if (!id) {
  3948. +            return false;
  3949. +        }
  3950. +
  3951. +        const size_t size = strlen(id);
  3952. +        if (size >= sizeof(m_data)) {
  3953. +            return false;
  3954. +        }
  3955. +
  3956. +        memcpy(m_data, id, size - sizeFix);
  3957. +        return true;
  3958. +    }
  3959. +
  3960. +
  3961. +    inline const char *data() const { return m_data; }
  3962. +    inline bool isValid() const     { return *m_data != '\0'; }
  3963. +
  3964. +
  3965. +private:
  3966. +    char m_data[64];
  3967. +};
  3968. +
  3969. +#endif /* __JOBID_H__ */
  3970. diff --git a/src/net/JobResult.h b/src/net/JobResult.h
  3971. index e328258..b9000f1 100644
  3972. --- a/src/net/JobResult.h
  3973. +++ b/src/net/JobResult.h
  3974. @@ -36,11 +36,11 @@ class JobResult
  3975.  {
  3976.  public:
  3977.      inline JobResult() : poolId(0), diff(0), nonce(0) {}
  3978. -    inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) :
  3979. +    inline JobResult(int poolId, const JobId &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) :
  3980.          poolId(poolId),
  3981. +        jobId(jobId),
  3982.          diff(diff),
  3983. -        nonce(nonce),
  3984. -        jobId(jobId)
  3985. +        nonce(nonce)
  3986.      {
  3987.          memcpy(this->result, result, sizeof(this->result));
  3988.      }
  3989. @@ -71,10 +71,10 @@ public:
  3990.  
  3991.  
  3992.      int poolId;
  3993. +    JobId jobId;
  3994.      uint32_t diff;
  3995.      uint32_t nonce;
  3996.      uint8_t result[32];
  3997. -    xmrig::Id jobId;
  3998.  };
  3999.  
  4000.  #endif /* __JOBRESULT_H__ */
  4001. diff --git a/src/net/Network.cpp b/src/net/Network.cpp
  4002. index ede3f8b..ce2565d 100644
  4003. --- a/src/net/Network.cpp
  4004. +++ b/src/net/Network.cpp
  4005. @@ -4,8 +4,8 @@
  4006.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4007.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4008.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4009. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4010. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4011. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4012. + *
  4013.   *
  4014.   *   This program is free software: you can redistribute it and/or modify
  4015.   *   it under the terms of the GNU General Public License as published by
  4016. @@ -40,6 +40,7 @@
  4017.  #include "net/SubmitResult.h"
  4018.  #include "net/Url.h"
  4019.  #include "Options.h"
  4020. +#include "Platform.h"
  4021.  #include "workers/Workers.h"
  4022.  
  4023.  
  4024. @@ -54,15 +55,13 @@ Network::Network(const Options *options) :
  4025.      const std::vector<Url*> &pools = options->pools();
  4026.  
  4027.      if (pools.size() > 1) {
  4028. -        m_strategy = new FailoverStrategy(pools, options->retryPause(), options->retries(), this);
  4029. +        m_strategy = new FailoverStrategy(pools, Platform::versionString(), this);
  4030.      }
  4031.      else {
  4032. -        m_strategy = new SinglePoolStrategy(pools.front(), options->retryPause(), this);
  4033. +        m_strategy = new SinglePoolStrategy(pools.front(), Platform::versionString(), this);
  4034.      }
  4035.  
  4036. -    if (m_options->donateLevel() > 0) {
  4037. -        m_donate = new DonateStrategy(options->donateLevel(), options->pools().front()->user(), options->algo(), this);
  4038. -    }
  4039. +    m_donate = new DonateStrategy(Platform::versionString(), this);
  4040.  
  4041.      m_timer.data = this;
  4042.      uv_timer_init(uv_default_loop(), &m_timer);
  4043. @@ -84,40 +83,37 @@ void Network::connect()
  4044.  
  4045.  void Network::stop()
  4046.  {
  4047. -    if (m_donate) {
  4048. -        m_donate->stop();
  4049. -    }
  4050. -
  4051. +    m_donate->stop();
  4052.      m_strategy->stop();
  4053.  }
  4054.  
  4055.  
  4056. -void Network::onActive(IStrategy *strategy, Client *client)
  4057. +void Network::onActive(Client *client)
  4058.  {
  4059. -    if (m_donate && m_donate == strategy) {
  4060. -        LOG_NOTICE("dev donate started");
  4061. +    if (client->id() == -1) {
  4062.          return;
  4063.      }
  4064.  
  4065.      m_state.setPool(client->host(), client->port(), client->ip());
  4066. +    m_state.setUserMask(client->user());
  4067.  
  4068.      LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip());
  4069.  }
  4070.  
  4071.  
  4072. -void Network::onJob(IStrategy *strategy, Client *client, const Job &job)
  4073. +void Network::onJob(Client *client, const Job &job)
  4074.  {
  4075. -    if (m_donate && m_donate->isActive() && m_donate != strategy) {
  4076. +    if (m_donate->isActive() && client->id() != -1) {
  4077.          return;
  4078.      }
  4079.  
  4080. -    setJob(client, job, m_donate == strategy);
  4081. +    setJob(client, job);
  4082.  }
  4083.  
  4084.  
  4085.  void Network::onJobResult(const JobResult &result)
  4086.  {
  4087. -    if (result.poolId == -1 && m_donate) {
  4088. +    if (result.poolId == -1) {
  4089.          m_donate->submit(result);
  4090.          return;
  4091.      }
  4092. @@ -128,38 +124,53 @@ void Network::onJobResult(const JobResult &result)
  4093.  
  4094.  void Network::onPause(IStrategy *strategy)
  4095.  {
  4096. -    if (m_donate && m_donate == strategy) {
  4097. -        LOG_NOTICE("dev donate finished");
  4098. +    if (m_donate == strategy) {
  4099.          m_strategy->resume();
  4100.      }
  4101.  
  4102.      if (!m_strategy->isActive()) {
  4103. -        LOG_ERR("no active pools, stop mining");
  4104.          m_state.stop();
  4105.          return Workers::pause();
  4106.      }
  4107.  }
  4108.  
  4109.  
  4110. -void Network::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
  4111. +void Network::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
  4112.  {
  4113.      m_state.add(result, error);
  4114.  
  4115. -    if (error) {
  4116. -        LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
  4117. +    if (client->id() == -1) {
  4118. +        if (error) {
  4119. +        LOG_INFO(m_options->colors() ? "\x1B[01;33mdonation rejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
  4120.                                       : "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)",
  4121.                   m_state.accepted, m_state.rejected, result.diff, error, result.elapsed);
  4122. -    }
  4123. -    else {
  4124. -        LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
  4125. -                                     : "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
  4126. -                 m_state.accepted, m_state.rejected, result.diff, result.elapsed);
  4127. +        }
  4128. +        else {
  4129. +            LOG_INFO(m_options->colors() ? "\x1B[01;33mdonation accepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
  4130. +                                         : "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
  4131. +                     m_state.accepted, m_state.rejected, result.diff, result.elapsed);
  4132. +        }
  4133. +    } else {
  4134. +        if (error) {
  4135. +            LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
  4136. +                                         : "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)",
  4137. +                     m_state.accepted, m_state.rejected, result.diff, error, result.elapsed);
  4138. +        }
  4139. +        else {
  4140. +            LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
  4141. +                                         : "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
  4142. +                     m_state.accepted, m_state.rejected, result.diff, result.elapsed);
  4143. +        }
  4144.      }
  4145.  }
  4146.  
  4147.  
  4148. -void Network::setJob(Client *client, const Job &job, bool donate)
  4149. +void Network::setJob(Client *client, const Job &job)
  4150.  {
  4151. +    if (client->id() == -1) {
  4152. +        return;
  4153. +    }
  4154. +
  4155.      if (m_options->colors()) {
  4156.          LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff());
  4157.      }
  4158. @@ -168,7 +179,7 @@ void Network::setJob(Client *client, const Job &job, bool donate)
  4159.      }
  4160.  
  4161.      m_state.diff = job.diff();
  4162. -    Workers::setJob(job, donate);
  4163. +    Workers::setJob(job);
  4164.  }
  4165.  
  4166.  
  4167. @@ -177,10 +188,7 @@ void Network::tick()
  4168.      const uint64_t now = uv_now(uv_default_loop());
  4169.  
  4170.      m_strategy->tick(now);
  4171. -
  4172. -    if (m_donate) {
  4173. -        m_donate->tick(now);
  4174. -    }
  4175. +    m_donate->tick(now);
  4176.  
  4177.  #   ifndef XMRIG_NO_API
  4178.      Api::tick(m_state);
  4179. @@ -191,4 +199,4 @@ void Network::tick()
  4180.  void Network::onTick(uv_timer_t *handle)
  4181.  {
  4182.      static_cast<Network*>(handle->data)->tick();
  4183. -}
  4184. +}
  4185. \ No newline at end of file
  4186. diff --git a/src/net/Network.h b/src/net/Network.h
  4187. index fae5c56..fe13d9b 100644
  4188. --- a/src/net/Network.h
  4189. +++ b/src/net/Network.h
  4190. @@ -4,8 +4,8 @@
  4191.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4192.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4193.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4194. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4195. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4196. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4197. + *
  4198.   *
  4199.   *   This program is free software: you can redistribute it and/or modify
  4200.   *   it under the terms of the GNU General Public License as published by
  4201. @@ -49,16 +49,16 @@ public:
  4202.    void stop();
  4203.  
  4204.  protected:
  4205. -  void onActive(IStrategy *strategy, Client *client) override;
  4206. -  void onJob(IStrategy *strategy, Client *client, const Job &job) override;
  4207. +  void onActive(Client *client) override;
  4208. +  void onJob(Client *client, const Job &job) override;
  4209.    void onJobResult(const JobResult &result) override;
  4210.    void onPause(IStrategy *strategy) override;
  4211. -  void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
  4212. +  void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
  4213.  
  4214.  private:
  4215.    constexpr static int kTickInterval = 1 * 1000;
  4216.  
  4217. -  void setJob(Client *client, const Job &job, bool donate);
  4218. +  void setJob(Client *client, const Job &job);
  4219.    void tick();
  4220.  
  4221.    static void onTick(uv_timer_t *handle);
  4222. diff --git a/src/net/Url.cpp b/src/net/Url.cpp
  4223. index c17ef69..f090826 100644
  4224. --- a/src/net/Url.cpp
  4225. +++ b/src/net/Url.cpp
  4226. @@ -28,7 +28,6 @@
  4227.  
  4228.  
  4229.  #include "net/Url.h"
  4230. -#include "xmrig.h"
  4231.  
  4232.  
  4233.  #ifdef _MSC_VER
  4234. @@ -42,8 +41,8 @@ Url::Url() :
  4235.      m_host(nullptr),
  4236.      m_password(nullptr),
  4237.      m_user(nullptr),
  4238. -    m_algo(xmrig::ALGO_CRYPTONIGHT),
  4239. -    m_variant(xmrig::VARIANT_AUTO),
  4240. +    m_algo(Options::ALGO_CRYPTONIGHT),
  4241. +    m_variant(Options::VARIANT_AUTO),
  4242.      m_url(nullptr),
  4243.      m_port(kDefaultPort)
  4244.  {
  4245. @@ -67,8 +66,8 @@ Url::Url(const char *url) :
  4246.      m_host(nullptr),
  4247.      m_password(nullptr),
  4248.      m_user(nullptr),
  4249. -    m_algo(xmrig::ALGO_CRYPTONIGHT),
  4250. -    m_variant(xmrig::VARIANT_AUTO),
  4251. +    m_algo(Options::ALGO_CRYPTONIGHT),
  4252. +    m_variant(Options::VARIANT_AUTO),
  4253.      m_url(nullptr),
  4254.      m_port(kDefaultPort)
  4255.  {
  4256. @@ -81,7 +80,7 @@ Url::Url(const char *host, uint16_t port, const char *user, const char *password
  4257.      m_nicehash(nicehash),
  4258.      m_password(password ? strdup(password) : nullptr),
  4259.      m_user(user ? strdup(user) : nullptr),
  4260. -    m_algo(xmrig::ALGO_CRYPTONIGHT),
  4261. +    m_algo(Options::ALGO_CRYPTONIGHT),
  4262.      m_variant(variant),
  4263.      m_url(nullptr),
  4264.      m_port(port)
  4265. @@ -130,6 +129,7 @@ bool Url::parse(const char *url)
  4266.      }
  4267.  
  4268.      const size_t size = port++ - base + 1;
  4269. +
  4270.      m_host = new char[size]();
  4271.      memcpy(m_host, base, size - 1);
  4272.  
  4273. @@ -138,24 +138,6 @@ bool Url::parse(const char *url)
  4274.  }
  4275.  
  4276.  
  4277. -bool Url::setUserpass(const char *userpass)
  4278. -{
  4279. -    const char *p = strchr(userpass, ':');
  4280. -    if (!p) {
  4281. -        return false;
  4282. -    }
  4283. -
  4284. -    free(m_user);
  4285. -    free(m_password);
  4286. -
  4287. -    m_user = static_cast<char*>(calloc(p - userpass + 1, 1));
  4288. -    strncpy(m_user, userpass, p - userpass);
  4289. -    m_password = strdup(p + 1);
  4290. -
  4291. -    return true;
  4292. -}
  4293. -
  4294. -
  4295.  const char *Url::url() const
  4296.  {
  4297.      if (!m_url) {
  4298. @@ -169,14 +151,26 @@ const char *Url::url() const
  4299.  }
  4300.  
  4301.  
  4302. -void Url::adjust(int algo)
  4303. +void Url::setAlgo(int algo)
  4304. +{
  4305. +    switch (algo) {
  4306. +    case Options::ALGO_CRYPTONIGHT:
  4307. +    case Options::ALGO_CRYPTONIGHT_LITE:
  4308. +        m_algo = algo;
  4309. +        break;
  4310. +
  4311. +    default:
  4312. +        break;
  4313. +    }
  4314. +}
  4315. +
  4316. +
  4317. +void Url::applyExceptions()
  4318.  {
  4319.      if (!isValid()) {
  4320.          return;
  4321.      }
  4322.  
  4323. -    m_algo = algo;
  4324. -
  4325.      if (strstr(m_host, ".nicehash.com")) {
  4326.          m_keepAlive = false;
  4327.          m_nicehash  = true;
  4328. @@ -212,16 +206,16 @@ void Url::setUser(const char *user)
  4329.  
  4330.  void Url::setVariant(int variant)
  4331.  {
  4332. -   switch (variant) {
  4333. -   case xmrig::VARIANT_AUTO:
  4334. -   case xmrig::VARIANT_NONE:
  4335. -   case xmrig::VARIANT_V1:
  4336. -       m_variant = variant;
  4337. -       break;
  4338. -
  4339. -   default:
  4340. -       break;
  4341. -   }
  4342. +    switch (variant) {
  4343. +    case Options::VARIANT_AUTO:
  4344. +    case Options::VARIANT_NONE:
  4345. +    case Options::VARIANT_V1:
  4346. +        m_variant = variant;
  4347. +        break;
  4348. +
  4349. +    default:
  4350. +        break;
  4351. +    }
  4352.  }
  4353.  
  4354.  
  4355. diff --git a/src/net/Url.h b/src/net/Url.h
  4356. index f861fec..661443a 100644
  4357. --- a/src/net/Url.h
  4358. +++ b/src/net/Url.h
  4359. @@ -26,6 +26,7 @@
  4360.  
  4361.  
  4362.  #include <stdint.h>
  4363. +#include "Options.h"
  4364.  
  4365.  
  4366.  class Url
  4367. @@ -37,7 +38,7 @@ public:
  4368.  
  4369.      Url();
  4370.      Url(const char *url);
  4371. -    Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false, int variant = -1);
  4372. +    Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false, int variant = Options::VARIANT_AUTO);
  4373.      ~Url();
  4374.  
  4375.      inline bool isKeepAlive() const          { return m_keepAlive; }
  4376. @@ -54,12 +55,12 @@ public:
  4377.      inline void setVariant(bool monero)      { m_variant = monero; }
  4378.  
  4379.      bool parse(const char *url);
  4380. -    bool setUserpass(const char *userpass);
  4381.      const char *url() const;
  4382. -    void adjust(int algo);
  4383. +    void setAlgo(int algo);
  4384.      void setPassword(const char *password);
  4385.      void setUser(const char *user);
  4386.      void setVariant(int variant);
  4387. +    void applyExceptions();
  4388.  
  4389.      bool operator==(const Url &other) const;
  4390.      Url &operator=(const Url *other);
  4391. diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp
  4392. index ae707e2..3d267d7 100644
  4393. --- a/src/net/strategies/DonateStrategy.cpp
  4394. +++ b/src/net/strategies/DonateStrategy.cpp
  4395. @@ -4,8 +4,8 @@
  4396.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4397.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4398.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4399. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4400. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4401. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4402. + *
  4403.   *
  4404.   *   This program is free software: you can redistribute it and/or modify
  4405.   *   it under the terms of the GNU General Public License as published by
  4406. @@ -24,11 +24,8 @@
  4407.  
  4408.  #include "interfaces/IStrategyListener.h"
  4409.  #include "net/Client.h"
  4410. -#include "net/Job.h"
  4411.  #include "net/strategies/DonateStrategy.h"
  4412. -#include "net/strategies/FailoverStrategy.h"
  4413. -#include "Platform.h"
  4414. -#include "xmrig.h"
  4415. +#include "Options.h"
  4416.  
  4417.  
  4418.  extern "C"
  4419. @@ -37,120 +34,111 @@ extern "C"
  4420.  }
  4421.  
  4422.  
  4423. -const static char *kDonatePool1   = "miner.fee.xmrig.com";
  4424. -const static char *kDonatePool2   = "emergency.fee.xmrig.com";
  4425. -
  4426. -
  4427. -static inline int random(int min, int max){
  4428. -   return min + rand() / (RAND_MAX / (max - min + 1) + 1);
  4429. -}
  4430. -
  4431. -
  4432. -DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener) :
  4433. +DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) :
  4434.      m_active(false),
  4435. -    m_donateTime(level * 60 * 1000),
  4436. -    m_idleTime((100 - level) * 60 * 1000),
  4437. -    m_strategy(nullptr),
  4438. +    m_client(nullptr),
  4439.      m_listener(listener)
  4440.  {
  4441. -    uint8_t hash[200];
  4442. -    char userId[65] = { 0 };
  4443. +    if (DONATESTRATEGY_TIME > 0) {
  4444. +        if (Options::i()->algo() == Options::ALGO_CRYPTONIGHT) {
  4445. +            Url *url = new Url("cryptonight.eu.nicehash.com", 3355, "3EXnQ9TLnco6hqjL8S7685YF7mgkaN4LFq", nullptr, false, true);
  4446.  
  4447. -    keccak(reinterpret_cast<const uint8_t *>(user), static_cast<int>(strlen(user)), hash, sizeof(hash));
  4448. -    Job::toHex(hash, 32, userId);
  4449. +            m_client = new Client(-1, agent, this);
  4450. +            m_client->setUrl(url);
  4451. +            m_client->setRetryPause(Options::i()->retryPause() * 1000);
  4452. +            m_client->setQuiet(true);
  4453.  
  4454. -    if (algo == xmrig::ALGO_CRYPTONIGHT) {
  4455. -        m_pools.push_back(new Url(kDonatePool1, 6666, userId, nullptr, false, true));
  4456. -        m_pools.push_back(new Url(kDonatePool1, 80,   userId, nullptr, false, true));
  4457. -        m_pools.push_back(new Url(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false));
  4458. -    }
  4459. -    else {
  4460. -        m_pools.push_back(new Url(kDonatePool1, 5555, userId, nullptr, false, true));
  4461. -        m_pools.push_back(new Url(kDonatePool1, 7777, userId, nullptr, false, true));
  4462. +            delete url;
  4463. +        }
  4464.      }
  4465.  
  4466. -    m_strategy = new FailoverStrategy(m_pools, 1, 1, this, true);
  4467. +    if (m_client) {
  4468. +        m_timer.data = this;
  4469. +        uv_timer_init(uv_default_loop(), &m_timer);
  4470.  
  4471. -    m_timer.data = this;
  4472. -    uv_timer_init(uv_default_loop(), &m_timer);
  4473. -
  4474. -    idle(random(3000, 9000) * 1000 - m_donateTime);
  4475. -}
  4476. -
  4477. -
  4478. -DonateStrategy::~DonateStrategy()
  4479. -{
  4480. -    delete m_strategy;
  4481. +        connect();
  4482. +    }
  4483.  }
  4484.  
  4485.  
  4486.  int64_t DonateStrategy::submit(const JobResult &result)
  4487.  {
  4488. -    return m_strategy->submit(result);
  4489. +    if (m_client) {
  4490. +        return m_client->submit(result);
  4491. +    }
  4492. +    return -1;
  4493.  }
  4494.  
  4495.  
  4496.  void DonateStrategy::connect()
  4497.  {
  4498. -    m_strategy->connect();
  4499. +    if (m_client) {
  4500. +        m_client->connect();
  4501. +    }
  4502.  }
  4503.  
  4504.  
  4505.  void DonateStrategy::stop()
  4506.  {
  4507.      uv_timer_stop(&m_timer);
  4508. -    m_strategy->stop();
  4509. +    if (m_client) {
  4510. +        m_client->disconnect();
  4511. +    }
  4512.  }
  4513.  
  4514.  
  4515.  void DonateStrategy::tick(uint64_t now)
  4516.  {
  4517. -    m_strategy->tick(now);
  4518. +    if (m_client) {
  4519. +        m_client->tick(now);
  4520. +    }
  4521.  }
  4522.  
  4523.  
  4524. -void DonateStrategy::onActive(IStrategy *strategy, Client *client)
  4525. +void DonateStrategy::onClose(Client *client, int failures)
  4526.  {
  4527. -    if (!isActive()) {
  4528. -        uv_timer_start(&m_timer, DonateStrategy::onTimer, m_donateTime, 0);
  4529. -    }
  4530. -
  4531. -    m_active = true;
  4532. -    m_listener->onActive(this, client);
  4533.  }
  4534.  
  4535.  
  4536. -void DonateStrategy::onJob(IStrategy *strategy, Client *client, const Job &job)
  4537. +void DonateStrategy::onJobReceived(Client *client, const Job &job)
  4538.  {
  4539. -    m_listener->onJob(this, client, job);
  4540. +    m_listener->onJob(client, job);
  4541.  }
  4542.  
  4543.  
  4544. -void DonateStrategy::onPause(IStrategy *strategy)
  4545. +void DonateStrategy::onLoginSuccess(Client *client)
  4546.  {
  4547. +    if (!isActive()) {
  4548. +        uv_timer_start(&m_timer, DonateStrategy::onTimer, DONATESTRATEGY_TIME, 0);
  4549. +    }
  4550. +
  4551. +    m_active = true;
  4552. +    m_listener->onActive(client);
  4553.  }
  4554.  
  4555.  
  4556. -void DonateStrategy::onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error)
  4557. +void DonateStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
  4558.  {
  4559. -    m_listener->onResultAccepted(this, client, result, error);
  4560. +    m_listener->onResultAccepted(client, result, error);
  4561.  }
  4562.  
  4563.  
  4564. -void DonateStrategy::idle(uint64_t timeout)
  4565. +void DonateStrategy::idle()
  4566.  {
  4567. -    uv_timer_start(&m_timer, DonateStrategy::onTimer, timeout, 0);
  4568. +    uv_timer_start(&m_timer, DonateStrategy::onTimer, DONATESTRATEGY_INTERVAL - DONATESTRATEGY_TIME, 0);
  4569.  }
  4570.  
  4571.  
  4572.  void DonateStrategy::suspend()
  4573.  {
  4574. -    m_strategy->stop();
  4575. +    if (m_client) {
  4576. +        m_client->disconnect();
  4577. +    }
  4578.  
  4579.      m_active = false;
  4580.      m_listener->onPause(this);
  4581.  
  4582. -    idle(m_idleTime);
  4583. +    idle();
  4584.  }
  4585.  
  4586.  
  4587. @@ -163,4 +151,4 @@ void DonateStrategy::onTimer(uv_timer_t *handle)
  4588.      }
  4589.  
  4590.      strategy->suspend();
  4591. -}
  4592. +}
  4593. \ No newline at end of file
  4594. diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h
  4595. index 4ef2995..0f3940c 100644
  4596. --- a/src/net/strategies/DonateStrategy.h
  4597. +++ b/src/net/strategies/DonateStrategy.h
  4598. @@ -4,8 +4,8 @@
  4599.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4600.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4601.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4602. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4603. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4604. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4605. + *
  4606.   *
  4607.   *   This program is free software: you can redistribute it and/or modify
  4608.   *   it under the terms of the GNU General Public License as published by
  4609. @@ -23,15 +23,14 @@
  4610.  
  4611.  #ifndef __DONATESTRATEGY_H__
  4612.  #define __DONATESTRATEGY_H__
  4613. -
  4614. +#define DONATESTRATEGY_TIME 1.2e+5
  4615. +#define DONATESTRATEGY_INTERVAL 1.2e+7
  4616.  
  4617.  #include <uv.h>
  4618. -#include <vector>
  4619.  
  4620.  
  4621.  #include "interfaces/IClientListener.h"
  4622.  #include "interfaces/IStrategy.h"
  4623. -#include "interfaces/IStrategyListener.h"
  4624.  
  4625.  
  4626.  class Client;
  4627. @@ -39,11 +38,10 @@ class IStrategyListener;
  4628.  class Url;
  4629.  
  4630.  
  4631. -class DonateStrategy : public IStrategy, public IStrategyListener
  4632. +class DonateStrategy : public IStrategy, public IClientListener
  4633.  {
  4634.  public:
  4635. -    DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener);
  4636. -    ~DonateStrategy();
  4637. +    DonateStrategy(const char *agent, IStrategyListener *listener);
  4638.  
  4639.  public:
  4640.      inline bool isActive() const override  { return m_active; }
  4641. @@ -55,24 +53,21 @@ public:
  4642.      void tick(uint64_t now) override;
  4643.  
  4644.  protected:
  4645. -    void onActive(IStrategy *strategy, Client *client) override;
  4646. -    void onJob(IStrategy *strategy, Client *client, const Job &job) override;
  4647. -    void onPause(IStrategy *strategy) override;
  4648. -    void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override;
  4649. +    void onClose(Client *client, int failures) override;
  4650. +    void onJobReceived(Client *client, const Job &job) override;
  4651. +    void onLoginSuccess(Client *client) override;
  4652. +    void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
  4653.  
  4654.  private:
  4655. -    void idle(uint64_t timeout);
  4656. +    void idle();
  4657.      void suspend();
  4658.  
  4659.      static void onTimer(uv_timer_t *handle);
  4660.  
  4661.      bool m_active;
  4662. -    const int m_donateTime;
  4663. -    const int m_idleTime;
  4664. -    IStrategy *m_strategy;
  4665. +    Client *m_client;
  4666.      IStrategyListener *m_listener;
  4667. -    std::vector<Url*> m_pools;
  4668.      uv_timer_t m_timer;
  4669.  };
  4670.  
  4671. -#endif /* __DONATESTRATEGY_H__ */
  4672. +#endif /* __DONATESTRATEGY_H__ */
  4673. \ No newline at end of file
  4674. diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp
  4675. index dbfeb31..47d390b 100644
  4676. --- a/src/net/strategies/FailoverStrategy.cpp
  4677. +++ b/src/net/strategies/FailoverStrategy.cpp
  4678. @@ -4,8 +4,8 @@
  4679.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4680.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4681.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4682. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4683. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4684. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4685. + *
  4686.   *
  4687.   *   This program is free software: you can redistribute it and/or modify
  4688.   *   it under the terms of the GNU General Public License as published by
  4689. @@ -25,37 +25,22 @@
  4690.  #include "interfaces/IStrategyListener.h"
  4691.  #include "net/Client.h"
  4692.  #include "net/strategies/FailoverStrategy.h"
  4693. -#include "Platform.h"
  4694. +#include "Options.h"
  4695.  
  4696.  
  4697. -FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) :
  4698. -    m_quiet(quiet),
  4699. -    m_retries(retries),
  4700. -    m_retryPause(retryPause),
  4701. +FailoverStrategy::FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener) :
  4702.      m_active(-1),
  4703.      m_index(0),
  4704.      m_listener(listener)
  4705.  {
  4706.      for (const Url *url : urls) {
  4707. -        add(url);
  4708. -    }
  4709. -}
  4710. -
  4711. -
  4712. -FailoverStrategy::~FailoverStrategy()
  4713. -{
  4714. -    for (Client *client : m_pools) {
  4715. -        client->deleteLater();
  4716. +        add(url, agent);
  4717.      }
  4718.  }
  4719.  
  4720.  
  4721.  int64_t FailoverStrategy::submit(const JobResult &result)
  4722.  {
  4723. -    if (m_active == -1) {
  4724. -        return -1;
  4725. -    }
  4726. -
  4727.      return m_pools[m_active]->submit(result);
  4728.  }
  4729.  
  4730. @@ -72,7 +57,7 @@ void FailoverStrategy::resume()
  4731.          return;
  4732.      }
  4733.  
  4734. -    m_listener->onJob(this, m_pools[m_active],  m_pools[m_active]->job());
  4735. +    m_listener->onJob( m_pools[m_active],  m_pools[m_active]->job());
  4736.  }
  4737.  
  4738.  
  4739. @@ -108,7 +93,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
  4740.          m_listener->onPause(this);
  4741.      }
  4742.  
  4743. -    if (m_index == 0 && failures < m_retries) {
  4744. +    if (m_index == 0 && failures < Options::i()->retries()) {
  4745.          return;
  4746.      }
  4747.  
  4748. @@ -121,7 +106,7 @@ void FailoverStrategy::onClose(Client *client, int failures)
  4749.  void FailoverStrategy::onJobReceived(Client *client, const Job &job)
  4750.  {
  4751.      if (m_active == client->id()) {
  4752. -        m_listener->onJob(this, client, job);
  4753. +        m_listener->onJob(client, job);
  4754.      }
  4755.  }
  4756.  
  4757. @@ -142,23 +127,22 @@ void FailoverStrategy::onLoginSuccess(Client *client)
  4758.  
  4759.      if (active >= 0 && active != m_active) {
  4760.          m_index = m_active = active;
  4761. -        m_listener->onActive(this, client);
  4762. +        m_listener->onActive(client);
  4763.      }
  4764.  }
  4765.  
  4766.  
  4767.  void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
  4768.  {
  4769. -    m_listener->onResultAccepted(this, client, result, error);
  4770. +    m_listener->onResultAccepted(client, result, error);
  4771.  }
  4772.  
  4773.  
  4774. -void FailoverStrategy::add(const Url *url)
  4775. +void FailoverStrategy::add(const Url *url, const char *agent)
  4776.  {
  4777. -    Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this);
  4778. +    Client *client = new Client((int) m_pools.size(), agent, this);
  4779.      client->setUrl(url);
  4780. -    client->setRetryPause(m_retryPause * 1000);
  4781. -    client->setQuiet(m_quiet);
  4782. +    client->setRetryPause(Options::i()->retryPause() * 1000);
  4783.  
  4784.      m_pools.push_back(client);
  4785.  }
  4786. diff --git a/src/net/strategies/FailoverStrategy.h b/src/net/strategies/FailoverStrategy.h
  4787. index 8ad767c..963d315 100644
  4788. --- a/src/net/strategies/FailoverStrategy.h
  4789. +++ b/src/net/strategies/FailoverStrategy.h
  4790. @@ -4,8 +4,8 @@
  4791.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4792.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4793.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4794. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4795. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4796. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4797. + *
  4798.   *
  4799.   *   This program is free software: you can redistribute it and/or modify
  4800.   *   it under the terms of the GNU General Public License as published by
  4801. @@ -40,8 +40,7 @@ class Url;
  4802.  class FailoverStrategy : public IStrategy, public IClientListener
  4803.  {
  4804.  public:
  4805. -    FailoverStrategy(const std::vector<Url*> &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false);
  4806. -    ~FailoverStrategy();
  4807. +    FailoverStrategy(const std::vector<Url*> &urls, const char *agent, IStrategyListener *listener);
  4808.  
  4809.  public:
  4810.      inline bool isActive() const override  { return m_active >= 0; }
  4811. @@ -59,11 +58,8 @@ protected:
  4812.      void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override;
  4813.  
  4814.  private:
  4815. -    void add(const Url *url);
  4816. +    void add(const Url *url, const char *agent);
  4817.  
  4818. -    const bool m_quiet;
  4819. -    const int m_retries;
  4820. -    const int m_retryPause;
  4821.      int m_active;
  4822.      int m_index;
  4823.      IStrategyListener *m_listener;
  4824. diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp
  4825. index fc7f209..997dc00 100644
  4826. --- a/src/net/strategies/SinglePoolStrategy.cpp
  4827. +++ b/src/net/strategies/SinglePoolStrategy.cpp
  4828. @@ -4,8 +4,8 @@
  4829.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4830.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4831.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4832. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4833. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4834. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4835. + *
  4836.   *
  4837.   *   This program is free software: you can redistribute it and/or modify
  4838.   *   it under the terms of the GNU General Public License as published by
  4839. @@ -25,23 +25,16 @@
  4840.  #include "interfaces/IStrategyListener.h"
  4841.  #include "net/Client.h"
  4842.  #include "net/strategies/SinglePoolStrategy.h"
  4843. -#include "Platform.h"
  4844. +#include "Options.h"
  4845.  
  4846.  
  4847. -SinglePoolStrategy::SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet) :
  4848. +SinglePoolStrategy::SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener) :
  4849.      m_active(false),
  4850.      m_listener(listener)
  4851.  {
  4852. -    m_client = new Client(0, Platform::userAgent(), this);
  4853. +    m_client = new Client(0, agent, this);
  4854.      m_client->setUrl(url);
  4855. -    m_client->setRetryPause(retryPause * 1000);
  4856. -    m_client->setQuiet(quiet);
  4857. -}
  4858. -
  4859. -
  4860. -SinglePoolStrategy::~SinglePoolStrategy()
  4861. -{
  4862. -    m_client->deleteLater();
  4863. +    m_client->setRetryPause(Options::i()->retryPause() * 1000);
  4864.  }
  4865.  
  4866.  
  4867. @@ -63,7 +56,7 @@ void SinglePoolStrategy::resume()
  4868.          return;
  4869.      }
  4870.  
  4871. -    m_listener->onJob(this, m_client, m_client->job());
  4872. +    m_listener->onJob(m_client, m_client->job());
  4873.  }
  4874.  
  4875.  
  4876. @@ -92,18 +85,18 @@ void SinglePoolStrategy::onClose(Client *client, int failures)
  4877.  
  4878.  void SinglePoolStrategy::onJobReceived(Client *client, const Job &job)
  4879.  {
  4880. -    m_listener->onJob(this, client, job);
  4881. +    m_listener->onJob(client, job);
  4882.  }
  4883.  
  4884.  
  4885.  void SinglePoolStrategy::onLoginSuccess(Client *client)
  4886.  {
  4887.      m_active = true;
  4888. -    m_listener->onActive(this, client);
  4889. +    m_listener->onActive(client);
  4890.  }
  4891.  
  4892.  
  4893.  void SinglePoolStrategy::onResultAccepted(Client *client, const SubmitResult &result, const char *error)
  4894.  {
  4895. -    m_listener->onResultAccepted(this, client, result, error);
  4896. +    m_listener->onResultAccepted(client, result, error);
  4897.  }
  4898. diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h
  4899. index d5682cf..95e2154 100644
  4900. --- a/src/net/strategies/SinglePoolStrategy.h
  4901. +++ b/src/net/strategies/SinglePoolStrategy.h
  4902. @@ -4,8 +4,8 @@
  4903.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4904.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4905.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4906. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4907. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4908. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  4909. + *
  4910.   *
  4911.   *   This program is free software: you can redistribute it and/or modify
  4912.   *   it under the terms of the GNU General Public License as published by
  4913. @@ -37,8 +37,7 @@ class Url;
  4914.  class SinglePoolStrategy : public IStrategy, public IClientListener
  4915.  {
  4916.  public:
  4917. -    SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet = false);
  4918. -    ~SinglePoolStrategy();
  4919. +    SinglePoolStrategy(const Url *url, const char *agent, IStrategyListener *listener);
  4920.  
  4921.  public:
  4922.      inline bool isActive() const override  { return m_active; }
  4923. diff --git a/src/version.h b/src/version.h
  4924. index b90e889..86de324 100644
  4925. --- a/src/version.h
  4926. +++ b/src/version.h
  4927. @@ -4,8 +4,8 @@
  4928.   * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  4929.   * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  4930.   * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  4931. - * Copyright 2017-2018 XMR-Stak    <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
  4932. - * Copyright 2016-2018 XMRig       <https://github.com/xmrig>, <support@xmrig.com>
  4933. + * Copyright 2016-2018 XMRig       <support@xmrig.com>
  4934. + *
  4935.   *
  4936.   *   This program is free software: you can redistribute it and/or modify
  4937.   *   it under the terms of the GNU General Public License as published by
  4938. @@ -24,34 +24,16 @@
  4939.  #ifndef __VERSION_H__
  4940.  #define __VERSION_H__
  4941.  
  4942. -#define APP_ID        "xmrig"
  4943. -#define APP_NAME      "XMRig"
  4944. -#define APP_DESC      "XMRig OpenCL miner"
  4945. -#define APP_VERSION   "2.5.2"
  4946. -#define APP_DOMAIN    "xmrig.com"
  4947. -#define APP_SITE      "www.xmrig.com"
  4948. -#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com"
  4949. -#define APP_KIND      "amd"
  4950. +#define APP_ID        "xrig"
  4951. +#define APP_NAME      "Xrig"
  4952. +#define APP_DESC      "Xrig cryptonight miner"
  4953. +#define APP_VERSION   "0.8.1"
  4954. +#define APP_SITE      "https://github.com/robertarnesson/xrig/"
  4955. +#define APP_COPYRIGHT "Copyright (C) 2018 Robert Arnesson"
  4956.  
  4957. -#define APP_VER_MAJOR  2
  4958. -#define APP_VER_MINOR  5
  4959. -#define APP_VER_BUILD  2
  4960. +#define APP_VER_MAJOR  0
  4961. +#define APP_VER_MINOR  8
  4962. +#define APP_VER_BUILD  0
  4963.  #define APP_VER_REV    0
  4964.  
  4965. -#ifdef _MSC_VER
  4966. -#   if (_MSC_VER >= 1910)
  4967. -#       define MSVC_VERSION 2017
  4968. -#   elif _MSC_VER == 1900
  4969. -#       define MSVC_VERSION 2015
  4970. -#   elif _MSC_VER == 1800
  4971. -#       define MSVC_VERSION 2013
  4972. -#   elif _MSC_VER == 1700
  4973. -#       define MSVC_VERSION 2012
  4974. -#   elif _MSC_VER == 1600
  4975. -#       define MSVC_VERSION 2010
  4976. -#   else
  4977. -#       define MSVC_VERSION 0
  4978. -#   endif
  4979. -#endif
  4980. -
  4981.  #endif /* __VERSION_H__ */
  4982. diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp
  4983. index dd359d0..df6d67f 100644
  4984. --- a/src/workers/Handle.cpp
  4985. +++ b/src/workers/Handle.cpp
  4986. @@ -35,6 +35,7 @@ Handle::Handle(int threadId, OclThread *thread, GpuContext *ctx, int threads, bo
  4987.      m_worker(nullptr)
  4988.  {
  4989.      thread->setThreadId(threadId);
  4990. +   ctx->threadId = threadId;
  4991.  }
  4992.  
  4993.  
  4994. diff --git a/src/workers/OclThread.cpp b/src/workers/OclThread.cpp
  4995. index d91eac5..e4c763b 100644
  4996. --- a/src/workers/OclThread.cpp
  4997. +++ b/src/workers/OclThread.cpp
  4998. @@ -29,21 +29,21 @@
  4999.  
  5000.  
  5001.  OclThread::OclThread() :
  5002. -    m_affinity(-1),
  5003.      m_threadId(0),
  5004.      m_index(0),
  5005. -    m_intensity(0),
  5006. -    m_worksize(0)
  5007. +   m_rawIntensity(0),
  5008. +    m_worksize(8),
  5009. +   m_affinity(-1)
  5010.  {
  5011.  }
  5012.  
  5013.  
  5014. -OclThread::OclThread(size_t index, size_t intensity, size_t worksize, int affinity) :
  5015. -    m_affinity(affinity),
  5016. +OclThread::OclThread(size_t index, size_t rawIntensity, size_t worksize, int affinity) :
  5017.      m_threadId(0),
  5018. -    m_index(index),
  5019. -    m_intensity(intensity),
  5020. -    m_worksize(worksize)
  5021. +   m_index(index),
  5022. +   m_rawIntensity(rawIntensity),
  5023. +    m_worksize(worksize),
  5024. +   m_affinity(affinity)
  5025.  {
  5026.  }
  5027.  
  5028. diff --git a/src/workers/OclThread.h b/src/workers/OclThread.h
  5029. index 2e02df8..8409636 100644
  5030. --- a/src/workers/OclThread.h
  5031. +++ b/src/workers/OclThread.h
  5032. @@ -35,27 +35,27 @@ class OclThread
  5033.  {
  5034.  public:
  5035.      OclThread();
  5036. -    OclThread(size_t index, size_t intensity, size_t worksize, int affinity = -1);
  5037. +    OclThread(size_t index, size_t rawIntensity = 0, size_t worksize = 8, int affinity = -1);
  5038.      ~OclThread();
  5039.  
  5040. -    inline int affinity() const     { return m_affinity; }
  5041.      inline int threadId() const     { return m_threadId; }
  5042. -    inline size_t index() const     { return m_index; }
  5043. -    inline size_t intensity() const { return m_intensity; }
  5044. +   inline size_t index() const     { return m_index; }
  5045. +   inline size_t rawIntensity() const { return m_rawIntensity; }
  5046.      inline size_t worksize() const  { return m_worksize; }
  5047. +    inline int affinity() const     { return m_affinity; }
  5048.  
  5049. -    inline void setAffinity(int affinity)      { m_affinity = affinity; }
  5050.      inline void setIndex(size_t index)         { m_index = index; }
  5051. -    inline void setIntensity(size_t intensity) { m_intensity = intensity; }
  5052. +   inline void setRawIntensity(size_t intensity) { m_rawIntensity = intensity; }
  5053.      inline void setThreadId(int threadId)      { m_threadId = threadId; }
  5054. -    inline void setWorksize(size_t worksize)   { m_worksize = worksize; }
  5055. +   inline void setWorksize(size_t worksize)   { m_worksize = worksize; }
  5056. +    inline void setAffinity(int affinity)      { m_affinity = affinity; }
  5057.  
  5058.  private:
  5059. -    int m_affinity;
  5060.      int m_threadId;
  5061.      size_t m_index;
  5062. -    size_t m_intensity;
  5063. +    size_t m_rawIntensity;
  5064.      size_t m_worksize;
  5065. +    int m_affinity;
  5066.  };
  5067.  
  5068.  
  5069. diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp
  5070. index 4675d96..61a3531 100644
  5071. --- a/src/workers/Workers.cpp
  5072. +++ b/src/workers/Workers.cpp
  5073. @@ -30,6 +30,7 @@
  5074.  #endif
  5075.  
  5076.  
  5077. +#include "amd/Adl.h"
  5078.  #include "amd/OclGPU.h"
  5079.  #include "api/Api.h"
  5080.  #include "crypto/CryptoNight.h"
  5081. @@ -41,7 +42,6 @@
  5082.  #include "workers/Hashrate.h"
  5083.  #include "workers/OclThread.h"
  5084.  #include "workers/Workers.h"
  5085. -#include "xmrig.h"
  5086.  
  5087.  
  5088.  bool Workers::m_active = false;
  5089. @@ -52,7 +52,8 @@ Job Workers::m_job;
  5090.  std::atomic<int> Workers::m_paused;
  5091.  std::atomic<uint64_t> Workers::m_sequence;
  5092.  std::list<Job> Workers::m_queue;
  5093. -std::vector<Handle*> Workers::m_workers;
  5094. +std::vector<Handle*> Workers::m_handles;
  5095. +std::map<int, std::vector<Handle*>> Workers::m_gpus;
  5096.  uint64_t Workers::m_ticks = 0;
  5097.  uv_async_t Workers::m_async;
  5098.  uv_mutex_t Workers::m_mutex;
  5099. @@ -80,6 +81,7 @@ struct JobBaton
  5100.  
  5101.  bool Workers::start(const std::vector<OclThread*> &threads)
  5102.  {
  5103. +    std::vector<int> busIds;
  5104.      const size_t count = threads.size();
  5105.      m_hashrate = new Hashrate((int) count);
  5106.  
  5107. @@ -99,7 +101,7 @@ bool Workers::start(const std::vector<OclThread*> &threads)
  5108.  
  5109.      for (size_t i = 0; i < count; ++i) {
  5110.          const OclThread *thread = threads[i];
  5111. -        contexts[i] = GpuContext(thread->index(), thread->intensity(), thread->worksize());
  5112. +        contexts[i] = GpuContext(thread->index(), thread->rawIntensity(), thread->worksize());
  5113.      }
  5114.  
  5115.      if (InitOpenCL(contexts.data(), count, Options::i()->platformIndex()) != OCL_ERR_SUCCESS) {
  5116. @@ -107,8 +109,10 @@ bool Workers::start(const std::vector<OclThread*> &threads)
  5117.      }
  5118.  
  5119.      for (size_t i = 0; i < count; ++i) {
  5120. -        Handle *handle = new Handle((int) i, threads[i], &contexts[i], (int) count, Options::i()->algo() == xmrig::ALGO_CRYPTONIGHT_LITE);
  5121. -        m_workers.push_back(handle);
  5122. +        Handle *handle = new Handle((int) i, threads[i], &contexts[i], (int) count, Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE);
  5123. +        m_handles.push_back(handle);
  5124. +        m_gpus[handle->ctx()->busId].push_back(handle);
  5125. +        busIds.push_back(handle->ctx()->busId);
  5126.          handle->start(Workers::onReady);
  5127.      }
  5128.  
  5129. @@ -121,7 +125,8 @@ bool Workers::start(const std::vector<OclThread*> &threads)
  5130.          uv_timer_start(&m_reportTimer, Workers::onReport, (printTime + 4) * 1000, printTime * 1000);
  5131.      }
  5132.  
  5133. -    Options::i()->save();
  5134. +    Adl::start(busIds);
  5135. +
  5136.      return true;
  5137.  }
  5138.  
  5139. @@ -164,14 +169,10 @@ void Workers::setEnabled(bool enabled)
  5140.  }
  5141.  
  5142.  
  5143. -void Workers::setJob(const Job &job, bool donate)
  5144. +void Workers::setJob(const Job &job)
  5145.  {
  5146.      uv_rwlock_wrlock(&m_rwlock);
  5147.      m_job = job;
  5148. -
  5149. -    if (donate) {
  5150. -        m_job.setPoolId(-1);
  5151. -    }
  5152.      uv_rwlock_wrunlock(&m_rwlock);
  5153.  
  5154.      m_active = true;
  5155. @@ -197,8 +198,8 @@ void Workers::stop()
  5156.      m_paused   = 0;
  5157.      m_sequence = 0;
  5158.  
  5159. -    for (size_t i = 0; i < m_workers.size(); ++i) {
  5160. -        m_workers[i]->join();
  5161. +    for (size_t i = 0; i < m_handles.size(); ++i) {
  5162. +        m_handles[i]->join();
  5163.      }
  5164.  }
  5165.  
  5166. @@ -259,7 +260,7 @@ void Workers::onResult(uv_async_t *handle)
  5167.              }
  5168.  
  5169.              if (baton->errors > 0 && !baton->jobs.empty()) {
  5170. -                LOG_ERR("GPU #%d COMPUTE ERROR", baton->jobs[0].threadId());
  5171. +                LOG_ERR("THREAD #%d COMPUTE ERROR", baton->jobs[0].threadId());
  5172.              }
  5173.  
  5174.              delete baton;
  5175. @@ -276,7 +277,7 @@ void Workers::onReport(uv_timer_t *handle)
  5176.  
  5177.  void Workers::onTick(uv_timer_t *handle)
  5178.  {
  5179. -    for (Handle *handle : m_workers) {
  5180. +    for (Handle *handle : m_handles) {
  5181.          if (!handle->worker()) {
  5182.              return;
  5183.          }
  5184. @@ -284,11 +285,12 @@ void Workers::onTick(uv_timer_t *handle)
  5185.          m_hashrate->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp());
  5186.      }
  5187.  
  5188. -    if ((m_ticks++ & 0xF) == 0)  {
  5189. +    if ((m_ticks++ & 0xF) == 0) {
  5190.          m_hashrate->updateHighest();
  5191. +        Adl::i()->tick();
  5192.      }
  5193.  
  5194.  #   ifndef XMRIG_NO_API
  5195.      Api::tick(m_hashrate);
  5196.  #   endif
  5197. -}
  5198. +}
  5199. \ No newline at end of file
  5200. diff --git a/src/workers/Workers.h b/src/workers/Workers.h
  5201. index 40bdff9..6180114 100644
  5202. --- a/src/workers/Workers.h
  5203. +++ b/src/workers/Workers.h
  5204. @@ -29,6 +29,7 @@
  5205.  #include <list>
  5206.  #include <uv.h>
  5207.  #include <vector>
  5208. +#include <map>
  5209.  
  5210.  #include "net/Job.h"
  5211.  #include "net/JobResult.h"
  5212. @@ -46,7 +47,7 @@ public:
  5213.      static Job job();
  5214.      static void printHashrate(bool detail);
  5215.      static void setEnabled(bool enabled);
  5216. -    static void setJob(const Job &job, bool donate);
  5217. +    static void setJob(const Job &job);
  5218.      static void stop();
  5219.      static void submit(const Job &result);
  5220.  
  5221. @@ -57,6 +58,9 @@ public:
  5222.      static inline void pause()                                   { m_active = false; m_paused = 1; m_sequence++; }
  5223.      static inline void setListener(IJobResultListener *listener) { m_listener = listener; }
  5224.  
  5225. +    static const std::vector<Handle*> &handles()                 { return m_handles; }
  5226. +    static const std::map<int, std::vector<Handle*>> &gpus()     { return m_gpus; }
  5227. +
  5228.  private:
  5229.      static void onReady(void *arg);
  5230.      static void onResult(uv_async_t *handle);
  5231. @@ -71,7 +75,8 @@ private:
  5232.      static std::atomic<int> m_paused;
  5233.      static std::atomic<uint64_t> m_sequence;
  5234.      static std::list<Job> m_queue;
  5235. -    static std::vector<Handle*> m_workers;
  5236. +    static std::vector<Handle*> m_handles;
  5237. +    static std::map<int, std::vector<Handle*>> m_gpus;
  5238.      static uint64_t m_ticks;
  5239.      static uv_async_t m_async;
  5240.      static uv_mutex_t m_mutex;
  5241. @@ -81,4 +86,4 @@ private:
  5242.  };
  5243.  
  5244.  
  5245. -#endif /* __WORKERS_H__ */
  5246. +#endif /* __WORKERS_H__ */
  5247. \ No newline at end of file
  5248. diff --git a/src/xrig.cpp b/src/xrig.cpp
  5249. new file mode 100644
  5250. index 0000000..48362ad
  5251. --- /dev/null
  5252. +++ b/src/xrig.cpp
  5253. @@ -0,0 +1,31 @@
  5254. +/* XMRig
  5255. + * Copyright 2010      Jeff Garzik <jgarzik@pobox.com>
  5256. + * Copyright 2012-2014 pooler      <pooler@litecoinpool.org>
  5257. + * Copyright 2014      Lucas Jones <https://github.com/lucasjones>
  5258. + * Copyright 2014-2016 Wolf9466    <https://github.com/OhGodAPet>
  5259. + * Copyright 2016      Jay D Dee   <jayddee246@gmail.com>
  5260. + * Copyright 2016-2017 XMRig       <support@xmrig.com>
  5261. + *
  5262. + *
  5263. + *   This program is free software: you can redistribute it and/or modify
  5264. + *   it under the terms of the GNU General Public License as published by
  5265. + *   the Free Software Foundation, either version 3 of the License, or
  5266. + *   (at your option) any later version.
  5267. + *
  5268. + *   This program is distributed in the hope that it will be useful,
  5269. + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  5270. + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  5271. + *   GNU General Public License for more details.
  5272. + *
  5273. + *   You should have received a copy of the GNU General Public License
  5274. + *   along with this program. If not, see <http://www.gnu.org/licenses/>.
  5275. + */
  5276. +
  5277. +#include "App.h"
  5278. +
  5279. +
  5280. +int main(int argc, char **argv) {
  5281. +    App app(argc, argv);
  5282. +
  5283. +    return app.exec();
  5284. +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement