1
0
mirror of https://github.com/xmrig/xmrig.git synced 2025-12-06 23:52:38 -05:00

Compare commits

...

248 Commits

Author SHA1 Message Date
XMRig
8600d8ee96 v2.99.0-beta 2019-07-22 00:18:30 +07:00
XMRig
ac849ea996 Merge branch 'evo' into beta 2019-07-21 23:59:16 +07:00
xmrig
2d719a28c4 Update CHANGELOG.md 2019-07-21 23:57:07 +07:00
XMRig
9660dfc7b3 Workaround for unsupported intensity option + warning. 2019-07-21 04:35:52 +07:00
XMRig
370be64f30 Merge branch 'evo' of github.com:xmrig/xmrig into evo 2019-07-21 00:10:01 +07:00
XMRig
162c3f3d32 Only intensity=1 allowed for RandomX. 2019-07-21 00:08:13 +07:00
xmrig
c7ba4f8f2f Update CPU.md 2019-07-20 23:33:04 +07:00
xmrig
7119e4c64c Update CPU.md 2019-07-20 23:23:13 +07:00
xmrig
83f0f2bcad Create CPU.md 2019-07-20 23:16:23 +07:00
xmrig
d1705a7f74 Update ALGORITHMS.md 2019-07-20 20:59:42 +07:00
XMRig
484253bf68 Updated algorithms descriptions. 2019-07-20 20:57:37 +07:00
xmrig
c4388fa74c Update ALGORITHMS.md 2019-07-20 20:14:34 +07:00
XMRig
e2a5bfa0b4 Better default config. 2019-07-20 16:20:11 +07:00
XMRig
3d7598b28d Updated default config example. 2019-07-20 05:57:58 +07:00
XMRig
71300fa852 v2.99.0-evo 2019-07-20 05:35:40 +07:00
XMRig
31ca1a1b6f Merge branch 'feature-per-pool-algo' into evo 2019-07-20 05:28:56 +07:00
XMRig
3fb180f04e Removed --variant option, use --algo instead. 2019-07-20 05:24:21 +07:00
XMRig
dc2c0552e0 Moved current valid algorithm to first position in algo list. 2019-07-20 01:43:36 +07:00
XMRig
d2ca254789 Disable rx/0 algorithm. 2019-07-20 01:20:50 +07:00
XMRig
222cebba71 Fixed command line config and removed --max-cpu-usage and --safe. 2019-07-20 00:37:15 +07:00
XMRig
2fc54d240a Fixed build. 2019-07-19 05:03:14 +07:00
XMRig
ca7fb33848 Removed class ApiRouter. 2019-07-19 04:41:48 +07:00
XMRig
1d78e7d60d "GET /1/threads" replaced to "GET /2/backends". 2019-07-19 04:22:21 +07:00
XMRig
fa2c9df075 Implemented "enabled" field for CPU backend; 2019-07-19 02:39:00 +07:00
XMRig
d9164c0b7b Restored "GET /1/summary" endpoint. 2019-07-19 02:24:37 +07:00
XMRig
691b2fabbf Restored algorithm verification. 2019-07-19 00:39:27 +07:00
XMRig
88edde804f Fixed duplicated shares after donation round. 2019-07-18 23:48:16 +07:00
XMRig
0ab26a1619 Restored algo field in login request. 2019-07-18 22:35:15 +07:00
XMRig
f590cf58fb Added support for threads restart if config changed. 2019-07-18 19:11:45 +07:00
XMRig
871bc3e180 Fixed bugs. 2019-07-18 04:21:14 +07:00
XMRig
6f93b7b38d Removed unused code. 2019-07-17 15:28:59 +07:00
XMRig
630a5dce67 Improved log. 2019-07-17 15:09:37 +07:00
XMRig
8ce00adda4 Restored "CPU READY" message. 2019-07-17 14:54:08 +07:00
XMRig
4f49533e98 Fixed warnings. 2019-07-17 05:33:13 +07:00
XMRig
bcae974ea1 Fixed build. 2019-07-17 05:01:12 +07:00
XMRig
2bf5ffb2df Class Mem replaced to VirtualMemory. 2019-07-17 04:57:58 +07:00
XMRig
20313cbc56 Implemented unified cryptonight and RandomX scratchpad memory. 2019-07-17 04:33:11 +07:00
XMRig
5699147aab Restored printable hashrate. 2019-07-17 01:28:42 +07:00
XMRig
27f3008d79 Added initial support for new style threads launch method. 2019-07-16 22:10:50 +07:00
XMRig
dff59fabc2 Removed CPU specific code from Worker class. 2019-07-14 00:35:38 +07:00
XMRig
ee434a5708 Move files. 2019-07-13 22:15:53 +07:00
XMRig
dc87ef6062 Removed xmrig.h. 2019-07-13 19:10:17 +07:00
XMRig
8b3f2d8fff Move Platform. 2019-07-13 16:48:14 +07:00
XMRig
4643742d13 Refactoring 2019-07-13 00:49:17 +07:00
XMRig
be7ff62c48 Removed no longer required code. 2019-07-12 02:25:07 +07:00
XMRig
6f27037f07 Added new nonce allocation method for dynamic/variable threads. 2019-07-11 16:15:51 +07:00
XMRig
8e2219b7c4 Fixed RandomX VM creation in some cases. 2019-07-10 10:26:10 +07:00
XMRig
270d3ba6a2 Added class RxVm. 2019-07-10 10:14:33 +07:00
XMRig
3bebf778da Fixed build. 2019-07-10 02:28:45 +07:00
XMRig
f42adafee0 Added classes Rx, RxAlgo, RxCache, RxDataset. 2019-07-10 01:53:05 +07:00
XMRig
ea1149a971 Added class JobResults. 2019-07-06 15:22:19 +07:00
XMRig
9bf4c2c98f Generate "rx" and "rx/wow" sections of CPU threads. 2019-07-06 11:31:12 +07:00
XMRig
9b14caa9f9 Merge branch 'evo' into feature-per-pool-algo 2019-07-06 10:49:31 +07:00
XMRig
8c02e20828 Quick fixes. 2019-07-02 22:57:08 +07:00
XMRig
b92807e8d8 Added support for multi-algorithm CPU threads settings. 2019-07-02 22:56:28 +07:00
XMRig
ee9538ab22 Fixed, client was stuck on some pools. 2019-07-02 22:38:09 +07:00
xmrig
02410fa084 Merge pull request #1050 from SChernykh/dev
Integrated RandomX, added RandomXL (Loki)
2019-07-02 22:33:35 +07:00
SChernykh
915729bec6 Fixed MingGW compilation 2019-07-01 20:48:51 +02:00
SChernykh
6eb9d0963b Integrated RandomX, added RandomXL (Loki) 2019-07-01 20:11:51 +02:00
XMRig
83fdbbf29c Added "features" and "algorithms" fields to API summary response. 2019-06-29 10:57:05 +07:00
XMRig
e10671fa51 Fixed ARM build. 2019-06-29 10:25:06 +07:00
XMRig
62edb2fc0a Move CPU information classes to new location. 2019-06-29 09:51:23 +07:00
XMRig
dd875c7c37 Added class CpuConfig. 2019-06-28 22:28:40 +07:00
XMRig
66d62de681 Merge Assembly enum and Asm class. 2019-06-28 13:08:08 +07:00
XMRig
188338c493 Merge branch 'evo' into feature-per-pool-algo 2019-06-26 15:44:52 +07:00
XMRig
0aaf2d38d4 v2.16.1-evo 2019-06-26 11:07:50 +07:00
XMRig
baa75569e2 Merge branch 'beta' into evo 2019-06-26 11:07:16 +07:00
xmrig
f7fe0a9ac3 Update CHANGELOG.md 2019-06-26 11:01:57 +07:00
xmrig
c2d662ff4c Update CHANGELOG.md 2019-06-25 14:48:43 +07:00
XMRig
6813657891 v2.16.0-beta 2019-06-25 14:17:43 +07:00
XMRig
ee93095e06 Merge branch 'evo' into beta 2019-06-25 14:17:06 +07:00
XMRig
b0a1481909 Sync changes with proxy. 2019-06-25 10:35:10 +07:00
XMRig
f7f2c09e89 Move RandowWOW to new global algorithm. 2019-06-25 08:21:40 +07:00
XMRig
cf61f49746 Use better source for AES settings in RandomX threads. 2019-06-23 14:23:29 +07:00
xmrig
1a2f9fb160 Merge pull request #1039 from SChernykh/random_wow
Fixed RandomX for CPUs without AES
2019-06-22 17:15:49 +07:00
SChernykh
187e55e28e Fixed RandomX for CPUs without AES 2019-06-19 12:45:05 +02:00
XMRig
41e0be111d v2.16.0-evo, added RandomWOW, backward compatibility with previous versions not break. 2019-06-19 01:18:31 +07:00
XMRig
e743301a79 Merge branch 'feature-randomx' into evo 2019-06-19 01:16:51 +07:00
xmrig
7a6c7aac29 Merge pull request #1037 from SChernykh/random_wow
RandomX fixes
2019-06-19 01:06:43 +07:00
SChernykh
53c9e5fe0e Merge remote-tracking branch 'upstream/feature-randomx' into random_wow 2019-06-18 19:53:26 +02:00
SChernykh
e8ac01d289 RandomX fixes
- Fixed possible infinite loop when updating RandomX dataset
- Fixed used memory display
- Allocate dataset and VM for RandomX only when it's actually used
2019-06-18 19:53:11 +02:00
XMRig
2a07cf391d Allow disable RandomX support. 2019-06-18 06:11:53 +07:00
XMRig
3d17ba6af6 Merge branch 'feature-randomx' into evo 2019-06-18 05:33:30 +07:00
XMRig
34e39e9946 Use canonical name for RandomX, because official RandomWOW repo not rename lib or headers, still need some solution to separate it in future. 2019-06-18 05:13:51 +07:00
xmrig
2b26874f11 Merge pull request #1036 from SChernykh/random_wow
RandomWOW
2019-06-18 03:49:18 +07:00
XMRig
b38e432647 Moved keccak files. 2019-06-17 04:06:38 +07:00
SChernykh
50ace41766 Fixed cmake for Linux 2019-06-15 23:52:39 +02:00
SChernykh
d0ce60a73a Fixed auto-config 2019-06-15 23:50:31 +02:00
SChernykh
202d44c147 Fixed gcc compilation 2019-06-15 23:29:13 +02:00
SChernykh
ac1b554282 RandomWOW support 2019-06-15 22:53:03 +02:00
XMRig
6990324681 Allow null algorithm for pools. 2019-06-16 03:50:22 +07:00
XMRig
b73c204e73 Fixed ARM mining code. 2019-06-15 00:28:16 +07:00
XMRig
088587fa72 Fixed build on Linux. 2019-06-14 05:21:17 +07:00
XMRig
1f0e3e501c Implemented new style algorithm definitions (except ARM), removed Algo and Variant enums. 2019-06-13 22:08:52 +07:00
XMRig
d7f42d54ad Added initial support for per pool algo option (mining code is broken). 2019-06-10 20:46:29 +07:00
XMRig
725c767928 v2.99.0-evo 2019-06-09 16:48:30 +07:00
XMRig
b684150336 Moved Algorithm class. 2019-06-09 16:46:44 +07:00
XMRig
d9eb700e03 Renamed macros for enable/disable algorithms. 2019-06-09 15:29:26 +07:00
XMRig
09cdddc7f6 Fixed ARM build, again. 2019-06-04 19:49:54 +07:00
XMRig
bd8370951f Fixed ARM build. 2019-06-04 19:27:51 +07:00
XMRig
d587eebaf2 Move files. 2019-06-04 19:20:33 +07:00
XMRig
ac43cd4f9c Added unprotectExecutableMemory for future use. 2019-06-04 15:48:32 +07:00
XMRig
f620ffe899 #1026 Probably fixed iOS build. 2019-06-03 18:40:12 +07:00
XMRig
242ece7222 Simplified cn/r code. 2019-06-02 23:38:02 +07:00
XMRig
36fcdf3f9d Fixed ARM build. 2019-06-02 21:06:30 +07:00
XMRig
ba94c08bf5 Moved mm_malloc.h 2019-06-02 20:57:49 +07:00
XMRig
8dc586283f Fixed Linux build. 2019-06-02 19:58:16 +07:00
XMRig
fc655d1b8d Moved common memory primitives to new VirtualMemory class. 2019-06-02 19:43:56 +07:00
XMRig
4b3592f60f v2.15.5-evo 2019-06-02 15:03:26 +07:00
XMRig
cd32677ad4 Merge branch 'beta' into evo 2019-06-02 15:02:19 +07:00
XMRig
277f188cd5 v2.15.4-beta 2019-06-02 14:30:09 +07:00
XMRig
e28c3db019 Merge branch 'evo' into beta 2019-06-02 14:29:39 +07:00
xmrig
5dde5dbf4e Update CHANGELOG.md 2019-06-02 14:18:13 +07:00
xmrig
9726f8cf9d Update CHANGELOG.md 2019-06-02 14:16:45 +07:00
XMRig
833a532e7a Merge branch 'dev' into evo 2019-05-31 23:20:35 +07:00
XMRig
3dde8cacff v2.14.5-dev 2019-05-31 22:50:39 +07:00
XMRig
84b359f29c Merge branch 'master' into dev 2019-05-31 22:50:13 +07:00
XMRig
2d8e8c92ab v2.14.4 2019-05-30 12:16:19 +07:00
XMRig
651009e1b9 Merge branch 'dev' 2019-05-30 12:11:47 +07:00
XMRig
1d4bc030fb v2.14.4-dev 2019-05-26 19:28:28 +07:00
xmrig
809efb4700 Update CHANGELOG.md 2019-05-26 19:21:13 +07:00
XMRig
10165da53e Removed obsolete automatic variants. 2019-05-26 18:54:47 +07:00
XMRig
51b92f66cf Sync changes. 2019-05-25 10:58:35 +07:00
XMRig
6fb014d0b1 Fixed MSVC 2019 version detection. 2019-05-21 12:14:20 +07:00
XMRig
ffb282a11a Added global uptime and extended connection information for API. 2019-05-13 00:11:57 +07:00
XMRig
a000544fdc Return current algorithm in API response. 2019-05-01 22:07:13 +07:00
XMRig
378bc504fc Use null for unknown hashrate in API. 2019-04-25 02:22:53 +07:00
XMRig
304d7bd09a v2.15.4-evo 2019-04-18 20:59:14 +07:00
XMRig
e9e2d7d152 Merge branch 'beta' into evo 2019-04-18 20:58:32 +07:00
XMRig
8b0d35b619 #1014 Fixed regression, default value for algo option was not applied. 2019-04-18 15:23:36 +07:00
XMRig
e46a2a508a v2.15.2-beta 2019-04-18 00:25:37 +07:00
XMRig
fe9aa9f3c4 Merge branch 'evo' into beta 2019-04-18 00:25:06 +07:00
xmrig
552858b9e3 Update CHANGELOG.md 2019-04-17 23:59:21 +07:00
XMRig
ff6544a14c Updated default config. 2019-04-17 19:03:15 +07:00
XMRig
d77e404439 Merge branch 'dev' into evo 2019-04-17 17:42:22 +07:00
xmrig
ff4d54dc4c Merge pull request #1012 from Spudz76/dev-fixClang9
Repair compilation with Clang 9.0.0
2019-04-16 02:37:19 +07:00
Tony Butler
699269bbae Upstream fixed it for good with [Added checks for _rotr.] and [Fixed _rotr detection.] 2019-04-15 13:26:55 -06:00
XMRig
9137f59ec1 #1012 Fixed _rotr detection. 2019-04-16 02:00:27 +07:00
XMRig
f9f7ef26b8 #1012 Added checks for _rotr. 2019-04-16 01:20:50 +07:00
Tony Butler
32c3d4b9f6 Repair compilation with Clang 9.0.0 (which now includes its own _rotr intrinsic) 2019-04-15 10:39:16 -06:00
XMRig
ee1d61d117 Fix Linux build. 2019-04-14 03:24:14 +07:00
XMRig
a3b303e885 Added checking for top_block_hash/hash. 2019-04-14 03:21:23 +07:00
XMRig
074b3869d2 Added JsonRequest. 2019-04-14 01:10:24 +07:00
XMRig
c0e668f36f Move files. 2019-04-13 23:58:58 +07:00
XMRig
21798edb8b Sync changes. 2019-04-13 19:09:22 +07:00
XMRig
23b0e3799e Fixed build on some systems. 2019-04-12 22:32:45 +07:00
XMRig
83a7a88b11 Fixed build without TLS support. 2019-04-12 19:25:03 +07:00
XMRig
60f6817d21 Merge branch 'feature-daemon' into evo 2019-04-12 19:08:30 +07:00
XMRig
867478b983 Added command line option --daemon and --daemon-poll-interval 2019-04-12 18:30:08 +07:00
XMRig
5e369a5af8 Fixed daemon support over HTTPS. 2019-04-12 04:25:47 +07:00
XMRig
62012a1a50 Added DaemonClient. 2019-04-12 03:25:21 +07:00
xmrig
54a1c614f7 Merge pull request #1011 from stoffu/config-max-msvc2017
Config: fix std::max issue with msvc2017
2019-04-11 14:08:45 +07:00
stoffu
cf7ce13986 Config: fix std::max issue with msvc2017
to fix the following errors:

    xmrig\src\core\Config.cpp(165): error C2065: 'max': undeclared identifier
    xmrig\src\core\Config.cpp(165): error C2275: 'size_t': illegal use of this type as an expression
2019-04-11 14:01:07 +09:00
XMRig
0d496aaf2f Prepare for daemon support. 2019-04-11 00:18:33 +07:00
XMRig
9a6944d694 Add IClient and BaseClient. 2019-04-10 18:29:33 +07:00
XMRig
1bd8d63508 64bit diff support. 2019-04-10 03:42:00 +07:00
XMRig
c41889477c Fix build. 2019-04-10 00:10:02 +07:00
XMRig
c823c54f9b Added HttpsClient. 2019-04-09 14:06:56 +07:00
XMRig
6812d22d63 Rename cmake option WITH_HTTPD to WITH_HTTP. 2019-04-09 02:27:19 +07:00
XMRig
241383068c Added HttpClient class. 2019-04-09 01:59:22 +07:00
XMRig
35d868fb48 Fix --userpass option. 2019-04-08 02:16:54 +07:00
XMRig
d6da0652ce Removed unused setters in Pool class. 2019-04-07 21:31:32 +07:00
XMRig
9561570c50 Fix build on FreeBSD. 2019-04-06 21:10:26 +07:00
XMRig
466aad8543 Fix build without ASM. 2019-04-06 20:07:20 +07:00
XMRig
db456a3e63 Merge branch 'feature-json-centric-config' into evo 2019-04-06 18:34:38 +07:00
XMRig
09df8c3846 Sync changes. 2019-04-06 18:32:24 +07:00
XMRig
5d9648956b Add milliseconds to log. 2019-04-06 02:11:02 +07:00
XMRig
1774b42345 Fix "colors" option. 2019-04-06 02:10:08 +07:00
XMRig
fa2a0b9b79 New config subsystem 2019-04-05 22:14:01 +07:00
XMRig
85ee55f309 Fixed, big HTTP responses was truncated. 2019-04-02 17:46:26 +07:00
XMRig
4aa7f01f13 v2.15.2-evo 2019-04-01 23:45:23 +07:00
XMRig
496870a59d Merge branch 'beta' into evo 2019-04-01 23:41:38 +07:00
XMRig
89d7e84f88 v2.15.1-beta 2019-04-01 19:04:48 +07:00
XMRig
29f683b01f Merge branch 'evo' into beta 2019-04-01 19:04:20 +07:00
xmrig
1e3e8df43c Update CHANGELOG.md 2019-04-01 19:01:34 +07:00
XMRig
1f45e77848 Fixed wrong status code for "GET /1/config" 2019-04-01 18:56:42 +07:00
xmrig
356fd04b0f Update README.md 2019-04-01 18:55:30 +07:00
xmrig
5a4720cf4a Merge pull request #1008 from snider/master
updates image used in readme for new pool url
2019-04-01 18:55:06 +07:00
snider
c0e2a15614 updates image used in readme for new pool url 2019-04-01 12:16:36 +01:00
XMRig
cf7245b469 Update default config. 2019-04-01 11:54:09 +07:00
XMRig
3b91817caf Special handle for favicon.ico 2019-04-01 11:50:28 +07:00
XMRig
4457089502 Added error log to http responses. 2019-04-01 02:46:41 +07:00
XMRig
40d9f53743 Sync changes. 2019-04-01 00:31:46 +07:00
XMRig
24e4328915 Fixed malformed HTTP response on Linux. 2019-04-01 00:21:15 +07:00
XMRig
0245ce5f35 Fix compile issue. 2019-04-01 00:00:40 +07:00
XMRig
96f5bd32b5 Merge branch 'feature-httpd' into evo 2019-03-31 23:34:17 +07:00
XMRig
e759ccf385 Sync changes. 2019-03-31 23:22:36 +07:00
XMRig
ca249f1f1c Cleanup. 2019-03-31 01:44:53 +07:00
XMRig
f8f9d6c0ef Restored API. 2019-03-31 01:31:40 +07:00
XMRig
e39ddeeea2 Removed IConfigCreator/ConfigCreator and changed file structure. 2019-03-30 21:27:54 +07:00
XMRig
d8aba7da7d Revert id and worker_id. 2019-03-30 20:46:08 +07:00
XMRig
bd6c7c64aa Added workaround, Google Chrome create extra dummy connections for future speed up. 2019-03-30 15:51:35 +07:00
XMRig
106e149324 Use static http_parser_settings. 2019-03-30 15:27:09 +07:00
XMRig
c9f9e6787c Restore network API. 2019-03-30 03:10:27 +07:00
XMRig
9c66c9b30f Added classes IApiRequest, ApiRequest, HttpApiRequest. 2019-03-30 02:26:30 +07:00
XMRig
dd036368e2 New API class. 2019-03-30 00:16:01 +07:00
XMRig
9cb43f9883 Fix log. 2019-03-29 17:22:25 +07:00
XMRig
3f1eefb131 HTTP layer ready for API calls. 2019-03-29 17:14:30 +07:00
XMRig
202b74367a Optimize HttpResponse for fixed size API responses. 2019-03-29 14:22:10 +07:00
XMRig
9daa5874f5 Change HttpResponse creation method. 2019-03-29 12:56:34 +07:00
XMRig
01ad6bf2d9 Added new HTTP server (tiny wrapper on top of libuv + http_parser), removed libmicrohttpd support. 2019-03-29 12:33:11 +07:00
XMRig
725796a1ab New API settings. 2019-03-29 02:31:56 +07:00
XMRig
1e0c410eea XMRIG_FEATURE_HTTP & XMRIG_FEATURE_API 2019-03-28 22:54:27 +07:00
XMRig
034720e888 Use XMRIG_FEATURE_TLS instead of XMRIG_NO_TLS 2019-03-28 22:13:27 +07:00
xmrig
22483dd231 Update CHANGELOG.md 2019-03-27 21:18:48 +07:00
XMRig
5db458efd4 Fix macOS build. 2019-03-27 20:03:15 +07:00
XMRig
3f4886bb86 Fix CPU info colors. 2019-03-27 19:29:29 +07:00
XMRig
82bbef614e Remove unused field. 2019-03-27 19:27:29 +07:00
XMRig
933c0d40b7 Merge branch 'dev' into evo 2019-03-27 19:20:12 +07:00
XMRig
cad3e7a101 Sync changes. 2019-03-27 19:18:54 +07:00
XMRig
d7795ca990 Remove uv_cancel for DNS requests. 2019-03-27 17:22:04 +07:00
XMRig
ba910a46ba Fix accidentally removed code. 2019-03-27 15:56:31 +07:00
XMRig
f43929db98 New log support. 2019-03-27 01:29:37 +07:00
XMRig
17e9e036f1 Fix Linux build. 2019-03-26 22:05:56 +07:00
XMRig
ced25c3fa0 Log subsystem rewritten, to handle both color and not color logs simultaneously and overall simplicity. 2019-03-26 19:56:35 +07:00
XMRig
0a893c2172 Merge branch 'beta' into evo 2019-03-24 21:33:06 +07:00
XMRig
177e0c9c26 v2.15.0-beta 2019-03-24 02:35:51 +07:00
xmrig
a891d2a590 Update CHANGELOG.md 2019-03-24 02:34:54 +07:00
XMRig
cf7df3f629 v2.15.0-evo 2019-03-20 11:55:15 +07:00
XMRig
453443a2f1 Merge branch 'feature-donate-over-proxy' into evo 2019-03-20 11:53:18 +07:00
XMRig
8d61a47040 Fix uv_tty_reset_mode on Linux. 2019-03-19 22:13:43 +07:00
XMRig
4c95136e6a Implemented donate over proxy. 2019-03-19 21:31:54 +07:00
XMRig
0907d1eb0c Added "donate-over-proxy" option. 2019-03-19 00:16:30 +07:00
XMRig
55686c7d57 Use new Timer inside DonateStrategy. 2019-03-18 13:40:56 +07:00
XMRig
9a6a5a94b5 Add class Timer. 2019-03-18 02:36:17 +07:00
XMRig
bbf0d11a51 Sync changes. 2019-03-17 16:03:45 +07:00
XMRig
c94c0210f7 Fix copy. 2019-03-16 13:32:00 +07:00
XMRig
1b9fbf1132 Fix compile issues. 2019-03-16 13:10:04 +07:00
XMRig
0d86e53a32 Move files. 2019-03-16 02:07:26 +07:00
xmrig
1f77b049e3 Merge pull request #992 from Spudz76/dev-clang35fix
Fix compilation with Clang 3.5
2019-03-16 01:30:13 +07:00
XMRig
ba68fb6c53 Added real graceful exit. 2019-03-16 00:44:15 +07:00
Tony Butler
29373c4226 Fix compilation with Clang 3.5 for those with limited compiler choices
Performance similar to gcc7+ on systems where gcc4 is the only alternative
2019-03-15 07:19:47 -06:00
XMRig
1e62943010 Fix memory leak. 2019-03-15 18:54:45 +07:00
XMRig
af3655c27e Add classes Dns, DnsRecord, IDnsListener. 2019-03-15 18:14:25 +07:00
XMRig
3094741c64 Remove file SubmitResult.cpp. 2019-03-15 12:54:00 +07:00
XMRig
f5077cadbd Added class RecvBuf. 2019-03-15 03:44:02 +07:00
XMRig
9808fbe396 Added class Buffer. 2019-03-15 02:25:38 +07:00
XMRig
8c362411ef Removed class Id. 2019-03-15 02:03:01 +07:00
XMRig
ba01f2a9c4 Rename files. 2019-03-15 01:50:35 +07:00
XMRig
be5d609856 Client refactoring. 2019-03-15 01:06:10 +07:00
XMRig
d57b41c673 Sync changes. 2019-03-14 18:42:27 +07:00
xmrig
fb62ee938a Merge pull request #987 from SChernykh/dev
Unified ASM functions signature
2019-03-14 13:39:30 +07:00
SChernykh
1bb8f77b52 Unified ASM functions signature 2019-03-13 22:00:44 +01:00
XMRig
5d9ebb0b91 v2.14.2-dev 2019-03-07 17:51:54 +07:00
XMRig
d4f6eaa371 Merge branch 'master' into dev 2019-03-07 17:51:17 +07:00
xmrig
08ef94486b Update CHANGELOG.md 2019-03-07 15:16:42 +07:00
XMRig
1042f23dd5 v2.14.1 2019-03-07 15:02:55 +07:00
XMRig
80a7aa2497 #975 Fixed crash on Linux if used double thread. 2019-03-07 14:52:40 +07:00
388 changed files with 29345 additions and 10049 deletions

View File

@@ -1,3 +1,51 @@
# v2.99.0-beta
- [#1050](https://github.com/xmrig/xmrig/pull/1050) Added RandomXL algorithm for [Loki](https://loki.network/), algorithm name used by miner is `randomx/loki` or `rx/loki`.
- Added [flexible](https://github.com/xmrig/xmrig/blob/evo/doc/CPU.md) multi algorithm configuration.
- Added unlimited switching between incompatible algorithms, all mining options can be changed in runtime.
- Breaked backward compatibility with previous configs and command line, `variant` option replaced to `algo`, global option `algo` removed, all CPU related settings moved to `cpu` object.
- Options `av`, `safe` and `max-cpu-usage` removed.
- Algorithm `cn/msr` renamed to `cn/fast`.
- Algorithm `cn/xtl` removed.
- API endpoint `GET /1/threads` replaced to `GET /2/backends`.
# v2.16.0-beta
- [#1036](https://github.com/xmrig/xmrig/pull/1036) Added RandomWOW (RandomX with different preferences) algorithm support for [Wownero](http://wownero.org/).
- Algorithm name used by miner is `randomx/wow` or `rx/wow`.
- Currently runtime algorithm switching NOT supported with other algorithms.
# v2.15.4-beta
- Added global uptime and extended connection information in API.
- API now return current algorithm instead of global algorithm specified in config.
- This version also include all changes from stable version v2.14.4.
# v2.15.3-beta
- [#1014](https://github.com/xmrig/xmrig/issues/1014) Fixed regression, default value for `algo` option was not applied.
# v2.15.2-beta
- [#1010](https://github.com/xmrig/xmrig/pull/1010#issuecomment-482632107) Added daemon support (solo mining).
- [#1012](https://github.com/xmrig/xmrig/pull/1012) Fixed compatibility with clang 9.
- Config subsystem was rewritten, internally JSON is primary format now.
- Fixed regression, big HTTP responses was truncated.
# v2.15.1-beta
- [#1007](https://github.com/xmrig/xmrig/issues/1007) Old HTTP API backend based on libmicrohttpd, replaced to custom HTTP server (libuv + http_parser).
- [#257](https://github.com/xmrig/xmrig-nvidia/pull/257) New logging subsystem, file and syslog now always without colors.
# v2.15.0-beta
- [#314](https://github.com/xmrig/xmrig-proxy/issues/314) Added donate over proxy feature.
- Added new option `donate-over-proxy`.
- Added real graceful exit.
# v2.14.4
- [#992](https://github.com/xmrig/xmrig/pull/992) Fixed compilation with Clang 3.5.
- [#1012](https://github.com/xmrig/xmrig/pull/1012) Fixed compilation with Clang 9.0.
- In HTTP API for unknown hashrate now used `null` instead of `0.0`.
- Fixed MSVC 2019 version detection.
- Removed obsolete automatic variants.
# v2.14.1
* [#975](https://github.com/xmrig/xmrig/issues/975) Fixed crash on Linux if double thread mode used.
# v2.14.0
- **[#969](https://github.com/xmrig/xmrig/pull/969) Added new algorithm `cryptonight/rwz`, short alias `cn/rwz` (also known as CryptoNight ReverseWaltz), for upcoming [Graft](https://www.graft.network/) fork.**
- **[#931](https://github.com/xmrig/xmrig/issues/931) Added new algorithm `cryptonight/zls`, short alias `cn/zls` for [Zelerius Network](https://zelerius.org) fork.**

View File

@@ -2,11 +2,12 @@ cmake_minimum_required(VERSION 2.8)
project(xmrig)
option(WITH_LIBCPUID "Use Libcpuid" ON)
option(WITH_AEON "CryptoNight-Lite support" ON)
option(WITH_SUMO "CryptoNight-Heavy support" ON)
option(WITH_CN_LITE "CryptoNight-Lite support" ON)
option(WITH_CN_HEAVY "CryptoNight-Heavy support" ON)
option(WITH_CN_PICO "CryptoNight-Pico support" ON)
option(WITH_CN_GPU "CryptoNight-GPU support" ON)
option(WITH_HTTPD "HTTP REST API" ON)
option(WITH_RANDOMX "RandomX support" ON)
option(WITH_HTTP "HTTP protocol support (client/server)" ON)
option(WITH_DEBUG_LOG "Enable debug log output" OFF)
option(WITH_TLS "Enable OpenSSL support" ON)
option(WITH_ASM "Enable ASM PoW implementations" ON)
@@ -16,172 +17,112 @@ option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF)
include (CheckIncludeFile)
include (cmake/cpu.cmake)
include (src/base/base.cmake)
include (src/backend/backend.cmake)
set(HEADERS
src/api/NetworkState.h
"${HEADERS_BASE}"
"${HEADERS_BASE_HTTP}"
"${HEADERS_BACKEND}"
src/api/interfaces/IApiListener.h
src/App.h
src/base/io/Json.h
src/base/io/Watcher.h
src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/ISignalListener.h
src/base/kernel/interfaces/IWatcherListener.h
src/base/kernel/Entry.h
src/base/kernel/Process.h
src/base/kernel/Signals.h
src/base/net/Pool.h
src/base/net/Pools.h
src/base/tools/Arguments.h
src/base/tools/Handle.h
src/base/tools/String.h
src/common/config/CommonConfig.h
src/common/config/ConfigLoader.h
src/common/config/ConfigWatcher.h
src/common/Console.h
src/common/cpu/Cpu.h
src/common/crypto/Algorithm.h
src/common/crypto/keccak.h
src/common/interfaces/IClientListener.h
src/common/interfaces/IConfig.h
src/common/interfaces/IConfigCreator.h
src/common/interfaces/IConsoleListener.h
src/common/interfaces/IControllerListener.h
src/common/interfaces/ICpuInfo.h
src/common/interfaces/ILogBackend.h
src/common/interfaces/IStrategy.h
src/common/interfaces/IStrategyListener.h
src/common/log/BasicLog.h
src/common/log/ConsoleLog.h
src/common/log/FileLog.h
src/common/log/Log.h
src/common/net/Client.h
src/common/net/Id.h
src/common/net/Job.h
src/common/net/Storage.h
src/common/net/strategies/FailoverStrategy.h
src/common/net/strategies/SinglePoolStrategy.h
src/common/net/SubmitResult.h
src/common/Platform.h
src/common/utils/c_str.h
src/common/utils/mm_malloc.h
src/common/xmrig.h
src/core/ConfigLoader_platform.h
src/core/ConfigLoader_default.h
src/core/config/Config_default.h
src/core/config/Config_platform.h
src/core/config/Config.h
src/core/config/ConfigTransform.h
src/core/config/usage.h
src/core/Controller.h
src/interfaces/IJobResultListener.h
src/interfaces/IThread.h
src/interfaces/IWorker.h
src/Mem.h
src/core/Miner.h
src/net/interfaces/IJobResultListener.h
src/net/JobResult.h
src/net/JobResults.h
src/net/Network.h
src/net/NetworkState.h
src/net/strategies/DonateStrategy.h
src/Summary.h
src/version.h
src/workers/CpuThread.h
src/workers/Handle.h
src/workers/Hashrate.h
src/workers/MultiWorker.h
src/workers/Worker.h
src/workers/Workers.h
)
set(HEADERS_CRYPTO
src/crypto/c_blake256.h
src/crypto/c_groestl.h
src/crypto/c_jh.h
src/crypto/c_skein.h
src/crypto/CryptoNight.h
src/crypto/CryptoNight_constants.h
src/crypto/CryptoNight_monero.h
src/crypto/CryptoNight_test.h
src/crypto/groestl_tables.h
src/crypto/hash.h
src/crypto/skein_port.h
src/crypto/soft_aes.h
src/crypto/asm/CryptonightR_template.h
src/crypto/cn/asm/CryptonightR_template.h
src/crypto/cn/c_blake256.h
src/crypto/cn/c_groestl.h
src/crypto/cn/c_jh.h
src/crypto/cn/c_skein.h
src/crypto/cn/CnAlgo.h
src/crypto/cn/CnCtx.h
src/crypto/cn/CnHash.h
src/crypto/cn/CryptoNight_monero.h
src/crypto/cn/CryptoNight_test.h
src/crypto/cn/CryptoNight.h
src/crypto/cn/groestl_tables.h
src/crypto/cn/hash.h
src/crypto/cn/skein_port.h
src/crypto/cn/soft_aes.h
src/crypto/common/Algorithm.h
src/crypto/common/keccak.h
src/crypto/common/Nonce.h
src/crypto/common/portable/mm_malloc.h
src/crypto/common/VirtualMemory.h
)
if (XMRIG_ARM)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_arm.h)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_arm.h)
else()
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/CryptoNight_x86.h)
set(HEADERS_CRYPTO "${HEADERS_CRYPTO}" src/crypto/cn/CryptoNight_x86.h)
endif()
set(SOURCES
src/api/NetworkState.cpp
"${SOURCES_BASE}"
"${SOURCES_BASE_HTTP}"
"${SOURCES_BACKEND}"
src/App.cpp
src/base/io/Json.cpp
src/base/io/Watcher.cpp
src/base/kernel/Entry.cpp
src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp
src/base/net/Pool.cpp
src/base/net/Pools.cpp
src/base/tools/Arguments.cpp
src/base/tools/Handle.cpp
src/base/tools/String.cpp
src/common/config/CommonConfig.cpp
src/common/config/ConfigLoader.cpp
src/common/config/ConfigWatcher.cpp
src/common/Console.cpp
src/common/crypto/Algorithm.cpp
src/common/crypto/keccak.cpp
src/common/log/BasicLog.cpp
src/common/log/ConsoleLog.cpp
src/common/log/FileLog.cpp
src/common/log/Log.cpp
src/common/net/Client.cpp
src/common/net/Job.cpp
src/common/net/strategies/FailoverStrategy.cpp
src/common/net/strategies/SinglePoolStrategy.cpp
src/common/net/SubmitResult.cpp
src/common/Platform.cpp
src/core/Config.cpp
src/core/config/Config.cpp
src/core/config/ConfigTransform.cpp
src/core/Controller.cpp
src/Mem.cpp
src/core/Miner.cpp
src/net/JobResults.cpp
src/net/Network.cpp
src/net/NetworkState.cpp
src/net/strategies/DonateStrategy.cpp
src/Summary.cpp
src/workers/CpuThread.cpp
src/workers/Handle.cpp
src/workers/Hashrate.cpp
src/workers/MultiWorker.cpp
src/workers/Worker.cpp
src/workers/Workers.cpp
src/xmrig.cpp
)
set(SOURCES_CRYPTO
src/crypto/c_groestl.c
src/crypto/c_blake256.c
src/crypto/c_jh.c
src/crypto/c_skein.c
src/crypto/cn/c_blake256.c
src/crypto/cn/c_groestl.c
src/crypto/cn/c_jh.c
src/crypto/cn/c_skein.c
src/crypto/cn/CnCtx.cpp
src/crypto/cn/CnHash.cpp
src/crypto/common/Algorithm.cpp
src/crypto/common/keccak.cpp
src/crypto/common/Nonce.cpp
)
if (WIN32)
set(SOURCES_OS
"${SOURCES_OS}"
res/app.rc
src/App_win.cpp
src/base/io/Json_win.cpp
src/common/Platform_win.cpp
src/Mem_win.cpp
src/crypto/common/VirtualMemory_win.cpp
)
add_definitions(/DWIN32)
set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv)
elseif (APPLE)
set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_mac.cpp
src/Mem_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)
else()
set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp
src/base/io/Json_unix.cpp
src/common/Platform_unix.cpp
src/Mem_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)
if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
@@ -205,80 +146,98 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
find_package(UV REQUIRED)
include(cmake/flags.cmake)
if (WITH_LIBCPUID)
add_subdirectory(src/3rdparty/libcpuid)
include_directories(src/3rdparty/libcpuid)
set(CPUID_LIB cpuid)
set(SOURCES_CPUID src/core/cpu/AdvancedCpuInfo.h src/core/cpu/AdvancedCpuInfo.cpp src/core/cpu/Cpu.cpp)
else()
add_definitions(/DXMRIG_NO_LIBCPUID)
set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp)
if (XMRIG_ARM)
set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp)
else()
set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp)
if (WITH_RANDOMX)
include_directories(src/crypto/randomx)
add_definitions(/DXMRIG_ALGO_RANDOMX)
set(SOURCES_CRYPTO
"${SOURCES_CRYPTO}"
src/crypto/randomx/aes_hash.cpp
src/crypto/randomx/allocator.cpp
src/crypto/randomx/argon2_core.c
src/crypto/randomx/argon2_ref.c
src/crypto/randomx/blake2_generator.cpp
src/crypto/randomx/blake2/blake2b.c
src/crypto/randomx/bytecode_machine.cpp
src/crypto/randomx/dataset.cpp
src/crypto/randomx/instructions_portable.cpp
src/crypto/randomx/randomx.cpp
src/crypto/randomx/reciprocal.c
src/crypto/randomx/soft_aes.cpp
src/crypto/randomx/superscalar.cpp
src/crypto/randomx/virtual_machine.cpp
src/crypto/randomx/virtual_memory.cpp
src/crypto/randomx/vm_compiled_light.cpp
src/crypto/randomx/vm_compiled.cpp
src/crypto/randomx/vm_interpreted_light.cpp
src/crypto/randomx/vm_interpreted.cpp
src/crypto/rx/Rx.cpp
src/crypto/rx/Rx.h
src/crypto/rx/RxAlgo.cpp
src/crypto/rx/RxAlgo.h
src/crypto/rx/RxCache.cpp
src/crypto/rx/RxCache.h
src/crypto/rx/RxDataset.cpp
src/crypto/rx/RxDataset.h
src/crypto/rx/RxVm.cpp
src/crypto/rx/RxVm.h
)
if (NOT ARCH_ID)
set(ARCH_ID ${CMAKE_HOST_SYSTEM_PROCESSOR})
endif()
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
enable_language(ASM_MASM)
list(APPEND SOURCES_CRYPTO
src/crypto/randomx/jit_compiler_x86_static.asm
src/crypto/randomx/jit_compiler_x86.cpp
)
elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND SOURCES_CRYPTO
src/crypto/randomx/jit_compiler_x86_static.S
src/crypto/randomx/jit_compiler_x86.cpp
)
# cheat because cmake and ccache hate each other
set_property(SOURCE src/crypto/randomx/jit_compiler_x86_static.S PROPERTY LANGUAGE C)
endif()
else()
remove_definitions(/DXMRIG_ALGO_RANDOMX)
endif()
include(cmake/flags.cmake)
include(cmake/OpenSSL.cmake)
include(cmake/asm.cmake)
include(cmake/cn-gpu.cmake)
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_SYSLOG_H)
set(SOURCES_SYSLOG src/common/log/SysLog.h src/common/log/SysLog.cpp)
if (WITH_CN_LITE)
add_definitions(/DXMRIG_ALGO_CN_LITE)
endif()
if (NOT WITH_AEON)
add_definitions(/DXMRIG_NO_AEON)
if (WITH_CN_HEAVY)
add_definitions(/DXMRIG_ALGO_CN_HEAVY)
endif()
if (NOT WITH_SUMO)
add_definitions(/DXMRIG_NO_SUMO)
endif()
if (NOT WITH_IPBC)
add_definitions(/DXMRIG_NO_IPBC)
endif()
if (NOT WITH_CN_PICO)
add_definitions(/DXMRIG_NO_CN_PICO)
if (WITH_CN_PICO)
add_definitions(/DXMRIG_ALGO_CN_PICO)
endif()
if (WITH_EMBEDDED_CONFIG)
add_definitions(/DXMRIG_FEATURE_EMBEDDED_CONFIG)
endif()
if (WITH_HTTPD)
find_package(MHD)
if (MHD_FOUND)
include_directories(${MHD_INCLUDE_DIRS})
set(HTTPD_SOURCES
src/api/Api.h
src/api/ApiRouter.h
src/common/api/HttpBody.h
src/common/api/Httpd.h
src/common/api/HttpReply.h
src/common/api/HttpRequest.h
src/api/Api.cpp
src/api/ApiRouter.cpp
src/common/api/Httpd.cpp
src/common/api/HttpRequest.cpp
)
else()
message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
endif()
if (WITH_HTTP)
set(HTTP_SOURCES
src/api/Api.cpp
src/api/Api.h
src/api/Httpd.cpp
src/api/Httpd.h
src/api/interfaces/IApiRequest.h
src/api/requests/ApiRequest.cpp
src/api/requests/ApiRequest.h
src/api/requests/HttpApiRequest.cpp
src/api/requests/HttpApiRequest.h
)
else()
set(HTTPD_SOURCES "")
set(MHD_LIBRARY "")
add_definitions(/DXMRIG_NO_HTTPD)
add_definitions(/DXMRIG_NO_API)
set(HTTP_SOURCES "")
endif()
include_directories(src)
@@ -293,5 +252,5 @@ if (WITH_DEBUG_LOG)
add_definitions(/DAPP_DEBUG)
endif()
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTP_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES} ${CN_GPU_SOURCES})
target_link_libraries(${CMAKE_PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB})

View File

@@ -13,7 +13,7 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
* This is the **CPU-mining** version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
<img src="http://i.imgur.com/OKZRVDh.png" width="619" >
<img src="http://i.imgur.com/Ymumes5.png" width="670" >
#### Table of contents
* [Features](#features)

View File

@@ -1,49 +0,0 @@
# - Try to find MHD
# Once done this will define
#
# MHD_FOUND - system has MHD
# MHD_INCLUDE_DIRS - the MHD include directory
# MHD_LIBRARY - Link these to use MHD
find_path(
MHD_INCLUDE_DIR
NAMES microhttpd.h
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "include"
DOC "microhttpd include dir"
NO_DEFAULT_PATH
)
find_path(MHD_INCLUDE_DIR NAMES microhttpd.h)
find_library(
MHD_LIBRARY
NAMES libmicrohttpd.a microhttpd libmicrohttpd
PATHS "${XMRIG_DEPS}" ENV "XMRIG_DEPS"
PATH_SUFFIXES "lib"
DOC "microhttpd library"
NO_DEFAULT_PATH
)
find_library(MHD_LIBRARY NAMES microhttpd libmicrohttpd)
set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
set(MHD_LIBRARIES ${MHD_LIBRARY})
# debug library on windows
# same naming convention as in qt (appending debug library with d)
# boost is using the same "hack" as us with "optimized" and "debug"
# official MHD project actually uses _d suffix
if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
find_library(
MHD_LIBRARY_DEBUG
NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d
DOC "mhd debug library"
)
set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MHD DEFAULT_MSG MHD_LIBRARY MHD_INCLUDE_DIR)
mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)

View File

@@ -11,15 +11,21 @@ if (WITH_TLS)
find_package(OpenSSL)
if (OPENSSL_FOUND)
set(TLS_SOURCES src/common/net/Tls.h src/common/net/Tls.cpp)
set(TLS_SOURCES src/base/net/stratum/Tls.h src/base/net/stratum/Tls.cpp)
include_directories(${OPENSSL_INCLUDE_DIR})
if (WITH_HTTP)
set(TLS_SOURCES ${TLS_SOURCES} src/base/net/http/HttpsClient.h src/base/net/http/HttpsClient.cpp)
endif()
else()
message(FATAL_ERROR "OpenSSL NOT found: use `-DWITH_TLS=OFF` to build without TLS support")
endif()
add_definitions(/DXMRIG_FEATURE_TLS)
else()
set(TLS_SOURCES "")
set(OPENSSL_LIBRARIES "")
add_definitions(/DXMRIG_NO_TLS)
remove_definitions(/DXMRIG_FEATURE_TLS)
set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
endif()

View File

@@ -6,13 +6,13 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
if (MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
set(XMRIG_ASM_FILES
"src/crypto/asm/cn_main_loop.asm"
"src/crypto/asm/CryptonightR_template.asm"
"src/crypto/cn/asm/cn_main_loop.asm"
"src/crypto/cn/asm/CryptonightR_template.asm"
)
else()
set(XMRIG_ASM_FILES
"src/crypto/asm/win64/cn_main_loop.asm"
"src/crypto/asm/win64/CryptonightR_template.asm"
"src/crypto/cn/asm/win64/cn_main_loop.asm"
"src/crypto/cn/asm/win64/CryptonightR_template.asm"
)
endif()
@@ -22,13 +22,13 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
if (WIN32 AND CMAKE_C_COMPILER_ID MATCHES GNU)
set(XMRIG_ASM_FILES
"src/crypto/asm/win64/cn_main_loop.S"
"src/crypto/asm/CryptonightR_template.S"
"src/crypto/cn/asm/win64/cn_main_loop.S"
"src/crypto/cn/asm/CryptonightR_template.S"
)
else()
set(XMRIG_ASM_FILES
"src/crypto/asm/cn_main_loop.S"
"src/crypto/asm/CryptonightR_template.S"
"src/crypto/cn/asm/cn_main_loop.S"
"src/crypto/cn/asm/CryptonightR_template.S"
)
endif()
@@ -36,10 +36,17 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8)
endif()
add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES})
set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp src/crypto/CryptonightR_gen.cpp)
set(XMRIG_ASM_SOURCES
src/crypto/common/Assembly.h
src/crypto/common/Assembly.cpp
src/crypto/cn/r/CryptonightR_gen.cpp
)
set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
add_definitions(/DXMRIG_FEATURE_ASM)
else()
set(XMRIG_ASM_SOURCES "")
set(XMRIG_ASM_LIBRARY "")
add_definitions(/DXMRIG_NO_ASM)
remove_definitions(/DXMRIG_FEATURE_ASM)
endif()

View File

@@ -1,23 +1,25 @@
if (WITH_CN_GPU AND CMAKE_SIZEOF_VOID_P EQUAL 8)
if (XMRIG_ARM)
set(CN_GPU_SOURCES src/crypto/cn_gpu_arm.cpp)
set(CN_GPU_SOURCES src/crypto/cn/gpu/cn_gpu_arm.cpp)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/cn_gpu_arm.cpp PROPERTIES COMPILE_FLAGS "-O3")
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_arm.cpp PROPERTIES COMPILE_FLAGS "-O3")
endif()
else()
set(CN_GPU_SOURCES src/crypto/cn_gpu_avx.cpp src/crypto/cn_gpu_ssse3.cpp)
set(CN_GPU_SOURCES src/crypto/cn/gpu/cn_gpu_avx.cpp src/crypto/cn/gpu/cn_gpu_ssse3.cpp)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU OR CMAKE_CXX_COMPILER_ID MATCHES Clang)
set_source_files_properties(src/crypto/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "-O3 -mavx2")
set_source_files_properties(src/crypto/cn_gpu_ssse3.cpp PROPERTIES COMPILE_FLAGS "-O3")
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "-O3 -mavx2")
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_ssse3.cpp PROPERTIES COMPILE_FLAGS "-O3")
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set_source_files_properties(src/crypto/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "/arch:AVX")
set_source_files_properties(src/crypto/cn/gpu/cn_gpu_avx.cpp PROPERTIES COMPILE_FLAGS "/arch:AVX")
endif()
endif()
add_definitions(/DXMRIG_ALGO_CN_GPU)
else()
set(CN_GPU_SOURCES "")
add_definitions(/DXMRIG_NO_CN_GPU)
remove_definitions(/DXMRIG_ALGO_CN_GPU)
endif()

View File

@@ -10,12 +10,14 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release")
add_definitions(/DNDEBUG)
endif()
include(CheckSymbolExists)
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-class-memaccess")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-class-memaccess")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s")
if (XMRIG_ARMv8)
@@ -27,6 +29,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
add_definitions(/DHAVE_ROTR)
endif()
if (WIN32)
@@ -50,13 +54,14 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
add_definitions(/DNOMINMAX)
add_definitions(/DHAVE_ROTR)
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-missing-braces")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-missing-braces")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
if (XMRIG_ARMv8)
@@ -68,6 +73,18 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
check_symbol_exists("_rotr" "x86intrin.h" HAVE_ROTR)
if (HAVE_ROTR)
add_definitions(/DHAVE_ROTR)
endif()
endif()
endif()
if (NOT WIN32)
check_symbol_exists("__builtin___clear_cache" "stdlib.h" HAVE_BUILTIN_CLEAR_CACHE)
if (HAVE_BUILTIN_CLEAR_CACHE)
add_definitions(/DHAVE_BUILTIN_CLEAR_CACHE)
endif()
endif()

View File

@@ -1,22 +1,14 @@
# Algorithms
XMRig uses a different way to specify algorithms, compared to other miners.
Algorithm selection splitted to 2 parts:
* Global base algorithm per miner or proxy instance, `algo` option. Possible values: `cryptonight`, `cryptonight-lite`, `cryptonight-heavy`.
* Algorithm variant specified separately for each pool, `variant` option.
* [Full table for supported algorithm and variants.](https://github.com/xmrig/xmrig-proxy/blob/master/doc/STRATUM_EXT.md#14-algorithm-names-and-variants)
Since version 3 mining [algorithm](#algorithm-names) should specified for each pool separately (`algo` option), earlier versions was use one global `algo` option and per pool `variant` option (this option was removed in v3). If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) you may not specify this option at all.
#### Example
```json
{
"algo": "cryptonight",
...
"pools": [
{
"url": "...",
"variant": 1,
"algo": "cn/r",
...
}
],
@@ -24,8 +16,34 @@ Algorithm selection splitted to 2 parts:
}
```
## Mining algorithm negotiation
If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) miner will choice proper variant automaticaly and if you choice wrong base algorithm you will see error message.
#### Pools with mining algorithm negotiation support.
Pools with mining algorithm negotiation support.
* [www.hashvault.pro](https://www.hashvault.pro/)
* [moneroocean.stream](https://moneroocean.stream)
## Algorithm names
| Name | Memory | Notes |
|-----------------|--------|--------------------------------------------------------------------------------------|
| `cn/0` | 2 MB | CryptoNight (original) |
| `cn/1` | 2 MB | CryptoNight variant 1 also known as `Monero7` and `CryptoNightV7`. |
| `cn/2` | 2 MB | CryptoNight variant 2. |
| `cn/r` | 2 MB | CryptoNightR (Monero's variant 4). |
| `cn/wow` | 2 MB | CryptoNightR (Wownero). |
| `cn/fast` | 2 MB | CryptoNight variant 1 with half iterations. |
| `cn/half` | 2 MB | CryptoNight variant 2 with half iterations (Masari/Torque) |
| `cn/xao` | 2 MB | CryptoNight variant 0 (modified, Alloy only) |
| `cn/rto` | 2 MB | CryptoNight variant 1 (modified, Arto only) |
| `cn/rwz` | 2 MB | CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft). |
| `cn/zls` | 2 MB | CryptoNight variant 2 with 3/4 iterations (Zelerius). |
| `cn/double` | 2 MB | CryptoNight variant 2 with double iterations (X-CASH). |
| `cn/gpu` | 2 MB | CryptoNight-GPU (RYO). |
| `cn-lite/0` | 1 MB | CryptoNight-Lite variant 0. |
| `cn-lite/1` | 1 MB | CryptoNight-Lite variant 1. |
| `cn-heavy/0` | 4 MB | CryptoNight-Heavy . |
| `cn-heavy/xhv` | 4 MB | CryptoNight-Heavy (modified, TUBE only). |
| `cn-heavy/tube` | 4 MB | CryptoNight-Heavy (modified, Haven Protocol only). |
| `cn-pico` | 256 KB | TurtleCoin (TRTL) |
| `rx/0` | 2 MB | RandomX (reference configuration), reserved for future use. |
| `rx/wow` | 1 MB | RandomWOW (Wownero). |
| `rx/loki` | 2 MB | RandomXL (Loki). |

60
doc/CPU.md Normal file
View File

@@ -0,0 +1,60 @@
# CPU backend
All CPU related settings contains in one `cpu` object in config file, CPU backend allow specify multiple profiles and allow switch between them without restrictions by pool request or config change. Default auto-configuration create reasonable minimum of profiles which cover all supported algorithms.
### Example
Example below demonstrate all primary ideas of flexible profiles configuration:
* `"rx/wow"` Exact match to algorithm `rx/wow`, defined 4 threads without CPU affinity.
* `"cn"` Default failback profile for all `cn/*` algorithms, defined 2 threads with CPU affinity, another failback profiles is `cn-lite`, `cn-heavy` and `rx`.
* `"cn-lite"` Default failback profile for all `cn-lite/*` algorithms, defined 2 double threads with CPU affinity.
* `"custom-profile"` Custom user defined profile.
* `"*"` Failback profile for all unhandled by other profiles algorithms.
* `"cn/r"` Exact match, alias to profile `custom-profile`.
* `"cn/0"` Exact match, disabled algorithm.
```json
{
"cpu": {
"enabled": true,
"huge-pages": true,
"hw-aes": null,
"priority": null,
"asm": true,
"rx/wow": [
-1,
-1,
-1,
-1,
],
"cn": [
0,
2
],
"cn-lite": [
{
"intensity": 2,
"affinity": 0
},
{
"intensity": 2,
"affinity": 2
}
],
"custom-profile": [
0,
2,
],
"*": [
-1
],
"cn/r": "custom-profile",
"cn/0": false
}
}
```
### Intensity
This option was known as `low_power_mode`, possible values is range from 1 to 5, for convinient if value 1 used, possible omit this option and specify CPU thread config by only one number: CPU affinity, instead of object.

View File

@@ -1,7 +1,7 @@
#include <windows.h>
#include "../src/version.h"
IDI_ICON1 ICON DISCARDABLE "app.ico"
101 ICON "app.ico"
VS_VERSION_INFO VERSIONINFO
FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0

View File

@@ -1,65 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ALIGNED_MALLOC_H__
#define __ALIGNED_MALLOC_H__
#include <stdlib.h>
#ifndef __cplusplus
extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
#else
// Some systems (e.g. those with GNU libc) declare posix_memalign with an
// exception specifier. Via an "egregious workaround" in
// Sema::CheckEquivalentExceptionSpec, Clang accepts the following as a valid
// redeclaration of glibc's declaration.
extern "C" int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
#endif
static __inline__ void *__attribute__((__always_inline__, __malloc__)) _mm_malloc(size_t __size, size_t __align)
{
if (__align == 1) {
return malloc(__size);
}
if (!(__align & (__align - 1)) && __align < sizeof(void *))
__align = sizeof(void *);
void *__mallocedMemory;
if (posix_memalign(&__mallocedMemory, __align, __size)) {
return 0;
}
return __mallocedMemory;
}
static __inline__ void __attribute__((__always_inline__)) _mm_free(void *__p)
{
free(__p);
}
#endif /* __ALIGNED_MALLOC_H__ */

68
src/3rdparty/http-parser/AUTHORS vendored Normal file
View File

@@ -0,0 +1,68 @@
# Authors ordered by first contribution.
Ryan Dahl <ry@tinyclouds.org>
Jeremy Hinegardner <jeremy@hinegardner.org>
Sergey Shepelev <temotor@gmail.com>
Joe Damato <ice799@gmail.com>
tomika <tomika_nospam@freemail.hu>
Phoenix Sol <phoenix@burninglabs.com>
Cliff Frey <cliff@meraki.com>
Ewen Cheslack-Postava <ewencp@cs.stanford.edu>
Santiago Gala <sgala@apache.org>
Tim Becker <tim.becker@syngenio.de>
Jeff Terrace <jterrace@gmail.com>
Ben Noordhuis <info@bnoordhuis.nl>
Nathan Rajlich <nathan@tootallnate.net>
Mark Nottingham <mnot@mnot.net>
Aman Gupta <aman@tmm1.net>
Tim Becker <tim.becker@kuriositaet.de>
Sean Cunningham <sean.cunningham@mandiant.com>
Peter Griess <pg@std.in>
Salman Haq <salman.haq@asti-usa.com>
Cliff Frey <clifffrey@gmail.com>
Jon Kolb <jon@b0g.us>
Fouad Mardini <f.mardini@gmail.com>
Paul Querna <pquerna@apache.org>
Felix Geisendörfer <felix@debuggable.com>
koichik <koichik@improvement.jp>
Andre Caron <andre.l.caron@gmail.com>
Ivo Raisr <ivosh@ivosh.net>
James McLaughlin <jamie@lacewing-project.org>
David Gwynne <loki@animata.net>
Thomas LE ROUX <thomas@november-eleven.fr>
Randy Rizun <rrizun@ortivawireless.com>
Andre Louis Caron <andre.louis.caron@usherbrooke.ca>
Simon Zimmermann <simonz05@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com>
Martell Malone <martellmalone@gmail.com>
Bertrand Paquet <bpaquet@octo.com>
BogDan Vatra <bogdan@kde.org>
Peter Faiman <peter@thepicard.org>
Corey Richardson <corey@octayn.net>
Tóth Tamás <tomika_nospam@freemail.hu>
Cam Swords <cam.swords@gmail.com>
Chris Dickinson <christopher.s.dickinson@gmail.com>
Uli Köhler <ukoehler@btronik.de>
Charlie Somerville <charlie@charliesomerville.com>
Patrik Stutz <patrik.stutz@gmail.com>
Fedor Indutny <fedor.indutny@gmail.com>
runner <runner.mei@gmail.com>
Alexis Campailla <alexis@janeasystems.com>
David Wragg <david@wragg.org>
Vinnie Falco <vinnie.falco@gmail.com>
Alex Butum <alexbutum@linux.com>
Rex Feng <rexfeng@gmail.com>
Alex Kocharin <alex@kocharin.ru>
Mark Koopman <markmontymark@yahoo.com>
Helge Heß <me@helgehess.eu>
Alexis La Goutte <alexis.lagoutte@gmail.com>
George Miroshnykov <george.miroshnykov@gmail.com>
Maciej Małecki <me@mmalecki.com>
Marc O'Morain <github.com@marcomorain.com>
Jeff Pinner <jpinner@twitter.com>
Timothy J Fontaine <tjfontaine@gmail.com>
Akagi201 <akagi201@gmail.com>
Romain Giraud <giraud.romain@gmail.com>
Jay Satiro <raysatiro@yahoo.com>
Arne Steen <Arne.Steen@gmx.de>
Kjell Schubert <kjell.schubert@gmail.com>
Olivier Mengué <dolmen@cpan.org>

19
src/3rdparty/http-parser/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

246
src/3rdparty/http-parser/README.md vendored Normal file
View File

@@ -0,0 +1,246 @@
HTTP Parser
===========
[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser)
This is a parser for HTTP messages written in C. It parses both requests and
responses. The parser is designed to be used in performance HTTP
applications. It does not make any syscalls nor allocations, it does not
buffer data, it can be interrupted at anytime. Depending on your
architecture, it only requires about 40 bytes of data per message
stream (in a web server that is per connection).
Features:
* No dependencies
* Handles persistent streams (keep-alive).
* Decodes chunked encoding.
* Upgrade support
* Defends against buffer overflow attacks.
The parser extracts the following information from HTTP messages:
* Header fields and values
* Content-Length
* Request method
* Response status code
* Transfer-Encoding
* HTTP version
* Request URL
* Message body
Usage
-----
One `http_parser` object is used per TCP connection. Initialize the struct
using `http_parser_init()` and set the callbacks. That might look something
like this for a request parser:
```c
http_parser_settings settings;
settings.on_url = my_url_callback;
settings.on_header_field = my_header_field_callback;
/* ... */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST);
parser->data = my_socket;
```
When data is received on the socket execute the parser and check for errors.
```c
size_t len = 80*1024, nparsed;
char buf[len];
ssize_t recved;
recved = recv(fd, buf, len, 0);
if (recved < 0) {
/* Handle error. */
}
/* Start up / continue the parser.
* Note we pass recved==0 to signal that EOF has been received.
*/
nparsed = http_parser_execute(parser, &settings, buf, recved);
if (parser->upgrade) {
/* handle new protocol */
} else if (nparsed != recved) {
/* Handle error. Usually just close the connection. */
}
```
`http_parser` needs to know where the end of the stream is. For example, sometimes
servers send responses without Content-Length and expect the client to
consume input (for the body) until EOF. To tell `http_parser` about EOF, give
`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors
can still be encountered during an EOF, so one must still be prepared
to receive them.
Scalar valued message information such as `status_code`, `method`, and the
HTTP version are stored in the parser structure. This data is only
temporally stored in `http_parser` and gets reset on each new message. If
this information is needed later, copy it out of the structure during the
`headers_complete` callback.
The parser decodes the transfer-encoding for both requests and responses
transparently. That is, a chunked encoding is decoded before being sent to
the on_body callback.
The Special Problem of Upgrade
------------------------------
`http_parser` supports upgrading the connection to a different protocol. An
increasingly common example of this is the WebSocket protocol which sends
a request like
GET /demo HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
WebSocket-Protocol: sample
followed by non-HTTP data.
(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the
WebSocket protocol.)
To support this, the parser will treat this as a normal HTTP message without a
body, issuing both on_headers_complete and on_message_complete callbacks. However
http_parser_execute() will stop parsing at the end of the headers and return.
The user is expected to check if `parser->upgrade` has been set to 1 after
`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied
offset by the return value of `http_parser_execute()`.
Callbacks
---------
During the `http_parser_execute()` call, the callbacks set in
`http_parser_settings` will be executed. The parser maintains state and
never looks behind, so buffering the data is not necessary. If you need to
save certain data for later usage, you can do that from the callbacks.
There are two types of callbacks:
* notification `typedef int (*http_cb) (http_parser*);`
Callbacks: on_message_begin, on_headers_complete, on_message_complete.
* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);`
Callbacks: (requests only) on_url,
(common) on_header_field, on_header_value, on_body;
Callbacks must return 0 on success. Returning a non-zero value indicates
error to the parser, making it exit immediately.
For cases where it is necessary to pass local information to/from a callback,
the `http_parser` object's `data` field can be used.
An example of such a case is when using threads to handle a socket connection,
parse a request, and then give a response over that socket. By instantiation
of a thread-local struct containing relevant data (e.g. accepted socket,
allocated memory for callbacks to write into, etc), a parser's callbacks are
able to communicate data between the scope of the thread and the scope of the
callback in a threadsafe manner. This allows `http_parser` to be used in
multi-threaded contexts.
Example:
```c
typedef struct {
socket_t sock;
void* buffer;
int buf_len;
} custom_data_t;
int my_url_callback(http_parser* parser, const char *at, size_t length) {
/* access to thread local custom_data_t struct.
Use this access save parsed data for later use into thread local
buffer, or communicate over socket
*/
parser->data;
...
return 0;
}
...
void http_parser_thread(socket_t sock) {
int nparsed = 0;
/* allocate memory for user data */
custom_data_t *my_data = malloc(sizeof(custom_data_t));
/* some information for use by callbacks.
* achieves thread -> callback information flow */
my_data->sock = sock;
/* instantiate a thread-local parser */
http_parser *parser = malloc(sizeof(http_parser));
http_parser_init(parser, HTTP_REQUEST); /* initialise parser */
/* this custom data reference is accessible through the reference to the
parser supplied to callback functions */
parser->data = my_data;
http_parser_settings settings; /* set up callbacks */
settings.on_url = my_url_callback;
/* execute parser */
nparsed = http_parser_execute(parser, &settings, buf, recved);
...
/* parsed information copied from callback.
can now perform action on data copied into thread-local memory from callbacks.
achieves callback -> thread information flow */
my_data->buffer;
...
}
```
In case you parse HTTP message in chunks (i.e. `read()` request line
from socket, parse, read half headers, parse, etc) your data callbacks
may be called more than once. `http_parser` guarantees that data pointer is only
valid for the lifetime of callback. You can also `read()` into a heap allocated
buffer to avoid copying memory around if this fits your application.
Reading headers may be a tricky task if you read/parse headers partially.
Basically, you need to remember whether last header callback was field or value
and apply the following logic:
(on_header_field and on_header_value shortened to on_h_*)
------------------------ ------------ --------------------------------------------
| State (prev. callback) | Callback | Description/action |
------------------------ ------------ --------------------------------------------
| nothing (first call) | on_h_field | Allocate new buffer and copy callback data |
| | | into it |
------------------------ ------------ --------------------------------------------
| value | on_h_field | New header started. |
| | | Copy current name,value buffers to headers |
| | | list and allocate new buffer for new name |
------------------------ ------------ --------------------------------------------
| field | on_h_field | Previous name continues. Reallocate name |
| | | buffer and append callback data to it |
------------------------ ------------ --------------------------------------------
| field | on_h_value | Value for current header started. Allocate |
| | | new buffer and copy callback data to it |
------------------------ ------------ --------------------------------------------
| value | on_h_value | Value continues. Reallocate value buffer |
| | | and append callback data to it |
------------------------ ------------ --------------------------------------------
Parsing URLs
------------
A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`.
Users of this library may wish to use it to parse URLs constructed from
consecutive `on_url` callbacks.
See examples of reading in headers:
* [partial example](http://gist.github.com/155877) in C
* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C
* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript

2501
src/3rdparty/http-parser/http_parser.c vendored Normal file

File diff suppressed because it is too large Load Diff

439
src/3rdparty/http-parser/http_parser.h vendored Normal file
View File

@@ -0,0 +1,439 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef http_parser_h
#define http_parser_h
#ifdef __cplusplus
extern "C" {
#endif
/* Also update SONAME in the Makefile whenever you change these. */
#define HTTP_PARSER_VERSION_MAJOR 2
#define HTTP_PARSER_VERSION_MINOR 9
#define HTTP_PARSER_VERSION_PATCH 0
#include <stddef.h>
#if defined(_WIN32) && !defined(__MINGW32__) && \
(!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
#include <BaseTsd.h>
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
* faster
*/
#ifndef HTTP_PARSER_STRICT
# define HTTP_PARSER_STRICT 1
#endif
/* Maximium header size allowed. If the macro is not defined
* before including this header then the default is used. To
* change the maximum header size, define the macro in the build
* environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
* the effective limit on the size of the header, define the macro
* to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
*/
#ifndef HTTP_MAX_HEADER_SIZE
# define HTTP_MAX_HEADER_SIZE (80*1024)
#endif
typedef struct http_parser http_parser;
typedef struct http_parser_settings http_parser_settings;
/* Callbacks should return non-zero to indicate an error. The parser will
* then halt execution.
*
* The one exception is on_headers_complete. In a HTTP_RESPONSE parser
* returning '1' from on_headers_complete will tell the parser that it
* should not expect a body. This is used when receiving a response to a
* HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
* chunked' headers that indicate the presence of a body.
*
* Returning `2` from on_headers_complete will tell parser that it should not
* expect neither a body nor any futher responses on this connection. This is
* useful for handling responses to a CONNECT request which may not contain
* `Upgrade` or `Connection: upgrade` headers.
*
* http_data_cb does not return data chunks. It will be called arbitrarily
* many times for each string. E.G. you might get 10 callbacks for "on_url"
* each providing just a few characters more data.
*/
typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
typedef int (*http_cb) (http_parser*);
/* Status Codes */
#define HTTP_STATUS_MAP(XX) \
XX(100, CONTINUE, Continue) \
XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \
XX(102, PROCESSING, Processing) \
XX(200, OK, OK) \
XX(201, CREATED, Created) \
XX(202, ACCEPTED, Accepted) \
XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \
XX(204, NO_CONTENT, No Content) \
XX(205, RESET_CONTENT, Reset Content) \
XX(206, PARTIAL_CONTENT, Partial Content) \
XX(207, MULTI_STATUS, Multi-Status) \
XX(208, ALREADY_REPORTED, Already Reported) \
XX(226, IM_USED, IM Used) \
XX(300, MULTIPLE_CHOICES, Multiple Choices) \
XX(301, MOVED_PERMANENTLY, Moved Permanently) \
XX(302, FOUND, Found) \
XX(303, SEE_OTHER, See Other) \
XX(304, NOT_MODIFIED, Not Modified) \
XX(305, USE_PROXY, Use Proxy) \
XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \
XX(308, PERMANENT_REDIRECT, Permanent Redirect) \
XX(400, BAD_REQUEST, Bad Request) \
XX(401, UNAUTHORIZED, Unauthorized) \
XX(402, PAYMENT_REQUIRED, Payment Required) \
XX(403, FORBIDDEN, Forbidden) \
XX(404, NOT_FOUND, Not Found) \
XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \
XX(406, NOT_ACCEPTABLE, Not Acceptable) \
XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \
XX(408, REQUEST_TIMEOUT, Request Timeout) \
XX(409, CONFLICT, Conflict) \
XX(410, GONE, Gone) \
XX(411, LENGTH_REQUIRED, Length Required) \
XX(412, PRECONDITION_FAILED, Precondition Failed) \
XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \
XX(414, URI_TOO_LONG, URI Too Long) \
XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \
XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \
XX(417, EXPECTATION_FAILED, Expectation Failed) \
XX(421, MISDIRECTED_REQUEST, Misdirected Request) \
XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \
XX(423, LOCKED, Locked) \
XX(424, FAILED_DEPENDENCY, Failed Dependency) \
XX(426, UPGRADE_REQUIRED, Upgrade Required) \
XX(428, PRECONDITION_REQUIRED, Precondition Required) \
XX(429, TOO_MANY_REQUESTS, Too Many Requests) \
XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \
XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \
XX(501, NOT_IMPLEMENTED, Not Implemented) \
XX(502, BAD_GATEWAY, Bad Gateway) \
XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \
XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \
XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \
XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \
XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \
XX(508, LOOP_DETECTED, Loop Detected) \
XX(510, NOT_EXTENDED, Not Extended) \
XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
enum http_status
{
#define XX(num, name, string) HTTP_STATUS_##name = num,
HTTP_STATUS_MAP(XX)
#undef XX
};
/* Request Methods */
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
/* pathological */ \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
/* WebDAV */ \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
/* subversion */ \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
/* upnp */ \
XX(24, MSEARCH, M-SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
/* RFC-5789 */ \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
XX(33, SOURCE, SOURCE) \
enum http_method
{
#define XX(num, name, string) HTTP_##name = num,
HTTP_METHOD_MAP(XX)
#undef XX
};
enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
/* Flag values for http_parser.flags field */
enum flags
{ F_CHUNKED = 1 << 0
, F_CONNECTION_KEEP_ALIVE = 1 << 1
, F_CONNECTION_CLOSE = 1 << 2
, F_CONNECTION_UPGRADE = 1 << 3
, F_TRAILING = 1 << 4
, F_UPGRADE = 1 << 5
, F_SKIPBODY = 1 << 6
, F_CONTENTLENGTH = 1 << 7
};
/* Map for errno-related constants
*
* The provided argument should be a macro that takes 2 arguments.
*/
#define HTTP_ERRNO_MAP(XX) \
/* No error */ \
XX(OK, "success") \
\
/* Callback-related errors */ \
XX(CB_message_begin, "the on_message_begin callback failed") \
XX(CB_url, "the on_url callback failed") \
XX(CB_header_field, "the on_header_field callback failed") \
XX(CB_header_value, "the on_header_value callback failed") \
XX(CB_headers_complete, "the on_headers_complete callback failed") \
XX(CB_body, "the on_body callback failed") \
XX(CB_message_complete, "the on_message_complete callback failed") \
XX(CB_status, "the on_status callback failed") \
XX(CB_chunk_header, "the on_chunk_header callback failed") \
XX(CB_chunk_complete, "the on_chunk_complete callback failed") \
\
/* Parsing-related errors */ \
XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \
XX(HEADER_OVERFLOW, \
"too many header bytes seen; overflow detected") \
XX(CLOSED_CONNECTION, \
"data received after completed connection: close message") \
XX(INVALID_VERSION, "invalid HTTP version") \
XX(INVALID_STATUS, "invalid HTTP status code") \
XX(INVALID_METHOD, "invalid HTTP method") \
XX(INVALID_URL, "invalid URL") \
XX(INVALID_HOST, "invalid host") \
XX(INVALID_PORT, "invalid port") \
XX(INVALID_PATH, "invalid path") \
XX(INVALID_QUERY_STRING, "invalid query string") \
XX(INVALID_FRAGMENT, "invalid fragment") \
XX(LF_EXPECTED, "LF character expected") \
XX(INVALID_HEADER_TOKEN, "invalid character in header") \
XX(INVALID_CONTENT_LENGTH, \
"invalid character in content-length header") \
XX(UNEXPECTED_CONTENT_LENGTH, \
"unexpected content-length header") \
XX(INVALID_CHUNK_SIZE, \
"invalid character in chunk size header") \
XX(INVALID_CONSTANT, "invalid constant string") \
XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
XX(STRICT, "strict mode assertion failed") \
XX(PAUSED, "parser is paused") \
XX(UNKNOWN, "an unknown error occurred")
/* Define HPE_* values for each errno value above */
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno {
HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN
/* Get an http_errno value from an http_parser */
#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno)
struct http_parser {
/** PRIVATE **/
unsigned int type : 2; /* enum http_parser_type */
unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */
unsigned int state : 7; /* enum state from http_parser.c */
unsigned int header_state : 7; /* enum header_state from http_parser.c */
unsigned int index : 7; /* index into current matcher */
unsigned int lenient_http_headers : 1;
uint32_t nread; /* # bytes read in various scenarios */
uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
/** READ-ONLY **/
unsigned short http_major;
unsigned short http_minor;
unsigned int status_code : 16; /* responses only */
unsigned int method : 8; /* requests only */
unsigned int http_errno : 7;
/* 1 = Upgrade header was present and the parser has exited because of that.
* 0 = No upgrade header present.
* Should be checked when http_parser_execute() returns in addition to
* error checking.
*/
unsigned int upgrade : 1;
/** PUBLIC **/
void *data; /* A pointer to get hook to the "connection" or "socket" object */
};
struct http_parser_settings {
http_cb on_message_begin;
http_data_cb on_url;
http_data_cb on_status;
http_data_cb on_header_field;
http_data_cb on_header_value;
http_cb on_headers_complete;
http_data_cb on_body;
http_cb on_message_complete;
/* When on_chunk_header is called, the current chunk length is stored
* in parser->content_length.
*/
http_cb on_chunk_header;
http_cb on_chunk_complete;
};
enum http_parser_url_fields
{ UF_SCHEMA = 0
, UF_HOST = 1
, UF_PORT = 2
, UF_PATH = 3
, UF_QUERY = 4
, UF_FRAGMENT = 5
, UF_USERINFO = 6
, UF_MAX = 7
};
/* Result structure for http_parser_parse_url().
*
* Callers should index into field_data[] with UF_* values iff field_set
* has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
* because we probably have padding left over), we convert any port to
* a uint16_t.
*/
struct http_parser_url {
uint16_t field_set; /* Bitmask of (1 << UF_*) values */
uint16_t port; /* Converted UF_PORT string */
struct {
uint16_t off; /* Offset into buffer in which field starts */
uint16_t len; /* Length of run in buffer */
} field_data[UF_MAX];
};
/* Returns the library version. Bits 16-23 contain the major version number,
* bits 8-15 the minor version number and bits 0-7 the patch level.
* Usage example:
*
* unsigned long version = http_parser_version();
* unsigned major = (version >> 16) & 255;
* unsigned minor = (version >> 8) & 255;
* unsigned patch = version & 255;
* printf("http_parser v%u.%u.%u\n", major, minor, patch);
*/
unsigned long http_parser_version(void);
void http_parser_init(http_parser *parser, enum http_parser_type type);
/* Initialize http_parser_settings members to 0
*/
void http_parser_settings_init(http_parser_settings *settings);
/* Executes the parser. Returns number of parsed bytes. Sets
* `parser->http_errno` on error. */
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings,
const char *data,
size_t len);
/* If http_should_keep_alive() in the on_headers_complete or
* on_message_complete callback returns 0, then this should be
* the last message on the connection.
* If you are the server, respond with the "Connection: close" header.
* If you are the client, close the connection.
*/
int http_should_keep_alive(const http_parser *parser);
/* Returns a string version of the HTTP method. */
const char *http_method_str(enum http_method m);
/* Returns a string version of the HTTP status code. */
const char *http_status_str(enum http_status s);
/* Return a string name of the given error */
const char *http_errno_name(enum http_errno err);
/* Return a string description of the given error */
const char *http_errno_description(enum http_errno err);
/* Initialize all http_parser_url members to 0 */
void http_parser_url_init(struct http_parser_url *u);
/* Parse a URL; return nonzero on failure */
int http_parser_parse_url(const char *buf, size_t buflen,
int is_connect,
struct http_parser_url *u);
/* Pause or un-pause the parser; a nonzero value pauses */
void http_parser_pause(http_parser *parser, int paused);
/* Checks if this is the final chunk of the body. */
int http_body_is_final(const http_parser *parser);
/* Change the maximum header size provided at compile time. */
void http_parser_set_max_header_size(uint32_t size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -6,7 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
@@ -30,29 +30,21 @@
#include "api/Api.h"
#include "App.h"
#include "backend/cpu/Cpu.h"
#include "base/io/Console.h"
#include "base/io/log/Log.h"
#include "base/kernel/Signals.h"
#include "common/Console.h"
#include "common/cpu/Cpu.h"
#include "common/log/Log.h"
#include "common/Platform.h"
#include "core/Config.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "crypto/CryptoNight.h"
#include "Mem.h"
#include "core/Miner.h"
#include "crypto/common/VirtualMemory.h"
#include "net/Network.h"
#include "Summary.h"
#include "version.h"
#include "workers/Workers.h"
#ifndef XMRIG_NO_HTTPD
# include "common/api/Httpd.h"
#endif
xmrig::App::App(Process *process) :
m_console(nullptr),
m_httpd(nullptr),
m_signals(nullptr)
{
m_controller = new Controller(process);
@@ -68,15 +60,9 @@ xmrig::App::App(Process *process) :
xmrig::App::~App()
{
uv_tty_reset_mode();
delete m_signals;
delete m_console;
delete m_controller;
# ifndef XMRIG_NO_HTTPD
delete m_httpd;
# endif
}
@@ -90,7 +76,7 @@ int xmrig::App::exec()
background();
Mem::init(m_controller->config()->isHugePages());
VirtualMemory::init(m_controller->config()->cpu().isHugePages());
Summary::print(m_controller);
@@ -100,24 +86,7 @@ int xmrig::App::exec()
return 0;
}
# ifndef XMRIG_NO_API
Api::start(m_controller);
# endif
# ifndef XMRIG_NO_HTTPD
m_httpd = new Httpd(
m_controller->config()->apiPort(),
m_controller->config()->apiToken(),
m_controller->config()->isApiIPv6(),
m_controller->config()->isApiRestricted()
);
m_httpd->start();
# endif
Workers::start(m_controller);
m_controller->network()->connect();
m_controller->start();
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());
@@ -131,23 +100,17 @@ void xmrig::App::onConsoleCommand(char command)
switch (command) {
case 'h':
case 'H':
Workers::printHashrate(true);
m_controller->miner()->printHashrate(true);
break;
case 'p':
case 'P':
if (Workers::isEnabled()) {
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume");
Workers::setEnabled(false);
}
m_controller->miner()->setEnabled(false);
break;
case 'r':
case 'R':
if (!Workers::isEnabled()) {
LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;32mresumed" : "resumed");
Workers::setEnabled(true);
}
m_controller->miner()->setEnabled(true);
break;
case 3:
@@ -187,8 +150,9 @@ void xmrig::App::onSignal(int signum)
void xmrig::App::close()
{
m_controller->network()->stop();
Workers::stop();
m_signals->stop();
m_console->stop();
m_controller->stop();
uv_stop(uv_default_loop());
Log::destroy();
}

View File

@@ -27,17 +27,14 @@
#define XMRIG_APP_H
#include "base/kernel/interfaces/IConsoleListener.h"
#include "base/kernel/interfaces/ISignalListener.h"
#include "common/interfaces/IConsoleListener.h"
class Console;
class Httpd;
namespace xmrig {
class Console;
class Controller;
class Network;
class Process;
@@ -62,7 +59,6 @@ private:
Console *m_console;
Controller *m_controller;
Httpd *m_httpd;
Signals *m_signals;
};

View File

@@ -30,8 +30,8 @@
#include "App.h"
#include "common/log/Log.h"
#include "core/Config.h"
#include "base/io/log/Log.h"
#include "core/config/Config.h"
#include "core/Controller.h"

View File

@@ -29,7 +29,7 @@
#include "App.h"
#include "core/Controller.h"
#include "core/Config.h"
#include "core/config/Config.h"
void xmrig::App::background()

View File

@@ -1,114 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <sys/mman.h>
#include "common/log/Log.h"
#include "common/utils/mm_malloc.h"
#include "common/xmrig.h"
#include "crypto/CryptoNight.h"
#include "Mem.h"
void Mem::init(bool enabled)
{
m_enabled = enabled;
}
void Mem::allocate(MemInfo &info, bool enabled)
{
info.hugePages = 0;
if (!enabled) {
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
return;
}
# if defined(__APPLE__)
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0));
# elif defined(__FreeBSD__)
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0));
# else
info.memory = static_cast<uint8_t*>(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0));
# endif
if (info.memory == MAP_FAILED) {
return allocate(info, false);;
}
info.hugePages = info.pages;
if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) {
LOG_ERR("madvise failed");
}
if (mlock(info.memory, info.size) == 0) {
m_flags |= Lock;
}
}
void Mem::release(MemInfo &info)
{
if (info.hugePages) {
if (m_flags & Lock) {
munlock(info.memory, info.size);
}
munmap(info.memory, info.size);
}
else {
_mm_free(info.memory);
}
}
void *Mem::allocateExecutableMemory(size_t size)
{
# if defined(__APPLE__)
return mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
# else
return mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
# endif
}
void Mem::protectExecutableMemory(void *p, size_t size)
{
mprotect(p, size, PROT_READ | PROT_EXEC);
}
void Mem::flushInstructionCache(void *p, size_t size)
{
# ifndef __FreeBSD__
__builtin___clear_cache(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p) + size);
# endif
}

View File

@@ -28,129 +28,90 @@
#include <uv.h>
#include "base/net/Pool.h"
#include "common/cpu/Cpu.h"
#include "common/log/Log.h"
#include "core/Config.h"
#include "backend/cpu/Cpu.h"
#include "base/io/log/Log.h"
#include "base/net/stratum/Pool.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "crypto/Asm.h"
#include "Mem.h"
#include "crypto/common/Assembly.h"
#include "crypto/common/VirtualMemory.h"
#include "Summary.h"
#include "version.h"
#ifndef XMRIG_NO_ASM
#ifdef XMRIG_FEATURE_ASM
static const char *coloredAsmNames[] = {
"\x1B[1;31mnone\x1B[0m",
RED_BOLD("none"),
"auto",
"\x1B[1;32mintel\x1B[0m",
"\x1B[1;32mryzen\x1B[0m",
"\x1B[1;32mbulldozer\x1B[0m"
GREEN_BOLD("intel"),
GREEN_BOLD("ryzen"),
GREEN_BOLD("bulldozer")
};
inline static const char *asmName(xmrig::Assembly assembly, bool colors)
inline static const char *asmName(xmrig::Assembly::Id assembly)
{
return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly);
return coloredAsmNames[assembly];
}
#endif
static void print_memory(xmrig::Config *config) {
static void print_memory(xmrig::Config *) {
# ifdef _WIN32
if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
"HUGE PAGES", Mem::isHugepagesAvailable() ? "\x1B[1;32mavailable" : "\x1B[01;31munavailable");
}
else {
Log::i()->text(" * %-13s%s", "HUGE PAGES", Mem::isHugepagesAvailable() ? "available" : "unavailable");
}
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
"HUGE PAGES", xmrig::VirtualMemory::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable"));
# endif
}
static void print_cpu(xmrig::Config *config)
static void print_cpu(xmrig::Config *)
{
using namespace xmrig;
if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES %sAVX2",
"CPU",
Cpu::info()->brand(),
Cpu::info()->sockets(),
Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-",
Cpu::info()->hasAVX2() ? "\x1B[1;32m" : "\x1B[1;31m-");
# ifndef XMRIG_NO_LIBCPUID
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif
}
else {
Log::i()->text(" * %-13s%s (%d) %sx64 %sAES %sAVX2",
"CPU",
Cpu::info()->brand(),
Cpu::info()->sockets(),
Cpu::info()->isX64() ? "" : "-",
Cpu::info()->hasAES() ? "" : "-",
Cpu::info()->hasAVX2() ? "" : "-");
# ifndef XMRIG_NO_LIBCPUID
Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif
}
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES %sAVX2",
"CPU",
Cpu::info()->brand(),
Cpu::info()->sockets(),
Cpu::info()->isX64() ? GREEN_BOLD_S : RED_BOLD_S "-",
Cpu::info()->hasAES() ? GREEN_BOLD_S : RED_BOLD_S "-",
Cpu::info()->hasAVX2() ? GREEN_BOLD_S : RED_BOLD_S "-"
);
# ifdef XMRIG_FEATURE_LIBCPUID
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0);
# endif
}
static void print_threads(xmrig::Config *config)
{
if (config->threadsMode() != xmrig::Config::Advanced) {
char buf[32] = { 0 };
if (config->affinity() != -1L) {
snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity());
}
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s%d%%"),
"DONATE",
config->pools().donateLevel() == 0 ? RED_BOLD_S : "",
config->pools().donateLevel()
);
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s")
: " * %-13s%d, %s, av=%d, %sdonate=%d%%%s",
"THREADS",
config->threadsCount(),
config->algorithm().name(),
config->algoVariant(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel(),
buf);
}
else {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%")
: " * %-13s%d, %s, %sdonate=%d%%",
"THREADS",
config->threadsCount(),
config->algorithm().name(),
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel());
}
# ifndef XMRIG_NO_ASM
if (config->assembly() == xmrig::ASM_AUTO) {
# ifdef XMRIG_FEATURE_ASM
if (config->cpu().assembly() == xmrig::Assembly::AUTO) {
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
: " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s"), "ASSEMBLY", asmName(assembly));
}
else {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s"), "ASSEMBLY", asmName(config->cpu().assembly()));
}
# endif
}
static void print_commands(xmrig::Config *config)
static void print_commands(xmrig::Config *)
{
if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
if (xmrig::Log::colors) {
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ")
MAGENTA_BOLD("p") WHITE_BOLD("ause, ")
MAGENTA_BOLD("r") WHITE_BOLD("esume"));
}
else {
Log::i()->text(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume");
xmrig::Log::print(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume");
}
}
@@ -161,8 +122,7 @@ void Summary::print(xmrig::Controller *controller)
print_memory(controller->config());
print_cpu(controller->config());
print_threads(controller->config());
controller->config()->printPools();
controller->config()->printAPI();
controller->config()->pools().print();
print_commands(controller->config());
}

View File

@@ -22,52 +22,185 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <uv.h>
#ifndef _WIN32
# include <unistd.h>
#endif
#include "3rdparty/http-parser/http_parser.h"
#include "api/Api.h"
#include "api/ApiRouter.h"
#include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h"
#include "api/interfaces/IApiListener.h"
#include "api/requests/HttpApiRequest.h"
#include "base/kernel/Base.h"
#include "base/tools/Buffer.h"
#include "base/tools/Chrono.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "crypto/common/Algorithm.h"
#include "crypto/common/keccak.h"
#include "version.h"
ApiRouter *Api::m_router = nullptr;
#ifdef XMRIG_FEATURE_HTTP
# include "api/Httpd.h"
#endif
bool Api::start(xmrig::Controller *controller)
xmrig::Api::Api(Base *base) :
m_base(base),
m_id(),
m_workerId(),
m_httpd(nullptr),
m_timestamp(Chrono::steadyMSecs())
{
m_router = new ApiRouter(controller);
base->addListener(this);
return true;
genId(base->config()->apiId());
}
void Api::release()
xmrig::Api::~Api()
{
delete m_router;
# ifdef XMRIG_FEATURE_HTTP
delete m_httpd;
# endif
}
void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
void xmrig::Api::request(const HttpData &req)
{
if (!m_router) {
reply.status = 500;
HttpApiRequest request(req, m_base->config()->http().isRestricted());
exec(request);
}
void xmrig::Api::start()
{
genWorkerId(m_base->config()->apiWorkerId());
# ifdef XMRIG_FEATURE_HTTP
m_httpd = new Httpd(m_base);
m_httpd->start();
# endif
}
void xmrig::Api::stop()
{
# ifdef XMRIG_FEATURE_HTTP
m_httpd->stop();
# endif
}
void xmrig::Api::onConfigChanged(Config *config, Config *previousConfig)
{
if (config->apiId() != previousConfig->apiId()) {
genId(config->apiId());
}
if (config->apiWorkerId() != previousConfig->apiWorkerId()) {
genWorkerId(config->apiWorkerId());
}
}
void xmrig::Api::exec(IApiRequest &request)
{
using namespace rapidjson;
if (request.type() == IApiRequest::REQ_SUMMARY) {
auto &allocator = request.doc().GetAllocator();
request.accept();
request.reply().AddMember("id", StringRef(m_id), allocator);
request.reply().AddMember("worker_id", StringRef(m_workerId), allocator);
request.reply().AddMember("uptime", (Chrono::steadyMSecs() - m_timestamp) / 1000, allocator);
Value features(kArrayType);
# ifdef XMRIG_FEATURE_API
features.PushBack("api", allocator);
# endif
# ifdef XMRIG_FEATURE_ASM
features.PushBack("asm", allocator);
# endif
# ifdef XMRIG_FEATURE_HTTP
features.PushBack("http", allocator);
# endif
# ifdef XMRIG_FEATURE_LIBCPUID
features.PushBack("cpuid", allocator);
# endif
# ifdef XMRIG_FEATURE_TLS
features.PushBack("tls", allocator);
# endif
request.reply().AddMember("features", features, allocator);
}
for (IApiListener *listener : m_listeners) {
listener->onRequest(request);
if (request.isDone()) {
return;
}
}
request.done(request.isNew() ? HTTP_STATUS_NOT_FOUND : HTTP_STATUS_OK);
}
void xmrig::Api::genId(const String &id)
{
memset(m_id, 0, sizeof(m_id));
if (id.size() > 0) {
strncpy(m_id, id.data(), sizeof(m_id) - 1);
return;
}
if (req.method() == xmrig::HttpRequest::Get) {
return m_router->get(req, reply);
}
uv_interface_address_t *interfaces;
int count = 0;
m_router->exec(req, reply);
}
void Api::tick(const xmrig::NetworkState &network)
{
if (!m_router) {
if (uv_interface_addresses(&interfaces, &count) < 0) {
return;
}
m_router->tick(network);
for (int i = 0; i < count; i++) {
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr);
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
const uint16_t port = static_cast<uint16_t>(m_base->config()->http().port());
uint8_t *input = new uint8_t[inSize]();
memcpy(input, &port, sizeof(uint16_t));
memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize);
memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
xmrig::keccak(input, inSize, hash);
xmrig::Buffer::toHex(hash, 8, m_id);
delete [] input;
break;
}
}
uv_free_interface_addresses(interfaces, count);
}
void xmrig::Api::genWorkerId(const String &id)
{
memset(m_workerId, 0, sizeof(m_workerId));
if (id.size() > 0) {
strncpy(m_workerId, id.data(), sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
}
}

View File

@@ -26,32 +26,56 @@
#define XMRIG_API_H
#include <uv.h>
#include <vector>
#include <stdint.h>
class ApiRouter;
class Hashrate;
#include "base/kernel/interfaces/IBaseListener.h"
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
class NetworkState;
}
class Api
class Base;
class Httpd;
class HttpData;
class IApiListener;
class IApiRequest;
class String;
class Api : public IBaseListener
{
public:
static bool start(xmrig::Controller *controller);
static void release();
Api(Base *base);
~Api() override;
static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
static void tick(const xmrig::NetworkState &results);
inline const char *id() const { return m_id; }
inline const char *workerId() const { return m_workerId; }
inline void addListener(IApiListener *listener) { m_listeners.push_back(listener); }
void request(const HttpData &req);
void start();
void stop();
protected:
void onConfigChanged(Config *config, Config *previousConfig) override;
private:
static ApiRouter *m_router;
void exec(IApiRequest &request);
void genId(const String &id);
void genWorkerId(const String &id);
Base *m_base;
char m_id[32];
char m_workerId[128];
Httpd *m_httpd;
std::vector<IApiListener *> m_listeners;
uint64_t m_timestamp;
};
} // namespace xmrig
#endif /* XMRIG_API_H */

View File

@@ -1,339 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
#include <string.h>
#include <uv.h>
#if _WIN32
# include "winsock2.h"
#else
# include "unistd.h"
#endif
#include "api/ApiRouter.h"
#include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h"
#include "common/cpu/Cpu.h"
#include "common/crypto/keccak.h"
#include "common/net/Job.h"
#include "common/Platform.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "interfaces/IThread.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "version.h"
#include "workers/Hashrate.h"
#include "workers/Workers.h"
static inline double normalize(double d)
{
if (!isnormal(d)) {
return 0.0;
}
return floor(d * 100.0) / 100.0;
}
ApiRouter::ApiRouter(xmrig::Controller *controller) :
m_controller(controller)
{
memset(m_workerId, 0, sizeof(m_workerId));
setWorkerId(controller->config()->apiWorkerId());
genId(controller->config()->apiId());
}
ApiRouter::~ApiRouter()
{
}
void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const
{
rapidjson::Document doc;
if (req.match("/1/config")) {
if (req.isRestricted()) {
reply.status = 403;
return;
}
m_controller->config()->getJSON(doc);
return finalize(reply, doc);
}
if (req.match("/1/threads")) {
getThreads(doc);
return finalize(reply, doc);
}
doc.SetObject();
getIdentify(doc);
getMiner(doc);
getHashrate(doc);
getResults(doc);
getConnection(doc);
return finalize(reply, doc);
}
void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply)
{
if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) {
m_controller->config()->reload(req.body());
return;
}
reply.status = 404;
}
void ApiRouter::tick(const xmrig::NetworkState &network)
{
m_network = network;
}
void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig)
{
updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId());
}
void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const
{
rapidjson::StringBuffer buffer(nullptr, 4096);
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
writer.SetMaxDecimalPlaces(10);
doc.Accept(writer);
reply.status = 200;
reply.buf = strdup(buffer.GetString());
reply.size = buffer.GetSize();
}
void ApiRouter::genId(const char *id)
{
memset(m_id, 0, sizeof(m_id));
if (id && strlen(id) > 0) {
strncpy(m_id, id, sizeof(m_id) - 1);
return;
}
uv_interface_address_t *interfaces;
int count = 0;
if (uv_interface_addresses(&interfaces, &count) < 0) {
return;
}
for (int i = 0; i < count; i++) {
if (!interfaces[i].is_internal && interfaces[i].address.address4.sin_family == AF_INET) {
uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr);
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
const uint16_t port = static_cast<uint16_t>(m_controller->config()->apiPort());
uint8_t *input = new uint8_t[inSize]();
memcpy(input, &port, sizeof(uint16_t));
memcpy(input + sizeof(uint16_t), interfaces[i].phys_addr, addrSize);
memcpy(input + sizeof(uint16_t) + addrSize, APP_KIND, strlen(APP_KIND));
xmrig::keccak(input, inSize, hash);
xmrig::Job::toHex(hash, 8, m_id);
delete [] input;
break;
}
}
uv_free_interface_addresses(interfaces, count);
}
void ApiRouter::getConnection(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
rapidjson::Value connection(rapidjson::kObjectType);
connection.AddMember("pool", rapidjson::StringRef(m_network.pool), allocator);
connection.AddMember("uptime", m_network.connectionTime(), allocator);
connection.AddMember("ping", m_network.latency(), allocator);
connection.AddMember("failures", m_network.failures, allocator);
connection.AddMember("error_log", rapidjson::Value(rapidjson::kArrayType), allocator);
doc.AddMember("connection", connection, allocator);
}
void ApiRouter::getHashrate(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
rapidjson::Value hashrate(rapidjson::kObjectType);
rapidjson::Value total(rapidjson::kArrayType);
rapidjson::Value threads(rapidjson::kArrayType);
const Hashrate *hr = Workers::hashrate();
total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator);
total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator);
total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator);
for (size_t i = 0; i < Workers::threads(); i++) {
rapidjson::Value thread(rapidjson::kArrayType);
thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
threads.PushBack(thread, allocator);
}
hashrate.AddMember("total", total, allocator);
hashrate.AddMember("highest", normalize(hr->highest()), allocator);
hashrate.AddMember("threads", threads, allocator);
doc.AddMember("hashrate", hashrate, allocator);
}
void ApiRouter::getIdentify(rapidjson::Document &doc) const
{
doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator());
doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator());
}
void ApiRouter::getMiner(rapidjson::Document &doc) const
{
using namespace xmrig;
auto &allocator = doc.GetAllocator();
rapidjson::Value cpu(rapidjson::kObjectType);
cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator);
cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
doc.AddMember("cpu", cpu, allocator);
doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator);
doc.AddMember("hugepages", Workers::hugePages() > 0, allocator);
doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator);
}
void ApiRouter::getResults(rapidjson::Document &doc) const
{
auto &allocator = doc.GetAllocator();
rapidjson::Value results(rapidjson::kObjectType);
results.AddMember("diff_current", m_network.diff, allocator);
results.AddMember("shares_good", m_network.accepted, allocator);
results.AddMember("shares_total", m_network.accepted + m_network.rejected, allocator);
results.AddMember("avg_time", m_network.avgTime(), allocator);
results.AddMember("hashes_total", m_network.total, allocator);
rapidjson::Value best(rapidjson::kArrayType);
for (size_t i = 0; i < m_network.topDiff.size(); ++i) {
best.PushBack(m_network.topDiff[i], allocator);
}
results.AddMember("best", best, allocator);
results.AddMember("error_log", rapidjson::Value(rapidjson::kArrayType), allocator);
doc.AddMember("results", results, allocator);
}
void ApiRouter::getThreads(rapidjson::Document &doc) const
{
doc.SetObject();
auto &allocator = doc.GetAllocator();
const Hashrate *hr = Workers::hashrate();
Workers::threadsSummary(doc);
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads();
rapidjson::Value list(rapidjson::kArrayType);
size_t i = 0;
for (const xmrig::IThread *thread : threads) {
rapidjson::Value value = thread->toAPI(doc);
rapidjson::Value hashrate(rapidjson::kArrayType);
hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
i++;
value.AddMember("hashrate", hashrate, allocator);
list.PushBack(value, allocator);
}
doc.AddMember("threads", list, allocator);
}
void ApiRouter::setWorkerId(const char *id)
{
memset(m_workerId, 0, sizeof(m_workerId));
if (id && strlen(id) > 0) {
strncpy(m_workerId, id, sizeof(m_workerId) - 1);
}
else {
gethostname(m_workerId, sizeof(m_workerId) - 1);
}
}
void ApiRouter::updateWorkerId(const char *id, const char *previousId)
{
if (id == previousId) {
return;
}
if (id != nullptr && previousId != nullptr && strcmp(id, previousId) == 0) {
return;
}
setWorkerId(id);
}

View File

@@ -1,76 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_APIROUTER_H
#define XMRIG_APIROUTER_H
#include "api/NetworkState.h"
#include "common/interfaces/IControllerListener.h"
#include "rapidjson/fwd.h"
class Hashrate;
namespace xmrig {
class Controller;
class HttpReply;
class HttpRequest;
}
class ApiRouter : public xmrig::IControllerListener
{
public:
ApiRouter(xmrig::Controller *controller);
~ApiRouter() override;
void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const;
void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply);
void tick(const xmrig::NetworkState &results);
protected:
void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override;
private:
void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const;
void genId(const char *id);
void getConnection(rapidjson::Document &doc) const;
void getHashrate(rapidjson::Document &doc) const;
void getIdentify(rapidjson::Document &doc) const;
void getMiner(rapidjson::Document &doc) const;
void getResults(rapidjson::Document &doc) const;
void getThreads(rapidjson::Document &doc) const;
void setWorkerId(const char *id);
void updateWorkerId(const char *id, const char *previousId);
char m_id[32];
char m_workerId[128];
xmrig::NetworkState m_network;
xmrig::Controller *m_controller;
};
#endif /* XMRIG_APIROUTER_H */

193
src/api/Httpd.cpp Normal file
View File

@@ -0,0 +1,193 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "3rdparty/http-parser/http_parser.h"
#include "api/Api.h"
#include "api/Httpd.h"
#include "base/io/log/Log.h"
#include "base/net/http/HttpApiResponse.h"
#include "base/net/http/HttpData.h"
#include "base/net/http/HttpServer.h"
#include "base/net/tools/TcpServer.h"
#include "core/config/Config.h"
#include "core/Controller.h"
namespace xmrig {
static const char *kAuthorization = "authorization";
static const char *kContentType = "content-type";
#ifdef _WIN32
static const char *favicon = nullptr;
static size_t faviconSize = 0;
#endif
} // namespace xmrig
xmrig::Httpd::Httpd(Base *base) :
m_base(base),
m_http(nullptr),
m_server(nullptr),
m_port(0)
{
base->addListener(this);
}
xmrig::Httpd::~Httpd()
{
}
bool xmrig::Httpd::start()
{
const Http &config = m_base->config()->http();
if (!config.isEnabled()) {
return true;
}
m_http = new HttpServer(this);
m_server = new TcpServer(config.host(), config.port(), m_http);
const int rc = m_server->bind();
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") BLUE_BOLD("%s:%d") " " RED_BOLD("%s"),
"HTTP API",
config.host().data(),
rc < 0 ? config.port() : rc,
rc < 0 ? uv_strerror(rc) : ""
);
if (rc < 0) {
stop();
return false;
}
m_port = static_cast<uint16_t>(rc);
# ifdef _WIN32
HRSRC src = FindResource(nullptr, MAKEINTRESOURCE(1), RT_ICON);
if (src != nullptr) {
HGLOBAL res = LoadResource(nullptr, src);
if (res != nullptr) {
favicon = static_cast<const char *>(LockResource(res));
faviconSize = SizeofResource(nullptr, src);
}
}
# endif
return true;
}
void xmrig::Httpd::stop()
{
delete m_server;
delete m_http;
m_server = nullptr;
m_http = nullptr;
m_port = 0;
}
void xmrig::Httpd::onConfigChanged(Config *config, Config *previousConfig)
{
if (config->http() == previousConfig->http()) {
return;
}
stop();
start();
}
void xmrig::Httpd::onHttpData(const HttpData &data)
{
if (data.method == HTTP_OPTIONS) {
return HttpApiResponse(data.id()).end();
}
if (data.method == HTTP_GET && data.url == "/favicon.ico") {
# ifdef _WIN32
if (favicon != nullptr) {
HttpResponse response(data.id());
response.setHeader("Content-Type", "image/x-icon");
return response.end(favicon, faviconSize);
}
# endif
return HttpResponse(data.id(), 404).end();
}
if (data.method > 4) {
return HttpApiResponse(data.id(), HTTP_STATUS_METHOD_NOT_ALLOWED).end();
}
const int status = auth(data);
if (status != HTTP_STATUS_OK) {
return HttpApiResponse(data.id(), status).end();
}
if (data.method != HTTP_GET) {
if (m_base->config()->http().isRestricted()) {
return HttpApiResponse(data.id(), HTTP_STATUS_FORBIDDEN).end();
}
if (!data.headers.count(kContentType) || data.headers.at(kContentType) != "application/json") {
return HttpApiResponse(data.id(), HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE).end();
}
}
m_base->api()->request(data);
}
int xmrig::Httpd::auth(const HttpData &req) const
{
const Http &config = m_base->config()->http();
if (!req.headers.count(kAuthorization)) {
return config.isAuthRequired() ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_OK;
}
if (config.token().isNull()) {
return HTTP_STATUS_UNAUTHORIZED;
}
const std::string &token = req.headers.at(kAuthorization);
const size_t size = token.size();
if (token.size() < 8 || config.token().size() != size - 7 || memcmp("Bearer ", token.c_str(), 7) != 0) {
return HTTP_STATUS_FORBIDDEN;
}
return strncmp(config.token().data(), token.c_str() + 7, config.token().size()) == 0 ? HTTP_STATUS_OK : HTTP_STATUS_FORBIDDEN;
}

70
src/api/Httpd.h Normal file
View File

@@ -0,0 +1,70 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPD_H
#define XMRIG_HTTPD_H
#include <stdint.h>
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/kernel/interfaces/IHttpListener.h"
namespace xmrig {
class Base;
class HttpServer;
class TcpServer;
class Httpd : public IBaseListener, public IHttpListener
{
public:
Httpd(Base *base);
~Httpd() override;
bool start();
void stop();
protected:
void onConfigChanged(Config *config, Config *previousConfig) override;
void onHttpData(const HttpData &data) override;
private:
int auth(const HttpData &req) const;
Base *m_base;
HttpServer *m_http;
TcpServer *m_server;
uint16_t m_port;
};
} /* namespace xmrig */
#endif /* XMRIG_HTTPD_H */

View File

@@ -20,31 +20,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONFIGCREATOR_H__
#define __CONFIGCREATOR_H__
#include "common/interfaces/IConfigCreator.h"
#include "core/Config.h"
#ifndef XMRIG_IAPILISTENER_H
#define XMRIG_IAPILISTENER_H
namespace xmrig {
class IConfig;
class IApiRequest;
class ConfigCreator : public IConfigCreator
class IApiListener
{
public:
inline IConfig *create() const override
{
return new Config();
}
virtual ~IApiListener() = default;
# ifdef XMRIG_FEATURE_API
virtual void onRequest(IApiRequest &request) = 0;
# endif
};
} /* namespace xmrig */
#endif // __CONFIGCREATOR_H__
#endif // XMRIG_IAPILISTENER_H

View File

@@ -0,0 +1,82 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IAPIREQUEST_H
#define XMRIG_IAPIREQUEST_H
#include "rapidjson/fwd.h"
namespace xmrig {
class String;
class IApiRequest
{
public:
enum Method {
METHOD_DELETE,
METHOD_GET,
METHOD_HEAD,
METHOD_POST,
METHOD_PUT
};
enum Source {
SOURCE_HTTP
};
enum RequestType {
REQ_UNKNOWN,
REQ_SUMMARY
};
virtual ~IApiRequest() = default;
virtual bool isDone() const = 0;
virtual bool isNew() const = 0;
virtual bool isRestricted() const = 0;
virtual const rapidjson::Value &json() const = 0;
virtual const String &url() const = 0;
virtual int version() const = 0;
virtual Method method() const = 0;
virtual rapidjson::Document &doc() = 0;
virtual rapidjson::Value &reply() = 0;
virtual RequestType type() const = 0;
virtual Source source() const = 0;
virtual void accept() = 0;
virtual void done(int status) = 0;
};
} /* namespace xmrig */
#endif // XMRIG_IAPIREQUEST_H

View File

@@ -23,24 +23,16 @@
*/
#include <uv.h>
#include "api/requests/ApiRequest.h"
#include "common/net/SubmitResult.h"
xmrig::SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId) :
reqId(reqId),
seq(seq),
diff(diff),
actualDiff(actualDiff),
elapsed(0)
xmrig::ApiRequest::ApiRequest(Source source, bool restricted) :
m_restricted(restricted),
m_source(source)
{
start = uv_hrtime();
}
void xmrig::SubmitResult::done()
xmrig::ApiRequest::~ApiRequest()
{
elapsed = (uv_hrtime() - start) / 1000000;
}

View File

@@ -0,0 +1,72 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_APIREQUEST_H
#define XMRIG_APIREQUEST_H
#include "api/interfaces/IApiRequest.h"
namespace xmrig {
class ApiRequest : public IApiRequest
{
public:
ApiRequest(Source source, bool restricted);
~ApiRequest() override;
protected:
inline bool isDone() const override { return m_state == STATE_DONE; }
inline bool isNew() const override { return m_state == STATE_NEW; }
inline bool isRestricted() const override { return m_restricted; }
inline int version() const override { return m_version; }
inline RequestType type() const override { return m_type; }
inline Source source() const override { return m_source; }
inline void accept() override { m_state = STATE_ACCEPTED; }
inline void done(int) override { m_state = STATE_DONE; }
int m_version = 1;
RequestType m_type = REQ_UNKNOWN;
private:
enum State {
STATE_NEW,
STATE_ACCEPTED,
STATE_DONE
};
bool m_restricted;
Source m_source;
State m_state = STATE_NEW;
};
} // namespace xmrig
#endif // XMRIG_APIREQUEST_H

View File

@@ -0,0 +1,87 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "api/requests/HttpApiRequest.h"
#include "base/net/http/HttpData.h"
#include "rapidjson/error/en.h"
xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) :
ApiRequest(SOURCE_HTTP, restricted),
m_parsed(false),
m_req(req),
m_res(req.id()),
m_url(req.url.c_str())
{
if (method() == METHOD_GET) {
if (url() == "/1/summary" || url() == "/2/summary" || url() == "/api.json") {
m_type = REQ_SUMMARY;
}
}
if (url().size() > 4) {
if (memcmp(url().data(), "/2/", 3) == 0) {
m_version = 2;
}
}
}
const rapidjson::Value &xmrig::HttpApiRequest::json() const
{
return m_body;
}
xmrig::IApiRequest::Method xmrig::HttpApiRequest::method() const
{
return static_cast<IApiRequest::Method>(m_req.method);
}
void xmrig::HttpApiRequest::accept()
{
using namespace rapidjson;
ApiRequest::accept();
if (!m_parsed && !m_req.body.empty()) {
m_parsed = true;
m_body.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(m_req.body.c_str());
if (m_body.HasParseError()) {
reply().AddMember("error", StringRef(GetParseError_En(m_body.GetParseError())), doc().GetAllocator());;
}
}
}
void xmrig::HttpApiRequest::done(int status)
{
ApiRequest::done(status);
m_res.setStatus(status);
m_res.end();
}

View File

@@ -0,0 +1,69 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HTTPAPIREQUEST_H
#define XMRIG_HTTPAPIREQUEST_H
#include "api/requests/ApiRequest.h"
#include "base/net/http/HttpApiResponse.h"
#include "base/tools/String.h"
namespace xmrig {
class HttpData;
class HttpApiRequest : public ApiRequest
{
public:
HttpApiRequest(const HttpData &req, bool restricted);
protected:
inline rapidjson::Document &doc() override { return m_res.doc(); }
inline rapidjson::Value &reply() override { return m_res.doc(); }
inline const String &url() const override { return m_url; }
const rapidjson::Value &json() const override;
Method method() const override;
void accept() override;
void done(int status) override;
private:
bool m_parsed;
const HttpData &m_req;
HttpApiResponse m_res;
rapidjson::Document m_body;
String m_url;
};
} // namespace xmrig
#endif // XMRIG_HTTPAPIREQUEST_H

13
src/backend/backend.cmake Normal file
View File

@@ -0,0 +1,13 @@
include (src/backend/cpu/cpu.cmake)
include (src/backend/common/common.cmake)
set(HEADERS_BACKEND
"${HEADERS_BACKEND_COMMON}"
"${HEADERS_BACKEND_CPU}"
)
set(SOURCES_BACKEND
"${SOURCES_BACKEND_COMMON}"
"${SOURCES_BACKEND_CPU}"
)

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,21 +24,20 @@
#include <assert.h>
#include <chrono>
#include <math.h>
#include <cmath>
#include <memory.h>
#include <stdio.h>
#include "common/log/Log.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "workers/Hashrate.h"
#include "backend/common/Hashrate.h"
#include "base/tools/Chrono.h"
#include "base/tools/Handle.h"
#include "rapidjson/document.h"
inline static const char *format(double h, char *buf, size_t size)
{
if (isnormal(h)) {
if (std::isnormal(h)) {
snprintf(buf, size, "%03.1f", h);
return buf;
}
@@ -46,10 +46,9 @@ inline static const char *format(double h, char *buf, size_t size)
}
Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
xmrig::Hashrate::Hashrate(size_t threads) :
m_highest(0.0),
m_threads(threads),
m_controller(controller)
m_threads(threads)
{
m_counts = new uint64_t*[threads];
m_timestamps = new uint64_t*[threads];
@@ -60,26 +59,30 @@ Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) :
m_timestamps[i] = new uint64_t[kBucketSize]();
m_top[i] = 0;
}
const int printTime = controller->config()->printTime();
if (printTime > 0) {
uv_timer_init(uv_default_loop(), &m_timer);
m_timer.data = this;
uv_timer_start(&m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000);
}
}
double Hashrate::calc(size_t ms) const
xmrig::Hashrate::~Hashrate()
{
for (size_t i = 0; i < m_threads; i++) {
delete [] m_counts[i];
delete [] m_timestamps[i];
}
delete [] m_counts;
delete [] m_timestamps;
delete [] m_top;
}
double xmrig::Hashrate::calc(size_t ms) const
{
double result = 0.0;
double data;
for (size_t i = 0; i < m_threads; ++i) {
data = calc(i, ms);
if (isnormal(data)) {
if (std::isnormal(data)) {
result += data;
}
}
@@ -88,16 +91,13 @@ double Hashrate::calc(size_t ms) const
}
double Hashrate::calc(size_t threadId, size_t ms) const
double xmrig::Hashrate::calc(size_t threadId, size_t ms) const
{
assert(threadId < m_threads);
if (threadId >= m_threads) {
return nan("");
}
using namespace std::chrono;
const uint64_t now = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
uint64_t earliestHashCount = 0;
uint64_t earliestStamp = 0;
uint64_t lastestStamp = 0;
@@ -116,7 +116,7 @@ double Hashrate::calc(size_t threadId, size_t ms) const
lastestHashCnt = m_counts[threadId][idx];
}
if (now - m_timestamps[threadId][idx] > ms) {
if (xmrig::Chrono::highResolutionMSecs() - m_timestamps[threadId][idx] > ms) {
haveFullSet = true;
break;
}
@@ -133,16 +133,14 @@ double Hashrate::calc(size_t threadId, size_t ms) const
return nan("");
}
double hashes, time;
hashes = (double) lastestHashCnt - earliestHashCount;
time = (double) lastestStamp - earliestStamp;
time /= 1000.0;
const double hashes = static_cast<double>(lastestHashCnt - earliestHashCount);
const double time = static_cast<double>(lastestStamp - earliestStamp) / 1000.0;
return hashes / time;
}
void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
void xmrig::Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
{
const size_t top = m_top[threadId];
m_counts[threadId][top] = count;
@@ -152,45 +150,28 @@ void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
}
void Hashrate::print() const
{
char num1[8] = { 0 };
char num2[8] = { 0 };
char num3[8] = { 0 };
char num4[8] = { 0 };
LOG_INFO(m_controller->config()->isColors() ? WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("H/s") " max " CYAN_BOLD("%s H/s")
: "speed 10s/60s/15m %s %s %s H/s max %s H/s",
format(calc(ShortInterval), num1, sizeof(num1)),
format(calc(MediumInterval), num2, sizeof(num2)),
format(calc(LargeInterval), num3, sizeof(num3)),
format(m_highest, num4, sizeof(num4))
);
}
void Hashrate::stop()
{
uv_timer_stop(&m_timer);
}
void Hashrate::updateHighest()
void xmrig::Hashrate::updateHighest()
{
double highest = calc(ShortInterval);
if (isnormal(highest) && highest > m_highest) {
if (std::isnormal(highest) && highest > m_highest) {
m_highest = highest;
}
}
const char *Hashrate::format(double h, char *buf, size_t size)
const char *xmrig::Hashrate::format(double h, char *buf, size_t size)
{
return ::format(h, buf, size);
}
void Hashrate::onReport(uv_timer_t *handle)
rapidjson::Value xmrig::Hashrate::normalize(double d)
{
static_cast<Hashrate*>(handle->data)->print();
using namespace rapidjson;
if (!std::isnormal(d)) {
return Value(kNullType);
}
return Value(floor(d * 100.0) / 100.0);
}

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,17 +22,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HASHRATE_H__
#define __HASHRATE_H__
#ifndef XMRIG_HASHRATE_H
#define XMRIG_HASHRATE_H
#include <stddef.h>
#include <stdint.h>
#include <uv.h>
#include "rapidjson/fwd.h"
namespace xmrig {
class Controller;
}
class Hashrate
@@ -43,22 +45,20 @@ public:
LargeInterval = 900000
};
Hashrate(size_t threads, xmrig::Controller *controller);
Hashrate(size_t threads);
~Hashrate();
double calc(size_t ms) const;
double calc(size_t threadId, size_t ms) const;
void add(size_t threadId, uint64_t count, uint64_t timestamp);
void print() const;
void stop();
void updateHighest();
inline double highest() const { return m_highest; }
inline size_t threads() const { return m_threads; }
static const char *format(double h, char *buf, size_t size);
static rapidjson::Value normalize(double d);
private:
static void onReport(uv_timer_t *handle);
constexpr static size_t kBucketSize = 2 << 11;
constexpr static size_t kBucketMask = kBucketSize - 1;
@@ -67,9 +67,10 @@ private:
uint32_t* m_top;
uint64_t** m_counts;
uint64_t** m_timestamps;
uv_timer_t m_timer;
xmrig::Controller *m_controller;
};
#endif /* __HASHRATE_H__ */
} // namespace xmrig
#endif /* XMRIG_HASHRATE_H */

View File

@@ -0,0 +1,67 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_THREAD_H
#define XMRIG_THREAD_H
#include <uv.h>
#include "backend/common/interfaces/IWorker.h"
namespace xmrig {
class IBackend;
template<class T>
class Thread
{
public:
inline Thread(IBackend *backend, size_t index, const T &config) : m_index(index), m_config(config), m_backend(backend) {}
inline ~Thread() { uv_thread_join(&m_thread); delete m_worker; }
inline const T &config() const { return m_config; }
inline IBackend *backend() const { return m_backend; }
inline IWorker *worker() const { return m_worker; }
inline size_t index() const { return m_index; }
inline void setWorker(IWorker *worker) { m_worker = worker; }
inline void start(void (*callback) (void *)) { uv_thread_create(&m_thread, callback, this); }
private:
const size_t m_index = 0;
const T m_config;
IBackend *m_backend;
IWorker *m_worker = nullptr;
uv_thread_t m_thread;
};
} // namespace xmrig
#endif /* XMRIG_THREAD_H */

View File

@@ -0,0 +1,164 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/common/Threads.h"
#include "backend/cpu/CpuThread.h"
#include "rapidjson/document.h"
namespace xmrig {
static const char *kAsterisk = "*";
} // namespace xmrig
template <class T>
const std::vector<T> &xmrig::Threads<T>::get(const String &profileName) const
{
static std::vector<T> empty;
if (profileName.isNull() || !has(profileName)) {
return empty;
}
return m_profiles.at(profileName);
}
template <class T>
size_t xmrig::Threads<T>::read(const rapidjson::Value &value)
{
using namespace rapidjson;
for (auto &member : value.GetObject()) {
if (member.value.IsArray()) {
std::vector<T> threads;
for (auto &v : member.value.GetArray()) {
T thread(v);
if (thread.isValid()) {
threads.push_back(std::move(thread));
}
}
if (!threads.empty()) {
move(member.name.GetString(), std::move(threads));
}
continue;
}
const Algorithm algo(member.name.GetString());
if (!algo.isValid()) {
continue;
}
if (member.value.IsBool() && member.value.IsFalse()) {
disable(algo);
continue;
}
if (member.value.IsString()) {
if (has(member.value.GetString())) {
m_aliases.insert({ algo, member.value.GetString() });
}
else {
m_disabled.insert(algo);
}
}
}
return m_profiles.size();
}
template <class T>
xmrig::String xmrig::Threads<T>::profileName(const Algorithm &algorithm, bool strict) const
{
if (isDisabled(algorithm)) {
return String();
}
const String name = algorithm.shortName();
if (has(name)) {
return name;
}
if (m_aliases.count(algorithm) > 0) {
return m_aliases.at(algorithm);
}
if (strict) {
return String();
}
if (name.contains("/")) {
const String base = name.split('/').at(0);
if (has(base)) {
return base;
}
}
if (has(kAsterisk)) {
return kAsterisk;
}
return String();
}
template <class T>
void xmrig::Threads<T>::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
for (const auto &kv : m_profiles) {
Value arr(kArrayType);
for (const T &thread : kv.second) {
arr.PushBack(thread.toJSON(doc), allocator);
}
out.AddMember(kv.first.toJSON(), arr, allocator);
}
for (const Algorithm &algo : m_disabled) {
out.AddMember(StringRef(algo.shortName()), false, allocator);
}
for (const auto &kv : m_aliases) {
out.AddMember(StringRef(kv.first.shortName()), kv.second.toJSON(), allocator);
}
}
namespace xmrig {
template class Threads<CpuThread>;
} // namespace xmrig

View File

@@ -0,0 +1,67 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_THREADS_H
#define XMRIG_THREADS_H
#include <map>
#include <set>
#include "base/tools/String.h"
#include "crypto/common/Algorithm.h"
#include "rapidjson/fwd.h"
namespace xmrig {
template <class T>
class Threads
{
public:
inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; }
inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; }
inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); }
inline const std::vector<T> &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); }
inline void disable(const Algorithm &algo) { m_disabled.insert(algo); }
inline void move(const char *profile, std::vector<T> &&threads) { m_profiles.insert({ profile, threads }); }
const std::vector<T> &get(const String &profileName) const;
size_t read(const rapidjson::Value &value);
String profileName(const Algorithm &algorithm, bool strict = false) const;
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
private:
std::map<Algorithm, String> m_aliases;
std::map<String, std::vector<T> > m_profiles;
std::set<Algorithm> m_disabled;
};
} /* namespace xmrig */
#endif /* XMRIG_THREADS_H */

View File

@@ -0,0 +1,47 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/common/Worker.h"
#include "base/kernel/Platform.h"
#include "base/tools/Chrono.h"
xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) :
m_id(id),
m_hashCount(0),
m_timestamp(0),
m_count(0)
{
Platform::trySetThreadAffinity(affinity);
Platform::setThreadPriority(priority);
}
void xmrig::Worker::storeStats()
{
m_hashCount.store(m_count, std::memory_order_relaxed);
m_timestamp.store(Chrono::highResolutionMSecs(), std::memory_order_relaxed);
}

View File

@@ -5,7 +5,9 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,41 +31,33 @@
#include <stdint.h>
#include "interfaces/IWorker.h"
#include "Mem.h"
class Handle;
#include "backend/common/interfaces/IWorker.h"
namespace xmrig {
class CpuThread;
}
class Worker : public IWorker
{
public:
Worker(Handle *handle);
Worker(size_t id, int64_t affinity, int priority);
inline const MemInfo &memory() const { return m_memory; }
inline size_t id() const override { return m_id; }
inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); }
inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); }
inline const VirtualMemory *memory() const override { return nullptr; }
inline size_t id() const override { return m_id; }
inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); }
inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); }
protected:
void storeStats();
const size_t m_id;
const size_t m_totalWays;
const uint32_t m_offset;
MemInfo m_memory;
std::atomic<uint64_t> m_hashCount;
std::atomic<uint64_t> m_timestamp;
uint64_t m_count;
uint64_t m_sequence;
xmrig::CpuThread *m_thread;
};
} // namespace xmrig
#endif /* XMRIG_WORKER_H */

View File

@@ -0,0 +1,142 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_WORKERJOB_H
#define XMRIG_WORKERJOB_H
#include <string.h>
#include "base/net/stratum/Job.h"
#include "crypto/common/Nonce.h"
namespace xmrig {
template<size_t N>
class WorkerJob
{
public:
inline const Job &currentJob() const { return m_jobs[index()]; }
inline uint32_t *nonce(size_t i = 0) { return reinterpret_cast<uint32_t*>(blob() + (i * currentJob().size()) + 39); }
inline uint64_t sequence() const { return m_sequence; }
inline uint8_t *blob() { return m_blobs[index()]; }
inline uint8_t index() const { return m_index; }
inline void add(const Job &job, uint64_t sequence, uint32_t reserveCount)
{
m_sequence = sequence;
if (currentJob() == job) {
return;
}
if (index() == 1 && job.index() == 0 && job == m_jobs[0]) {
return;
}
save(job, reserveCount);
}
inline void nextRound(uint32_t reserveCount)
{
m_rounds[index()]++;
if ((m_rounds[index()] % reserveCount) == 0) {
for (size_t i = 0; i < N; ++i) {
*nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, currentJob().isNicehash());
}
}
else {
for (size_t i = 0; i < N; ++i) {
*nonce(i) += 1;
}
}
}
private:
inline void save(const Job &job, uint32_t reserveCount)
{
m_index = job.index();
const size_t size = job.size();
m_jobs[index()] = job;
m_rounds[index()] = 0;
for (size_t i = 0; i < N; ++i) {
memcpy(m_blobs[index()] + (i * size), job.blob(), size);
*nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, job.isNicehash());
}
}
alignas(16) uint8_t m_blobs[2][Job::kMaxBlobSize * N];
Job m_jobs[2];
uint32_t m_rounds[2] = { 0, 0 };
uint64_t m_sequence = 0;
uint8_t m_index = 0;
};
template<>
inline uint32_t *xmrig::WorkerJob<1>::nonce(size_t)
{
return reinterpret_cast<uint32_t*>(blob() + 39);
}
template<>
inline void xmrig::WorkerJob<1>::nextRound(uint32_t reserveCount)
{
m_rounds[index()]++;
if ((m_rounds[index()] % reserveCount) == 0) {
*nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash());
}
else {
*nonce() += 1;
}
}
template<>
inline void xmrig::WorkerJob<1>::save(const Job &job, uint32_t reserveCount)
{
m_index = job.index();
m_jobs[index()] = job;
m_rounds[index()] = 0;
memcpy(blob(), job.blob(), job.size());
*nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash());
}
} // namespace xmrig
#endif /* XMRIG_WORKERJOB_H */

View File

@@ -0,0 +1,224 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/common/Hashrate.h"
#include "backend/common/interfaces/IBackend.h"
#include "backend/common/Workers.h"
#include "backend/cpu/CpuWorker.h"
#include "base/io/log/Log.h"
namespace xmrig {
class WorkersPrivate
{
public:
inline WorkersPrivate()
{
}
inline ~WorkersPrivate()
{
delete hashrate;
}
Hashrate *hashrate = nullptr;
IBackend *backend = nullptr;
};
} // namespace xmrig
template<class T>
xmrig::Workers<T>::Workers() :
d_ptr(new WorkersPrivate())
{
}
template<class T>
xmrig::Workers<T>::~Workers()
{
delete d_ptr;
}
template<class T>
const xmrig::Hashrate *xmrig::Workers<T>::hashrate() const
{
return d_ptr->hashrate;
}
template<class T>
void xmrig::Workers<T>::setBackend(IBackend *backend)
{
d_ptr->backend = backend;
}
template<class T>
void xmrig::Workers<T>::start(const std::vector<T> &data)
{
for (const T &item : data) {
m_workers.push_back(new Thread<T>(d_ptr->backend, m_workers.size(), item));
}
d_ptr->hashrate = new Hashrate(m_workers.size());
for (Thread<T> *worker : m_workers) {
worker->start(Workers<T>::onReady);
}
}
template<class T>
void xmrig::Workers<T>::stop()
{
Nonce::stop(T::backend());
for (Thread<T> *worker : m_workers) {
delete worker;
}
m_workers.clear();
Nonce::touch(T::backend());
delete d_ptr->hashrate;
d_ptr->hashrate = nullptr;
}
template<class T>
void xmrig::Workers<T>::tick(uint64_t)
{
if (!d_ptr->hashrate) {
return;
}
for (Thread<T> *handle : m_workers) {
if (!handle->worker()) {
return;
}
d_ptr->hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp());
}
d_ptr->hashrate->updateHighest();
}
template<class T>
xmrig::IWorker *xmrig::Workers<T>::create(Thread<CpuLaunchData> *)
{
return nullptr;
}
template<class T>
void xmrig::Workers<T>::onReady(void *arg)
{
Thread<T> *handle = static_cast<Thread<T>* >(arg);
IWorker *worker = create(handle);
if (!worker || !worker->selfTest()) {
LOG_ERR("thread %zu error: \"hash self-test failed\".", worker->id());
return;
}
handle->setWorker(worker);
handle->backend()->start(worker);
}
namespace xmrig {
#if defined (XMRIG_ALGO_RANDOMX) || defined (XMRIG_ALGO_CN_GPU)
static void printIntensityWarning(Thread<CpuLaunchData> *handle)
{
LOG_WARN("CPU thread %zu warning: \"intensity %d not supported for %s algorithm\".", handle->index(), handle->config().intensity, handle->config().algorithm.shortName());
}
#endif
template<>
xmrig::IWorker *xmrig::Workers<CpuLaunchData>::create(Thread<CpuLaunchData> *handle)
{
const int intensity = handle->config().intensity;
# if defined (XMRIG_ALGO_RANDOMX) || defined (XMRIG_ALGO_CN_GPU)
if (intensity > 1) {
# ifdef XMRIG_ALGO_RANDOMX
if (handle->config().algorithm.family() == Algorithm::RANDOM_X) {
printIntensityWarning(handle);
return new CpuWorker<1>(handle->index(), handle->config());
}
# endif
# ifdef XMRIG_ALGO_CN_GPU
if (handle->config().algorithm == Algorithm::CN_GPU) {
printIntensityWarning(handle);
return new CpuWorker<1>(handle->index(), handle->config());
}
# endif
}
# endif
switch (intensity) {
case 1:
return new CpuWorker<1>(handle->index(), handle->config());
case 2:
return new CpuWorker<2>(handle->index(), handle->config());
case 3:
return new CpuWorker<3>(handle->index(), handle->config());
case 4:
return new CpuWorker<4>(handle->index(), handle->config());
case 5:
return new CpuWorker<5>(handle->index(), handle->config());
}
return nullptr;
}
template class Workers<CpuLaunchData>;
} // namespace xmrig

View File

@@ -0,0 +1,73 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_WORKERS_H
#define XMRIG_WORKERS_H
#include "backend/common/Thread.h"
#include "backend/cpu/CpuLaunchData.h"
namespace xmrig {
class Hashrate;
class WorkersPrivate;
template<class T>
class Workers
{
public:
Workers();
~Workers();
const Hashrate *hashrate() const;
void setBackend(IBackend *backend);
void start(const std::vector<T> &data);
void stop();
void tick(uint64_t ticks);
private:
static IWorker *create(Thread<CpuLaunchData> *handle);
static void onReady(void *arg);
std::vector<Thread<T> *> m_workers;
WorkersPrivate *d_ptr;
};
template<>
IWorker *Workers<CpuLaunchData>::create(Thread<CpuLaunchData> *handle);
extern template class Workers<CpuLaunchData>;
} // namespace xmrig
#endif /* XMRIG_WORKERS_H */

View File

@@ -0,0 +1,18 @@
set(HEADERS_BACKEND_COMMON
src/backend/common/interfaces/IBackend.h
src/backend/common/interfaces/IThread.h
src/backend/common/interfaces/IWorker.h
src/backend/common/Hashrate.h
src/backend/common/Thread.h
src/backend/common/Threads.h
src/backend/common/Worker.h
src/backend/common/Workers.h
src/backend/common/WorkerJob.h
)
set(SOURCES_BACKEND_COMMON
src/backend/common/Hashrate.cpp
src/backend/common/Threads.cpp
src/backend/common/Worker.cpp
src/backend/common/Workers.cpp
)

View File

@@ -0,0 +1,70 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IBACKEND_H
#define XMRIG_IBACKEND_H
#include <stdint.h>
#include "rapidjson/fwd.h"
namespace xmrig {
class Algorithm;
class Hashrate;
class IWorker;
class Job;
class String;
class IBackend
{
public:
virtual ~IBackend() = default;
virtual bool isEnabled() const = 0;
virtual bool isEnabled(const Algorithm &algorithm) const = 0;
virtual const Hashrate *hashrate() const = 0;
virtual const String &profileName() const = 0;
virtual const String &type() const = 0;
virtual void printHashrate(bool details) = 0;
virtual void setJob(const Job &job) = 0;
virtual void start(IWorker *worker) = 0;
virtual void stop() = 0;
virtual void tick(uint64_t ticks) = 0;
# ifdef XMRIG_FEATURE_API
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
# endif
};
} // namespace xmrig
#endif // XMRIG_IBACKEND_H

View File

@@ -27,7 +27,7 @@
#include <stdint.h>
#include "common/xmrig.h"
#include "crypto/common/Algorithm.h"
#include "rapidjson/fwd.h"
@@ -51,9 +51,9 @@ public:
PentaWay
};
virtual ~IThread() {}
virtual ~IThread() = default;
virtual Algo algorithm() const = 0;
virtual Algorithm algorithm() const = 0;
virtual int priority() const = 0;
virtual int64_t affinity() const = 0;
virtual Multiway multiway() const = 0;
@@ -61,7 +61,7 @@ public:
virtual size_t index() const = 0;
virtual Type type() const = 0;
# ifndef XMRIG_NO_API
# ifdef XMRIG_FEATURE_API
virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0;
# endif

View File

@@ -27,6 +27,13 @@
#include <stdint.h>
#include <stddef.h>
namespace xmrig {
class VirtualMemory;
class IWorker
@@ -34,12 +41,16 @@ class IWorker
public:
virtual ~IWorker() = default;
virtual bool selfTest() = 0;
virtual size_t id() const = 0;
virtual uint64_t hashCount() const = 0;
virtual uint64_t timestamp() const = 0;
virtual void start() = 0;
virtual bool selfTest() = 0;
virtual const VirtualMemory *memory() const = 0;
virtual size_t id() const = 0;
virtual uint64_t hashCount() const = 0;
virtual uint64_t timestamp() const = 0;
virtual void start() = 0;
};
} // namespace xmrig
#endif // XMRIG_IWORKER_H

View File

@@ -4,8 +4,9 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2017 XMRig <support@xmrig.com>
*
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,11 +26,13 @@
#include <assert.h>
#include "common/cpu/Cpu.h"
#include "backend/cpu/Cpu.h"
#ifndef XMRIG_NO_LIBCPUID
# include "core/cpu/AdvancedCpuInfo.h"
#ifdef XMRIG_FEATURE_LIBCPUID
# include "backend/cpu/platform/AdvancedCpuInfo.h"
#else
# include "backend/cpu/platform/BasicCpuInfo.h"
#endif
@@ -48,7 +51,11 @@ void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
# ifdef XMRIG_FEATURE_LIBCPUID
cpuInfo = new AdvancedCpuInfo();
# else
cpuInfo = new BasicCpuInfo();
# endif
}

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,7 +26,7 @@
#define XMRIG_CPU_H
#include "common/interfaces/ICpuInfo.h"
#include "backend/cpu/interfaces/ICpuInfo.h"
namespace xmrig {
@@ -37,6 +38,8 @@ public:
static ICpuInfo *info();
static void init();
static void release();
inline static Assembly::Id assembly(Assembly::Id hint) { return hint == Assembly::AUTO ? Cpu::info()->assembly() : hint; }
};

View File

@@ -0,0 +1,343 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <uv.h>
#include "backend/common/Hashrate.h"
#include "backend/common/interfaces/IWorker.h"
#include "backend/common/Workers.h"
#include "backend/cpu/Cpu.h"
#include "backend/cpu/CpuBackend.h"
#include "base/io/log/Log.h"
#include "base/net/stratum/Job.h"
#include "base/tools/Chrono.h"
#include "base/tools/String.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "crypto/common/VirtualMemory.h"
#include "crypto/rx/Rx.h"
#include "crypto/rx/RxDataset.h"
#include "rapidjson/document.h"
namespace xmrig {
extern template class Threads<CpuThread>;
static const String kType = "cpu";
struct LaunchStatus
{
public:
inline void reset()
{
hugePages = 0;
memory = 0;
pages = 0;
started = 0;
threads = 0;
ways = 0;
ts = Chrono::steadyMSecs();
}
size_t hugePages = 0;
size_t memory = 0;
size_t pages = 0;
size_t started = 0;
size_t threads = 0;
size_t ways = 0;
uint64_t ts = 0;
};
class CpuBackendPrivate
{
public:
inline CpuBackendPrivate(Controller *controller) :
controller(controller)
{
uv_mutex_init(&mutex);
}
inline ~CpuBackendPrivate()
{
uv_mutex_destroy(&mutex);
}
inline void start()
{
LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"),
profileName.data(),
threads.size(),
algo.memory() / 1024
);
workers.stop();
status.reset();
status.memory = algo.memory();
status.threads = threads.size();
for (const CpuLaunchData &data : threads) {
status.ways += static_cast<size_t>(data.intensity);
}
workers.start(threads);
}
Algorithm algo;
Controller *controller;
LaunchStatus status;
std::vector<CpuLaunchData> threads;
String profileName;
uv_mutex_t mutex;
Workers<CpuLaunchData> workers;
};
} // namespace xmrig
xmrig::CpuBackend::CpuBackend(Controller *controller) :
d_ptr(new CpuBackendPrivate(controller))
{
d_ptr->workers.setBackend(this);
}
xmrig::CpuBackend::~CpuBackend()
{
delete d_ptr;
}
bool xmrig::CpuBackend::isEnabled() const
{
return d_ptr->controller->config()->cpu().isEnabled();
}
bool xmrig::CpuBackend::isEnabled(const Algorithm &algorithm) const
{
return !d_ptr->controller->config()->cpu().threads().get(algorithm).empty();
}
const xmrig::Hashrate *xmrig::CpuBackend::hashrate() const
{
return d_ptr->workers.hashrate();
}
const xmrig::String &xmrig::CpuBackend::profileName() const
{
return d_ptr->profileName;
}
const xmrig::String &xmrig::CpuBackend::type() const
{
return kType;
}
void xmrig::CpuBackend::printHashrate(bool details)
{
if (!details || !hashrate()) {
return;
}
char num[8 * 3] = { 0 };
Log::print(WHITE_BOLD_S "| CPU THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |");
size_t i = 0;
for (const CpuLaunchData &data : d_ptr->threads) {
Log::print("| %13zu | %8" PRId64 " | %7s | %7s | %7s |",
i,
data.affinity,
Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
);
i++;
}
}
void xmrig::CpuBackend::setJob(const Job &job)
{
if (!isEnabled()) {
d_ptr->workers.stop();
d_ptr->threads.clear();
return;
}
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm());
if (d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
return;
}
d_ptr->algo = job.algorithm();
d_ptr->profileName = cpu.threads().profileName(job.algorithm());
if (d_ptr->profileName.isNull() || threads.empty()) {
d_ptr->workers.stop();
LOG_WARN(YELLOW_BOLD_S "CPU disabled, no suitable configuration for algo %s", job.algorithm().shortName());
return;
}
d_ptr->threads = std::move(threads);
d_ptr->start();
}
void xmrig::CpuBackend::start(IWorker *worker)
{
uv_mutex_lock(&d_ptr->mutex);
const auto pages = worker->memory()->hugePages();
d_ptr->status.started++;
d_ptr->status.hugePages += pages.first;
d_ptr->status.pages += pages.second;
if (d_ptr->status.started == d_ptr->status.threads) {
const double percent = d_ptr->status.hugePages == 0 ? 0.0 : static_cast<double>(d_ptr->status.hugePages) / d_ptr->status.pages * 100.0;
const size_t memory = d_ptr->status.ways * d_ptr->status.memory / 1024;
LOG_INFO(GREEN_BOLD("CPU READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"),
d_ptr->status.threads, d_ptr->status.ways,
(d_ptr->status.hugePages == d_ptr->status.pages ? GREEN_BOLD_S : (d_ptr->status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
d_ptr->status.hugePages, d_ptr->status.pages, percent, memory,
Chrono::steadyMSecs() - d_ptr->status.ts
);
}
uv_mutex_unlock(&d_ptr->mutex);
worker->start();
}
void xmrig::CpuBackend::stop()
{
d_ptr->workers.stop();
}
void xmrig::CpuBackend::tick(uint64_t ticks)
{
d_ptr->workers.tick(ticks);
}
#ifdef XMRIG_FEATURE_API
rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
Value out(kObjectType);
out.AddMember("type", type().toJSON(), allocator);
out.AddMember("enabled", isEnabled(), allocator);
out.AddMember("algo", d_ptr->algo.toJSON(), allocator);
out.AddMember("profile", profileName().toJSON(), allocator);
out.AddMember("hw-aes", cpu.isHwAES(), allocator);
out.AddMember("priority", cpu.priority(), allocator);
# ifdef XMRIG_FEATURE_ASM
const Assembly assembly = Cpu::assembly(cpu.assembly());
out.AddMember("asm", assembly.toJSON(), allocator);
# else
out.AddMember("asm", false, allocator);
# endif
uv_mutex_lock(&d_ptr->mutex);
uint64_t pages[2] = { d_ptr->status.hugePages, d_ptr->status.pages };
const size_t ways = d_ptr->status.ways;
uv_mutex_unlock(&d_ptr->mutex);
# ifdef XMRIG_ALGO_RANDOMX
if (d_ptr->algo.family() == Algorithm::RANDOM_X) {
RxDataset *dataset = Rx::dataset();
if (dataset) {
const auto rxPages = dataset->hugePages();
pages[0] += rxPages.first;
pages[1] += rxPages.second;
}
}
# endif
rapidjson::Value hugepages(rapidjson::kArrayType);
hugepages.PushBack(pages[0], allocator);
hugepages.PushBack(pages[1], allocator);
out.AddMember("hugepages", hugepages, allocator);
out.AddMember("memory", static_cast<uint64_t>(d_ptr->algo.isValid() ? (ways * d_ptr->algo.memory()) : 0), allocator);
if (d_ptr->threads.empty() || !hashrate()) {
return out;
}
Value threads(kArrayType);
const Hashrate *hr = hashrate();
size_t i = 0;
for (const CpuLaunchData &data : d_ptr->threads) {
Value thread(kObjectType);
thread.AddMember("intensity", data.intensity, allocator);
thread.AddMember("affinity", data.affinity, allocator);
thread.AddMember("av", data.av(), allocator);
Value hashrate(kArrayType);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)), allocator);
i++;
thread.AddMember("hashrate", hashrate, allocator);
threads.PushBack(thread, allocator);
}
out.AddMember("threads", threads, allocator);
return out;
}
#endif

View File

@@ -0,0 +1,70 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CPUBACKEND_H
#define XMRIG_CPUBACKEND_H
#include "backend/common/interfaces/IBackend.h"
namespace xmrig {
class Controller;
class CpuBackendPrivate;
class Miner;
class CpuBackend : public IBackend
{
public:
CpuBackend(Controller *controller);
~CpuBackend() override;
protected:
bool isEnabled() const override;
bool isEnabled(const Algorithm &algorithm) const override;
const Hashrate *hashrate() const override;
const String &profileName() const override;
const String &type() const override;
void printHashrate(bool details) override;
void setJob(const Job &job) override;
void start(IWorker *worker) override;
void stop() override;
void tick(uint64_t ticks) override;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
# endif
private:
CpuBackendPrivate *d_ptr;
};
} /* namespace xmrig */
#endif /* XMRIG_CPUBACKEND_H */

View File

@@ -0,0 +1,187 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cpu/Cpu.h"
#include "backend/cpu/CpuConfig.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
namespace xmrig {
static const char *kCn = "cn";
static const char *kEnabled = "enabled";
static const char *kHugePages = "huge-pages";
static const char *kHwAes = "hw-aes";
static const char *kPriority = "priority";
#ifdef XMRIG_FEATURE_ASM
static const char *kAsm = "asm";
#endif
#ifdef XMRIG_ALGO_CN_GPU
static const char *kCnGPU = "cn/gpu";
#endif
#ifdef XMRIG_ALGO_CN_LITE
static const char *kCnLite = "cn-lite";
#endif
#ifdef XMRIG_ALGO_CN_HEAVY
static const char *kCnHeavy = "cn-heavy";
#endif
#ifdef XMRIG_ALGO_CN_PICO
static const char *kCnPico = "cn-pico";
#endif
#ifdef XMRIG_ALGO_RANDOMX
static const char *kRx = "rx";
static const char *kRxWOW = "rx/wow";
#endif
extern template class Threads<CpuThread>;
}
xmrig::CpuConfig::CpuConfig()
{
}
bool xmrig::CpuConfig::isHwAES() const
{
return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW;
}
rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value obj(kObjectType);
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
# ifdef XMRIG_FEATURE_ASM
obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator);
# endif
m_threads.toJSON(obj, doc);
return obj;
}
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
{
std::vector<CpuLaunchData> out;
const std::vector<CpuThread> &threads = m_threads.get(algorithm);
if (threads.empty()) {
return out;
}
out.reserve(threads.size());
for (const CpuThread &thread : threads) {
out.push_back(CpuLaunchData(miner, algorithm, *this, thread));
}
return out;
}
void xmrig::CpuConfig::read(const rapidjson::Value &value)
{
if (value.IsObject()) {
m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
setAesMode(Json::getValue(value, kHwAes));
setPriority(Json::getInt(value, kPriority, -1));
# ifdef XMRIG_FEATURE_ASM
m_assembly = Json::getValue(value, kAsm);
# endif
if (!m_threads.read(value)) {
generate();
}
}
else if (value.IsBool() && value.IsFalse()) {
m_enabled = false;
}
else {
generate();
}
}
void xmrig::CpuConfig::generate()
{
m_shouldSave = true;
m_threads.disable(Algorithm::CN_0);
m_threads.move(kCn, Cpu::info()->threads(Algorithm::CN_0));
# ifdef XMRIG_ALGO_CN_GPU
m_threads.move(kCnGPU, Cpu::info()->threads(Algorithm::CN_GPU));
# endif
# ifdef XMRIG_ALGO_CN_LITE
m_threads.disable(Algorithm::CN_LITE_0);
m_threads.move(kCnLite, Cpu::info()->threads(Algorithm::CN_LITE_1));
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
m_threads.move(kCnHeavy, Cpu::info()->threads(Algorithm::CN_HEAVY_0));
# endif
# ifdef XMRIG_ALGO_CN_PICO
m_threads.move(kCnPico, Cpu::info()->threads(Algorithm::CN_PICO_0));
# endif
# ifdef XMRIG_ALGO_RANDOMX
m_threads.move(kRx, Cpu::info()->threads(Algorithm::RX_0));
m_threads.move(kRxWOW, Cpu::info()->threads(Algorithm::RX_WOW));
# endif
}
void xmrig::CpuConfig::setAesMode(const rapidjson::Value &aesMode)
{
if (aesMode.IsBool()) {
m_aes = aesMode.GetBool() ? AES_HW : AES_SOFT;
}
else {
m_aes = AES_AUTO;
}
}

View File

@@ -0,0 +1,80 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CPUCONFIG_H
#define XMRIG_CPUCONFIG_H
#include "backend/common/Threads.h"
#include "backend/cpu/CpuLaunchData.h"
#include "backend/cpu/CpuThread.h"
#include "crypto/common/Assembly.h"
namespace xmrig {
class CpuConfig
{
public:
enum AesMode {
AES_AUTO,
AES_HW,
AES_SOFT
};
CpuConfig();
bool isHwAES() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
void read(const rapidjson::Value &value);
inline bool isEnabled() const { return m_enabled; }
inline bool isHugePages() const { return m_hugePages; }
inline bool isShouldSave() const { return m_shouldSave; }
inline const Assembly &assembly() const { return m_assembly; }
inline const Threads<CpuThread> &threads() const { return m_threads; }
inline int priority() const { return m_priority; }
private:
void generate();
void setAesMode(const rapidjson::Value &aesMode);
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
AesMode m_aes = AES_AUTO;
Assembly m_assembly;
bool m_enabled = true;
bool m_hugePages = true;
bool m_shouldSave = false;
int m_priority = -1;
Threads<CpuThread> m_threads;
};
} /* namespace xmrig */
#endif /* XMRIG_CPUCONFIG_H */

View File

@@ -0,0 +1,64 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cpu/CpuLaunchData.h"
#include "backend/cpu/CpuConfig.h"
xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread) :
algorithm(algorithm),
assembly(config.assembly()),
hugePages(config.isHugePages()),
hwAES(config.isHwAES()),
intensity(thread.intensity()),
priority(config.priority()),
affinity(thread.affinity()),
miner(miner)
{
}
bool xmrig::CpuLaunchData::isEqual(const CpuLaunchData &other) const
{
return (algorithm.memory() == other.algorithm.memory()
&& assembly == other.assembly
&& hugePages == other.hugePages
&& hwAES == other.hwAES
&& intensity == other.intensity
&& priority == other.priority
&& affinity == other.affinity
);
}
xmrig::CnHash::AlgoVariant xmrig::CpuLaunchData::av() const
{
if (intensity <= 2) {
return static_cast<CnHash::AlgoVariant>(!hwAES ? (intensity + 2) : intensity);
}
return static_cast<CnHash::AlgoVariant>(!hwAES ? (intensity + 5) : (intensity + 2));
}

View File

@@ -23,54 +23,49 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_MULTIWORKER_H
#define XMRIG_MULTIWORKER_H
#ifndef XMRIG_CPULAUNCHDATA_H
#define XMRIG_CPULAUNCHDATA_H
#include "common/net/Job.h"
#include "Mem.h"
#include "net/JobResult.h"
#include "workers/Worker.h"
#include "crypto/cn/CnHash.h"
#include "crypto/common/Algorithm.h"
#include "crypto/common/Assembly.h"
#include "crypto/common/Nonce.h"
class Handle;
namespace xmrig {
template<size_t N>
class MultiWorker : public Worker
class CpuConfig;
class CpuThread;
class Miner;
class CpuLaunchData
{
public:
MultiWorker(Handle *handle);
~MultiWorker();
CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread);
protected:
bool selfTest() override;
void start() override;
bool isEqual(const CpuLaunchData &other) const;
CnHash::AlgoVariant av() const;
private:
bool resume(const xmrig::Job &job);
bool verify(xmrig::Variant variant, const uint8_t *referenceValue);
bool verify2(xmrig::Variant variant, const uint8_t *referenceValue);
void consumeJob();
void save(const xmrig::Job &job);
inline constexpr static Nonce::Backend backend() { return Nonce::CPU; }
inline uint32_t *nonce(size_t index)
{
return reinterpret_cast<uint32_t*>(m_state.blob + (index * m_state.job.size()) + 39);
}
inline bool operator!=(const CpuLaunchData &other) const { return !isEqual(other); }
inline bool operator==(const CpuLaunchData &other) const { return isEqual(other); }
struct State
{
alignas(16) uint8_t blob[xmrig::Job::kMaxBlobSize * N];
xmrig::Job job;
};
cryptonight_ctx *m_ctx[N];
State m_pausedState;
State m_state;
uint8_t m_hash[N * 32];
const Algorithm algorithm;
const Assembly assembly;
const bool hugePages;
const bool hwAES;
const int intensity;
const int priority;
const int64_t affinity;
const Miner *miner;
};
#endif /* XMRIG_MULTIWORKER_H */
} // namespace xmrig
#endif /* XMRIG_CPULAUNCHDATA_H */

View File

@@ -0,0 +1,71 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/cpu/CpuThread.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
namespace xmrig {
static const char *kAffinity = "affinity";
static const char *kIntensity = "intensity";
}
xmrig::CpuThread::CpuThread(const rapidjson::Value &value)
{
if (value.IsObject()) {
m_intensity = Json::getInt(value, kIntensity, -1);
m_affinity = Json::getInt(value, kAffinity, -1);
}
else if (value.IsInt()) {
m_intensity = 1;
m_affinity = value.GetInt();
}
}
rapidjson::Value xmrig::CpuThread::toJSON(rapidjson::Document &doc) const
{
using namespace rapidjson;
if (intensity() > 1) {
auto &allocator = doc.GetAllocator();
Value obj(kObjectType);
obj.AddMember(StringRef(kIntensity), m_intensity, allocator);
obj.AddMember(StringRef(kAffinity), m_affinity, allocator);
return obj;
}
return Value(m_affinity);
}

View File

@@ -22,51 +22,46 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CONFIGLOADER_H
#define XMRIG_CONFIGLOADER_H
#ifndef XMRIG_CPUTHREADCONFIG_H
#define XMRIG_CPUTHREADCONFIG_H
#include <stdint.h>
#include <vector>
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class ConfigWatcher;
class IConfigCreator;
class IConfigListener;
class IConfig;
class Process;
class ConfigLoader
class CpuThread
{
public:
static bool loadFromFile(IConfig *config, const char *fileName);
static bool loadFromJSON(IConfig *config, const char *json);
static bool loadFromJSON(IConfig *config, const rapidjson::Document &doc);
static bool reload(IConfig *oldConfig, const char *json);
static bool watch(IConfig *config);
static IConfig *load(Process *process, IConfigCreator *creator, IConfigListener *listener);
static void release();
inline constexpr CpuThread(int intensity = 1, int64_t affinity = -1) : m_intensity(intensity), m_affinity(affinity) {}
CpuThread(const rapidjson::Value &value);
inline bool isEqual(const CpuThread &other) const { return other.m_affinity == m_affinity && other.m_intensity == m_intensity; }
inline bool isValid() const { return m_intensity >= 1 && m_intensity <= 5; }
inline int intensity() const { return m_intensity; }
inline int64_t affinity() const { return m_affinity; }
inline bool operator!=(const CpuThread &other) const { return !isEqual(other); }
inline bool operator==(const CpuThread &other) const { return isEqual(other); }
rapidjson::Value toJSON(rapidjson::Document &doc) const;
private:
static bool getJSON(const char *fileName, rapidjson::Document &doc);
static bool parseArg(IConfig *config, int key, const char *arg);
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
static ConfigWatcher *m_watcher;
static IConfigCreator *m_creator;
static IConfigListener *m_listener;
int m_intensity = -1;
int64_t m_affinity = -1;
};
typedef std::vector<CpuThread> CpuThreads;
} /* namespace xmrig */
#endif /* XMRIG_CONFIGLOADER_H */
#endif /* XMRIG_CPUTHREADCONFIG_H */

View File

@@ -0,0 +1,307 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <thread>
#include "backend/cpu/CpuWorker.h"
#include "core/Miner.h"
#include "crypto/cn/CnCtx.h"
#include "crypto/cn/CryptoNight_test.h"
#include "crypto/common/Nonce.h"
#include "crypto/common/VirtualMemory.h"
#include "crypto/rx/Rx.h"
#include "crypto/rx/RxVm.h"
#include "net/JobResults.h"
#ifdef XMRIG_ALGO_RANDOMX
# include "crypto/randomx/randomx.h"
#endif
namespace xmrig {
static constexpr uint32_t kReserveCount = 4096;
} // namespace xmrig
template<size_t N>
xmrig::CpuWorker<N>::CpuWorker(size_t index, const CpuLaunchData &data) :
Worker(index, data.affinity, data.priority),
m_algorithm(data.algorithm),
m_assembly(data.assembly),
m_hwAES(data.hwAES),
m_av(data.av()),
m_miner(data.miner),
m_ctx()
{
m_memory = new VirtualMemory(m_algorithm.memory() * N, data.hugePages);
}
template<size_t N>
xmrig::CpuWorker<N>::~CpuWorker()
{
CnCtx::release(m_ctx, N);
delete m_memory;
# ifdef XMRIG_ALGO_RANDOMX
delete m_vm;
# endif
}
#ifdef XMRIG_ALGO_RANDOMX
template<size_t N>
void xmrig::CpuWorker<N>::allocateRandomX_VM()
{
if (!m_vm) {
RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm());
m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES);
}
}
#endif
template<size_t N>
bool xmrig::CpuWorker<N>::selfTest()
{
# ifdef XMRIG_ALGO_RANDOMX
if (m_algorithm.family() == Algorithm::RANDOM_X) {
return N == 1;
}
# endif
allocateCnCtx();
if (m_algorithm.family() == Algorithm::CN) {
const bool rc = verify(Algorithm::CN_0, test_output_v0) &&
verify(Algorithm::CN_1, test_output_v1) &&
verify(Algorithm::CN_2, test_output_v2) &&
verify(Algorithm::CN_FAST, test_output_msr) &&
verify(Algorithm::CN_XAO, test_output_xao) &&
verify(Algorithm::CN_RTO, test_output_rto) &&
verify(Algorithm::CN_HALF, test_output_half) &&
verify2(Algorithm::CN_WOW, test_output_wow) &&
verify2(Algorithm::CN_R, test_output_r) &&
verify(Algorithm::CN_RWZ, test_output_rwz) &&
verify(Algorithm::CN_ZLS, test_output_zls) &&
verify(Algorithm::CN_DOUBLE, test_output_double);
# ifdef XMRIG_ALGO_CN_GPU
if (!rc || N > 1) {
return rc;
}
return verify(Algorithm::CN_GPU, test_output_gpu);
# else
return rc;
# endif
}
# ifdef XMRIG_ALGO_CN_LITE
if (m_algorithm.family() == Algorithm::CN_LITE) {
return verify(Algorithm::CN_LITE_0, test_output_v0_lite) &&
verify(Algorithm::CN_LITE_1, test_output_v1_lite);
}
# endif
# ifdef XMRIG_ALGO_CN_HEAVY
if (m_algorithm.family() == Algorithm::CN_HEAVY) {
return verify(Algorithm::CN_HEAVY_0, test_output_v0_heavy) &&
verify(Algorithm::CN_HEAVY_XHV, test_output_xhv_heavy) &&
verify(Algorithm::CN_HEAVY_TUBE, test_output_tube_heavy);
}
# endif
# ifdef XMRIG_ALGO_CN_PICO
if (m_algorithm.family() == Algorithm::CN_PICO) {
return verify(Algorithm::CN_PICO_0, test_output_pico_trtl);
}
# endif
return false;
}
template<size_t N>
void xmrig::CpuWorker<N>::start()
{
while (Nonce::sequence(Nonce::CPU) > 0) {
if (Nonce::isPaused()) {
do {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
while (Nonce::isPaused() && Nonce::sequence(Nonce::CPU) > 0);
if (Nonce::sequence(Nonce::CPU) == 0) {
break;
}
consumeJob();
}
while (!Nonce::isOutdated(Nonce::CPU, m_job.sequence())) {
if ((m_count & 0x7) == 0) {
storeStats();
}
const Job &job = m_job.currentJob();
if (job.algorithm().memory() != m_algorithm.memory()) {
break;
}
# ifdef XMRIG_ALGO_RANDOMX
if (job.algorithm().family() == Algorithm::RANDOM_X) {
randomx_calculate_hash(m_vm->get(), m_job.blob(), job.size(), m_hash);
}
else
# endif
{
fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height());
}
for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < job.target()) {
JobResults::submit(JobResult(job, *m_job.nonce(i), m_hash + (i * 32)));
}
}
m_job.nextRound(kReserveCount);
m_count += N;
std::this_thread::yield();
}
consumeJob();
}
}
template<size_t N>
bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
{
cn_hash_fun func = fn(algorithm);
if (!func) {
return false;
}
func(test_input, 76, m_hash, m_ctx, 0);
return memcmp(m_hash, referenceValue, sizeof m_hash) == 0;
}
template<size_t N>
bool xmrig::CpuWorker<N>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
{
cn_hash_fun func = fn(algorithm);
if (!func) {
return false;
}
for (size_t i = 0; i < (sizeof(cn_r_test_input) / sizeof(cn_r_test_input[0])); ++i) {
const size_t size = cn_r_test_input[i].size;
for (size_t k = 0; k < N; ++k) {
memcpy(m_job.blob() + (k * size), cn_r_test_input[i].data, size);
}
func(m_job.blob(), size, m_hash, m_ctx, cn_r_test_input[i].height);
for (size_t k = 0; k < N; ++k) {
if (memcmp(m_hash + k * 32, referenceValue + i * 32, sizeof m_hash / N) != 0) {
return false;
}
}
}
return true;
}
namespace xmrig {
template<>
bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
{
cn_hash_fun func = fn(algorithm);
if (!func) {
return false;
}
for (size_t i = 0; i < (sizeof(cn_r_test_input) / sizeof(cn_r_test_input[0])); ++i) {
func(cn_r_test_input[i].data, cn_r_test_input[i].size, m_hash, m_ctx, cn_r_test_input[i].height);
if (memcmp(m_hash, referenceValue + i * 32, sizeof m_hash) != 0) {
return false;
}
}
return true;
}
} // namespace xmrig
template<size_t N>
void xmrig::CpuWorker<N>::allocateCnCtx()
{
if (m_ctx[0] == nullptr) {
CnCtx::create(m_ctx, m_memory->scratchpad(), m_algorithm.memory(), N);
}
}
template<size_t N>
void xmrig::CpuWorker<N>::consumeJob()
{
m_job.add(m_miner->job(), Nonce::sequence(Nonce::CPU), kReserveCount);
# ifdef XMRIG_ALGO_RANDOMX
if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) {
allocateRandomX_VM();
}
else
# endif
{
allocateCnCtx();
}
}
namespace xmrig {
template class CpuWorker<1>;
template class CpuWorker<2>;
template class CpuWorker<3>;
template class CpuWorker<4>;
template class CpuWorker<5>;
} // namespace xmrig

View File

@@ -0,0 +1,98 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CPUWORKER_H
#define XMRIG_CPUWORKER_H
#include "backend/common/Worker.h"
#include "backend/common/WorkerJob.h"
#include "backend/cpu/CpuLaunchData.h"
#include "base/net/stratum/Job.h"
#include "net/JobResult.h"
namespace xmrig {
class RxVm;
template<size_t N>
class CpuWorker : public Worker
{
public:
CpuWorker(size_t index, const CpuLaunchData &data);
~CpuWorker() override;
protected:
bool selfTest() override;
void start() override;
inline const VirtualMemory *memory() const override { return m_memory; }
private:
inline cn_hash_fun fn(const Algorithm &algorithm) const { return CnHash::fn(algorithm, m_av, m_assembly); }
# ifdef XMRIG_ALGO_RANDOMX
void allocateRandomX_VM();
# endif
bool verify(const Algorithm &algorithm, const uint8_t *referenceValue);
bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue);
void allocateCnCtx();
void consumeJob();
const Algorithm m_algorithm;
const Assembly m_assembly;
const bool m_hwAES;
const CnHash::AlgoVariant m_av;
const Miner *m_miner;
cryptonight_ctx *m_ctx[N];
uint8_t m_hash[N * 32];
VirtualMemory *m_memory = nullptr;
WorkerJob<N> m_job;
# ifdef XMRIG_ALGO_RANDOMX
RxVm *m_vm = nullptr;
# endif
};
template<>
bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue);
extern template class CpuWorker<1>;
extern template class CpuWorker<2>;
extern template class CpuWorker<3>;
extern template class CpuWorker<4>;
extern template class CpuWorker<5>;
} // namespace xmrig
#endif /* XMRIG_CPUWORKER_H */

37
src/backend/cpu/cpu.cmake Normal file
View File

@@ -0,0 +1,37 @@
set(HEADERS_BACKEND_CPU
src/backend/cpu/Cpu.h
src/backend/cpu/CpuBackend.h
src/backend/cpu/CpuConfig.h
src/backend/cpu/CpuLaunchData.cpp
src/backend/cpu/CpuThread.h
src/backend/cpu/CpuWorker.h
src/backend/cpu/interfaces/ICpuInfo.h
)
set(SOURCES_BACKEND_CPU
src/backend/cpu/Cpu.cpp
src/backend/cpu/CpuBackend.cpp
src/backend/cpu/CpuConfig.cpp
src/backend/cpu/CpuLaunchData.h
src/backend/cpu/CpuThread.cpp
src/backend/cpu/CpuWorker.cpp
)
if (WITH_LIBCPUID)
add_subdirectory(src/3rdparty/libcpuid)
include_directories(src/3rdparty/libcpuid)
add_definitions(/DXMRIG_FEATURE_LIBCPUID)
set(CPUID_LIB cpuid)
set(SOURCES_CPUID src/backend/cpu/platform/AdvancedCpuInfo.h src/backend/cpu/platform/AdvancedCpuInfo.cpp src/backend/cpu/Cpu.cpp)
else()
remove_definitions(/DXMRIG_FEATURE_LIBCPUID)
set(SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo.h src/backend/cpu/Cpu.cpp)
if (XMRIG_ARM)
set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo_arm.cpp)
else()
set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo.cpp)
endif()
endif()

View File

@@ -26,11 +26,9 @@
#define XMRIG_CPUINFO_H
#include <stddef.h>
#include <stdint.h>
#include "common/xmrig.h"
#include "backend/cpu/CpuThread.h"
#include "crypto/common/Assembly.h"
#include "crypto/common/Algorithm.h"
namespace xmrig {
@@ -39,21 +37,26 @@ namespace xmrig {
class ICpuInfo
{
public:
virtual ~ICpuInfo() {}
virtual ~ICpuInfo() = default;
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
inline constexpr static bool isX64() { return true; }
# else
inline constexpr static bool isX64() { return false; }
# endif
virtual Assembly::Id assembly() const = 0;
virtual bool hasAES() const = 0;
virtual bool hasAVX2() const = 0;
virtual bool isSupported() const = 0;
virtual bool isX64() const = 0;
virtual const char *brand() const = 0;
virtual int32_t cores() const = 0;
virtual int32_t L2() const = 0;
virtual int32_t L3() const = 0;
virtual int32_t nodes() const = 0;
virtual int32_t sockets() const = 0;
virtual int32_t threads() const = 0;
virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0;
virtual xmrig::Assembly assembly() const = 0;
virtual CpuThreads threads(const Algorithm &algorithm) const = 0;
virtual size_t cores() const = 0;
virtual size_t L2() const = 0;
virtual size_t L3() const = 0;
virtual size_t nodes() const = 0;
virtual size_t sockets() const = 0;
virtual size_t threads() const = 0;
};

View File

@@ -22,66 +22,57 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <assert.h>
#include <libcpuid.h>
#include <math.h>
#include <string.h>
#include "core/cpu/AdvancedCpuInfo.h"
#include "backend/cpu/platform/AdvancedCpuInfo.h"
xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
m_assembly(ASM_NONE),
m_aes(false),
m_avx2(false),
m_L2_exclusive(false),
m_brand(),
m_cores(0),
m_L2(0),
m_L3(0),
m_sockets(1),
m_threads(0)
m_brand()
{
struct cpu_raw_data_t raw = { 0 };
struct cpu_id_t data = { 0 };
struct cpu_raw_data_t raw = {};
struct cpu_id_t data = {};
cpuid_get_raw_data(&raw);
cpu_identify(&raw, &data);
strncpy(m_brand, data.brand_str, sizeof(m_brand));
m_threads = data.total_logical_cpus;
m_sockets = threads() / data.num_logical_cpus;
if (m_sockets == 0) {
m_sockets = 1;
}
m_threads = static_cast<size_t>(data.total_logical_cpus);
m_sockets = std::max<size_t>(threads() / static_cast<size_t>(data.num_logical_cpus), 1);
m_cores = static_cast<size_t>(data.num_cores) * m_sockets;
m_L3 = data.l3_cache > 0 ? static_cast<size_t>(data.l3_cache) * m_sockets : 0;
m_cores = data.num_cores * m_sockets;
m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0;
const size_t l2 = static_cast<size_t>(data.l2_cache);
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) {
m_L2 = data.l2_cache * (cores() / 2) * m_sockets;
m_L2 = l2 * (cores() / 2) * m_sockets;
m_L2_exclusive = true;
}
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue
// These processors have L2 cache shared by 2 cores.
else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) {
int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;
size_t l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
m_L2 = data.l2_cache > 0 ? l2 * l2_count_per_socket * m_sockets : 0;
}
else{
m_L2 = data.l2_cache > 0 ? data.l2_cache * cores() * m_sockets : 0;
m_L2 = data.l2_cache > 0 ? l2 * cores() * m_sockets : 0;
}
if (data.flags[CPU_FEATURE_AES]) {
m_aes = true;
if (data.vendor == VENDOR_AMD) {
m_assembly = (data.ext_family >= 23) ? ASM_RYZEN : ASM_BULLDOZER;
m_assembly = (data.ext_family >= 23) ? Assembly::RYZEN : Assembly::BULLDOZER;
}
else if (data.vendor == VENDOR_INTEL) {
m_assembly = ASM_INTEL;
m_assembly = Assembly::INTEL;
}
}
@@ -89,13 +80,21 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
}
size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) const
{
if (threads() == 1) {
return 1;
return CpuThreads(1);
}
# ifdef XMRIG_ALGO_CN_GPU
if (algorithm == Algorithm::CN_GPU) {
return CpuThreads(threads());
}
# endif
size_t cache = 0;
size_t count = 0;
if (m_L3) {
cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3;
}
@@ -103,12 +102,14 @@ size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsa
cache = m_L2;
}
size_t count = 0;
if (cache) {
count = cache / memSize;
cache *= 1024;
const size_t memory = algorithm.memory();
assert(memory > 0);
if (cache % memSize >= memSize / 2) {
count = cache / memory;
if (cache % memory >= memory / 2) {
count++;
}
}
@@ -116,13 +117,5 @@ size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsa
count = threads() / 2;
}
if (count > (size_t) threads()) {
count = threads();
}
if (((float) count / threads() * 100) > maxCpuUsage) {
count = (int) ceil((float) threads() * (maxCpuUsage / 100.0));
}
return count < 1 ? 1 : count;
return CpuThreads(std::max<size_t>(std::min<size_t>(count, threads()), 1));
}

View File

@@ -26,7 +26,7 @@
#define XMRIG_ADVANCEDCPUINFO_H
#include "common/interfaces/ICpuInfo.h"
#include "backend/cpu/interfaces/ICpuInfo.h"
namespace xmrig {
@@ -38,37 +38,31 @@ public:
AdvancedCpuInfo();
protected:
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
CpuThreads threads(const Algorithm &algorithm) const override;
inline Assembly assembly() const override { return m_assembly; }
inline Assembly::Id assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; }
inline bool hasAVX2() const override { return m_avx2; }
inline bool isSupported() const override { return true; }
inline const char *brand() const override { return m_brand; }
inline int32_t cores() const override { return m_cores; }
inline int32_t L2() const override { return m_L2; }
inline int32_t L3() const override { return m_L3; }
inline int32_t nodes() const override { return -1; }
inline int32_t sockets() const override { return m_sockets; }
inline int32_t threads() const override { return m_threads; }
# if defined(__x86_64__) || defined(_M_AMD64)
inline bool isX64() const override { return true; }
# else
inline bool isX64() const override { return false; }
# endif
inline size_t cores() const override { return m_cores; }
inline size_t L2() const override { return m_L2; }
inline size_t L3() const override { return m_L3; }
inline size_t nodes() const override { return 0; }
inline size_t sockets() const override { return m_sockets; }
inline size_t threads() const override { return m_threads; }
private:
Assembly m_assembly;
bool m_aes;
bool m_avx2;
bool m_L2_exclusive;
bool m_aes = false;
bool m_avx2 = false;
bool m_L2_exclusive = false;
char m_brand[64];
int32_t m_cores;
int32_t m_L2;
int32_t m_L3;
int32_t m_sockets;
int32_t m_threads;
size_t m_cores = 0;
size_t m_L2 = 0;
size_t m_L3 = 0;
size_t m_sockets = 1;
size_t m_threads = 0;
};

View File

@@ -22,6 +22,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <string.h>
#include <thread>
@@ -45,7 +46,8 @@
#endif
#include "common/cpu/BasicCpuInfo.h"
#include "backend/cpu/platform/BasicCpuInfo.h"
#include "crypto/common/Assembly.h"
#define VENDOR_ID (0)
@@ -121,15 +123,15 @@ static inline bool has_ossave()
xmrig::BasicCpuInfo::BasicCpuInfo() :
m_assembly(ASM_NONE),
m_assembly(Assembly::NONE),
m_aes(has_aes_ni()),
m_avx2(has_avx2() && has_ossave()),
m_brand(),
m_avx2(has_avx2() && has_ossave()),
m_threads(std::thread::hardware_concurrency())
{
cpu_brand_string(m_brand);
# ifndef XMRIG_NO_ASM
# ifdef XMRIG_FEATURE_ASM
if (hasAES()) {
char vendor[13] = { 0 };
int32_t data[4] = { 0 };
@@ -141,19 +143,35 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
memcpy(vendor + 8, &data[2], 4);
if (memcmp(vendor, "GenuineIntel", 12) == 0) {
m_assembly = ASM_INTEL;
m_assembly = Assembly::INTEL;
}
else if (memcmp(vendor, "AuthenticAMD", 12) == 0) {
m_assembly = ASM_RYZEN;
m_assembly = Assembly::RYZEN;
}
}
# endif
}
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const
{
const size_t count = threads() / 2;
if (threads() == 1) {
return CpuThreads(1);
}
return count < 1 ? 1 : count;
# ifdef XMRIG_ALGO_CN_GPU
if (algorithm == Algorithm::CN_GPU) {
return CpuThreads(threads());
}
# endif
if (algorithm.family() == Algorithm::CN_LITE || algorithm.family() == Algorithm::CN_PICO) {
return CpuThreads(threads());
}
if (algorithm.family() == Algorithm::CN_HEAVY) {
return CpuThreads(std::max<size_t>(threads() / 4, 1));
}
return CpuThreads(std::max<size_t>(threads() / 2, 1));
}

View File

@@ -26,7 +26,7 @@
#define XMRIG_BASICCPUINFO_H
#include "common/interfaces/ICpuInfo.h"
#include "backend/cpu/interfaces/ICpuInfo.h"
namespace xmrig {
@@ -38,32 +38,26 @@ public:
BasicCpuInfo();
protected:
size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override;
CpuThreads threads(const Algorithm &algorithm) const override;
inline Assembly assembly() const override { return m_assembly; }
inline Assembly::Id assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; }
inline bool hasAVX2() const override { return m_avx2; }
inline bool isSupported() const override { return true; }
inline const char *brand() const override { return m_brand; }
inline int32_t cores() const override { return -1; }
inline int32_t L2() const override { return -1; }
inline int32_t L3() const override { return -1; }
inline int32_t nodes() const override { return -1; }
inline int32_t sockets() const override { return 1; }
inline int32_t threads() const override { return m_threads; }
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
inline bool isX64() const override { return true; }
# else
inline bool isX64() const override { return false; }
# endif
inline size_t cores() const override { return 0; }
inline size_t L2() const override { return 0; }
inline size_t L3() const override { return 0; }
inline size_t nodes() const override { return 0; }
inline size_t sockets() const override { return 1; }
inline size_t threads() const override { return m_threads; }
private:
Assembly m_assembly;
bool m_aes;
bool m_avx2;
char m_brand[64];
int32_t m_threads;
char m_brand[64 + 6];
const bool m_avx2;
const size_t m_threads;
};

View File

@@ -25,19 +25,20 @@
#include <string.h>
#include <thread>
#if __ARM_FEATURE_CRYPTO
#if __ARM_FEATURE_CRYPTO && !defined(__APPLE__)
# include <sys/auxv.h>
# include <asm/hwcap.h>
#endif
#include "common/cpu/BasicCpuInfo.h"
#include "backend/cpu/platform/BasicCpuInfo.h"
xmrig::BasicCpuInfo::BasicCpuInfo() :
m_aes(false),
m_avx2(false),
m_brand(),
m_avx2(false),
m_threads(std::thread::hardware_concurrency())
{
# ifdef XMRIG_ARMv8
@@ -47,12 +48,16 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
# endif
# if __ARM_FEATURE_CRYPTO
# if !defined(__APPLE__)
m_aes = getauxval(AT_HWCAP) & HWCAP_AES;
# else
m_aes = true;
# endif
# endif
}
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const
{
return threads();
return CpuThreads(threads());
}

148
src/base/base.cmake Normal file
View File

@@ -0,0 +1,148 @@
set(HEADERS_BASE
src/base/io/Console.h
src/base/io/json/Json.h
src/base/io/json/JsonChain.h
src/base/io/json/JsonRequest.h
src/base/io/log/backends/ConsoleLog.h
src/base/io/log/backends/FileLog.h
src/base/io/log/Log.h
src/base/io/Watcher.h
src/base/kernel/Base.h
src/base/kernel/config/BaseConfig.h
src/base/kernel/config/BaseTransform.h
src/base/kernel/Entry.h
src/base/kernel/interfaces/IBaseListener.h
src/base/kernel/interfaces/IClient.h
src/base/kernel/interfaces/IClientListener.h
src/base/kernel/interfaces/IConfig.h
src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/IConfigTransform.h
src/base/kernel/interfaces/IConsoleListener.h
src/base/kernel/interfaces/IDnsListener.h
src/base/kernel/interfaces/ILineListener.h
src/base/kernel/interfaces/ILogBackend.h
src/base/kernel/interfaces/ISignalListener.h
src/base/kernel/interfaces/IStrategy.h
src/base/kernel/interfaces/IStrategyListener.h
src/base/kernel/interfaces/ITimerListener.h
src/base/kernel/interfaces/IWatcherListener.h
src/base/kernel/Platform.h
src/base/kernel/Process.h
src/base/kernel/Signals.h
src/base/net/dns/Dns.h
src/base/net/dns/DnsRecord.h
src/base/net/http/Http.h
src/base/net/stratum/BaseClient.h
src/base/net/stratum/Client.h
src/base/net/stratum/Job.h
src/base/net/stratum/Pool.h
src/base/net/stratum/Pools.h
src/base/net/stratum/strategies/FailoverStrategy.h
src/base/net/stratum/strategies/SinglePoolStrategy.h
src/base/net/stratum/SubmitResult.h
src/base/net/tools/RecvBuf.h
src/base/net/tools/Storage.h
src/base/tools/Arguments.h
src/base/tools/Baton.h
src/base/tools/Buffer.h
src/base/tools/Chrono.h
src/base/tools/Handle.h
src/base/tools/String.h
src/base/tools/Timer.h
)
set(SOURCES_BASE
src/base/io/Console.cpp
src/base/io/json/Json.cpp
src/base/io/json/JsonChain.cpp
src/base/io/json/JsonRequest.cpp
src/base/io/log/backends/ConsoleLog.cpp
src/base/io/log/backends/FileLog.cpp
src/base/io/log/Log.cpp
src/base/io/Watcher.cpp
src/base/kernel/Base.cpp
src/base/kernel/config/BaseConfig.cpp
src/base/kernel/config/BaseTransform.cpp
src/base/kernel/Entry.cpp
src/base/kernel/Platform.cpp
src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp
src/base/net/dns/Dns.cpp
src/base/net/dns/DnsRecord.cpp
src/base/net/http/Http.cpp
src/base/net/stratum/BaseClient.cpp
src/base/net/stratum/Client.cpp
src/base/net/stratum/Job.cpp
src/base/net/stratum/Pool.cpp
src/base/net/stratum/Pools.cpp
src/base/net/stratum/strategies/FailoverStrategy.cpp
src/base/net/stratum/strategies/SinglePoolStrategy.cpp
src/base/tools/Arguments.cpp
src/base/tools/Buffer.cpp
src/base/tools/String.cpp
src/base/tools/Timer.cpp
)
if (WIN32)
set(SOURCES_OS
src/base/io/json/Json_win.cpp
src/base/kernel/Platform_win.cpp
)
elseif (APPLE)
set(SOURCES_OS
src/base/io/json/Json_unix.cpp
src/base/kernel/Platform_mac.cpp
)
else()
set(SOURCES_OS
src/base/io/json/Json_unix.cpp
src/base/kernel//Platform_unix.cpp
)
endif()
if (NOT WIN32)
CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H)
if (HAVE_SYSLOG_H)
add_definitions(/DHAVE_SYSLOG_H)
set(SOURCES_SYSLOG src/base/io/log/backends/SysLog.h src/base/io/log/backends/SysLog.cpp)
endif()
endif()
if (WITH_HTTP)
set(HEADERS_BASE_HTTP
src/3rdparty/http-parser/http_parser.h
src/base/kernel/interfaces/IHttpListener.h
src/base/kernel/interfaces/IJsonReader.h
src/base/kernel/interfaces/ITcpServerListener.h
src/base/net/http/HttpApiResponse.h
src/base/net/http/HttpClient.h
src/base/net/http/HttpContext.h
src/base/net/http/HttpData.h
src/base/net/http/HttpResponse.h
src/base/net/http/HttpServer.h
src/base/net/stratum/DaemonClient.h
src/base/net/tools/TcpServer.h
)
set(SOURCES_BASE_HTTP
src/3rdparty/http-parser/http_parser.c
src/base/net/http/HttpApiResponse.cpp
src/base/net/http/HttpClient.cpp
src/base/net/http/HttpContext.cpp
src/base/net/http/HttpResponse.cpp
src/base/net/http/HttpServer.cpp
src/base/net/stratum/DaemonClient.cpp
src/base/net/tools/TcpServer.cpp
)
add_definitions(/DXMRIG_FEATURE_HTTP)
add_definitions(/DXMRIG_FEATURE_API)
else()
set(HEADERS_BASE_HTTP "")
set(SOURCES_BASE_HTTP "")
remove_definitions(/DXMRIG_FEATURE_HTTP)
remove_definitions(/DXMRIG_FEATURE_API)
endif()

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,26 +23,44 @@
*/
#include "common/Console.h"
#include "interfaces/IConsoleListener.h"
#include "base/io/Console.h"
#include "base/kernel/interfaces/IConsoleListener.h"
#include "base/tools/Handle.h"
Console::Console(IConsoleListener *listener)
xmrig::Console::Console(IConsoleListener *listener)
: m_listener(listener)
{
m_tty.data = this;
uv_tty_init(uv_default_loop(), &m_tty, 0, 1);
m_tty = new uv_tty_t;
if (!uv_is_readable(reinterpret_cast<uv_stream_t*>(&m_tty))) {
m_tty->data = this;
uv_tty_init(uv_default_loop(), m_tty, 0, 1);
if (!uv_is_readable(reinterpret_cast<uv_stream_t*>(m_tty))) {
return;
}
uv_tty_set_mode(&m_tty, UV_TTY_MODE_RAW);
uv_read_start(reinterpret_cast<uv_stream_t*>(&m_tty), Console::onAllocBuffer, Console::onRead);
uv_tty_set_mode(m_tty, UV_TTY_MODE_RAW);
uv_read_start(reinterpret_cast<uv_stream_t*>(m_tty), Console::onAllocBuffer, Console::onRead);
}
void Console::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
xmrig::Console::~Console()
{
stop();
}
void xmrig::Console::stop()
{
uv_tty_reset_mode();
Handle::close(m_tty);
m_tty = nullptr;
}
void xmrig::Console::onAllocBuffer(uv_handle_t *handle, size_t, uv_buf_t *buf)
{
auto console = static_cast<Console*>(handle->data);
buf->len = 1;
@@ -49,7 +68,7 @@ void Console::onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t
}
void Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
void xmrig::Console::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
{
if (nread < 0) {
return uv_close(reinterpret_cast<uv_handle_t*>(stream), nullptr);

View File

@@ -5,7 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,13 +22,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONSOLE_H__
#define __CONSOLE_H__
#ifndef XMRIG_CONSOLE_H
#define XMRIG_CONSOLE_H
#include <uv.h>
namespace xmrig {
class IConsoleListener;
@@ -35,6 +40,9 @@ class Console
{
public:
Console(IConsoleListener *listener);
~Console();
void stop();
private:
static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
@@ -42,8 +50,11 @@ private:
char m_buf[1];
IConsoleListener *m_listener;
uv_tty_t m_tty;
uv_tty_t *m_tty;
};
#endif /* __CONSOLE_H__ */
} /* namespace xmrig */
#endif /* XMRIG_CONSOLE_H */

View File

@@ -29,37 +29,31 @@
#include "base/kernel/interfaces/IWatcherListener.h"
#include "base/io/Watcher.h"
#include "base/tools/Handle.h"
#include "base/tools/Timer.h"
xmrig::Watcher::Watcher(const String &path, IWatcherListener *listener) :
m_listener(listener),
m_path(path)
{
m_timer = new Timer(this);
m_fsEvent = new uv_fs_event_t;
m_fsEvent->data = this;
uv_fs_event_init(uv_default_loop(), m_fsEvent);
m_timer = new uv_timer_t;
uv_timer_init(uv_default_loop(), m_timer);
m_fsEvent->data = m_timer->data = this;
start();
}
xmrig::Watcher::~Watcher()
{
Handle::close(m_timer);
delete m_timer;
Handle::close(m_fsEvent);
}
void xmrig::Watcher::onTimer(uv_timer_t *handle)
{
static_cast<Watcher *>(handle->data)->reload();
}
void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int, int)
{
if (!filename) {
@@ -72,8 +66,8 @@ void xmrig::Watcher::onFsEvent(uv_fs_event_t *handle, const char *filename, int,
void xmrig::Watcher::queueUpdate()
{
uv_timer_stop(m_timer);
uv_timer_start(m_timer, xmrig::Watcher::onTimer, kDelay, 0);
m_timer->stop();
m_timer->start(kDelay, 0);
}

View File

@@ -26,30 +26,33 @@
#define XMRIG_WATCHER_H
#include "base/kernel/interfaces/ITimerListener.h"
#include "base/tools/String.h"
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_timer_s uv_timer_t;
namespace xmrig {
class IWatcherListener;
class Timer;
class Watcher
class Watcher : public ITimerListener
{
public:
Watcher(const String &path, IWatcherListener *listener);
~Watcher();
~Watcher() override;
protected:
inline void onTimer(const Timer *) override { reload(); }
private:
constexpr static int kDelay = 500;
static void onFsEvent(uv_fs_event_t *handle, const char *filename, int events, int status);
static void onTimer(uv_timer_t *handle);
void queueUpdate();
void reload();
@@ -57,11 +60,12 @@ private:
IWatcherListener *m_listener;
String m_path;
Timer *m_timer;
uv_fs_event_t *m_fsEvent;
uv_timer_t *m_timer;
};
} /* namespace xmrig */
#endif /* XMRIG_WATCHER_H */

View File

@@ -23,10 +23,17 @@
*/
#include "base/io/Json.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
namespace xmrig {
static const rapidjson::Value kNullValue;
}
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
{
auto i = obj.FindMember(key);
@@ -49,6 +56,39 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
}
const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsArray()) {
return i->value;
}
return kNullValue;
}
const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsObject()) {
return i->value;
}
return kNullValue;
}
const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd()) {
return i->value;
}
return kNullValue;
}
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
{
auto i = obj.FindMember(key);
@@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi
return defaultValue;
}
bool xmrig::JsonReader::isEmpty() const
{
return !m_obj.IsObject() || m_obj.ObjectEmpty();
}

79
src/base/io/json/Json.h Normal file
View File

@@ -0,0 +1,79 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSON_H
#define XMRIG_JSON_H
#include "base/kernel/interfaces/IJsonReader.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Json
{
public:
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
static const rapidjson::Value &getArray(const rapidjson::Value &obj, const char *key);
static const rapidjson::Value &getObject(const rapidjson::Value &obj, const char *key);
static const rapidjson::Value &getValue(const rapidjson::Value &obj, const char *key);
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
static bool get(const char *fileName, rapidjson::Document &doc);
static bool save(const char *fileName, const rapidjson::Document &doc);
};
class JsonReader : public IJsonReader
{
public:
inline JsonReader(const rapidjson::Value &obj) : m_obj(obj) {}
inline bool getBool(const char *key, bool defaultValue = false) const override { return Json::getBool(m_obj, key, defaultValue); }
inline const char *getString(const char *key, const char *defaultValue = nullptr) const override { return Json::getString(m_obj, key, defaultValue); }
inline const rapidjson::Value &getArray(const char *key) const override { return Json::getArray(m_obj, key); }
inline const rapidjson::Value &getObject(const char *key) const override { return Json::getObject(m_obj, key); }
inline const rapidjson::Value &getValue(const char *key) const override { return Json::getValue(m_obj, key); }
inline int getInt(const char *key, int defaultValue = 0) const override { return Json::getInt(m_obj, key, defaultValue); }
inline int64_t getInt64(const char *key, int64_t defaultValue = 0) const override { return Json::getInt64(m_obj, key, defaultValue); }
inline uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override { return Json::getUint64(m_obj, key, defaultValue); }
inline unsigned getUint(const char *key, unsigned defaultValue = 0) const override { return Json::getUint(m_obj, key, defaultValue); }
bool isEmpty() const override;
private:
const rapidjson::Value &m_obj;
};
} /* namespace xmrig */
#endif /* XMRIG_JSON_H */

View File

@@ -0,0 +1,213 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/io/json/Json.h"
#include "base/io/json/JsonChain.h"
#include "base/io/log/Log.h"
#include "rapidjson/error/en.h"
namespace xmrig {
static const rapidjson::Value kNullValue;
}
xmrig::JsonChain::JsonChain()
{
}
bool xmrig::JsonChain::add(rapidjson::Document &&doc)
{
if (doc.HasParseError() || !doc.IsObject() || doc.ObjectEmpty()) {
return false;
}
m_chain.push_back(std::move(doc));
return true;
}
bool xmrig::JsonChain::addFile(const char *fileName)
{
using namespace rapidjson;
Document doc;
if (Json::get(fileName, doc)) {
m_fileName = fileName;
return add(std::move(doc));
}
if (doc.HasParseError()) {
LOG_ERR("%s<offset:%zu>: \"%s\"", fileName, doc.GetErrorOffset(), GetParseError_En(doc.GetParseError()));
}
else {
LOG_ERR("unable to open \"%s\".", fileName);
}
return false;
}
bool xmrig::JsonChain::addRaw(const char *json)
{
using namespace rapidjson;
Document doc;
doc.Parse<kParseCommentsFlag | kParseTrailingCommasFlag>(json);
return add(std::move(doc));
}
void xmrig::JsonChain::dump(const char *fileName)
{
rapidjson::Document doc(rapidjson::kArrayType);
for (rapidjson::Document &value : m_chain) {
doc.PushBack(value, doc.GetAllocator());
}
Json::save(fileName, doc);
}
bool xmrig::JsonChain::getBool(const char *key, bool defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsBool()) {
return i->value.GetBool();
}
}
return defaultValue;
}
const char *xmrig::JsonChain::getString(const char *key, const char *defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsString()) {
return i->value.GetString();
}
}
return defaultValue;
}
const rapidjson::Value &xmrig::JsonChain::getArray(const char *key) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsArray()) {
return i->value;
}
}
return kNullValue;
}
const rapidjson::Value &xmrig::JsonChain::getObject(const char *key) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsObject()) {
return i->value;
}
}
return kNullValue;
}
const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd()) {
return i->value;
}
}
return kNullValue;
}
int xmrig::JsonChain::getInt(const char *key, int defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsInt()) {
return i->value.GetInt();
}
}
return defaultValue;
}
int64_t xmrig::JsonChain::getInt64(const char *key, int64_t defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsInt64()) {
return i->value.GetInt64();
}
}
return defaultValue;
}
uint64_t xmrig::JsonChain::getUint64(const char *key, uint64_t defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsUint64()) {
return i->value.GetUint64();
}
}
return defaultValue;
}
unsigned xmrig::JsonChain::getUint(const char *key, unsigned defaultValue) const
{
for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) {
auto i = it->FindMember(key);
if (i != it->MemberEnd() && i->value.IsUint()) {
return i->value.GetUint();
}
}
return defaultValue;
}

View File

@@ -0,0 +1,76 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSONCHAIN_H
#define XMRIG_JSONCHAIN_H
#include <vector>
#include "base/kernel/interfaces/IJsonReader.h"
#include "base/tools/String.h"
#include "rapidjson/document.h"
namespace xmrig {
class JsonChain : public IJsonReader
{
public:
JsonChain();
bool add(rapidjson::Document &&doc);
bool addFile(const char *fileName);
bool addRaw(const char *json);
void dump(const char *fileName);
inline const String &fileName() const { return m_fileName; }
inline size_t size() const { return m_chain.size(); }
protected:
inline bool isEmpty() const override { return m_chain.empty(); }
bool getBool(const char *key, bool defaultValue = false) const override;
const char *getString(const char *key, const char *defaultValue = nullptr) const override;
const rapidjson::Value &getArray(const char *key) const override;
const rapidjson::Value &getObject(const char *key) const override;
const rapidjson::Value &getValue(const char *key) const override;
int getInt(const char *key, int defaultValue = 0) const override;
int64_t getInt64(const char *key, int64_t defaultValue = 0) const override;
uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override;
unsigned getUint(const char *key, unsigned defaultValue = 0) const override;
private:
std::vector<rapidjson::Document> m_chain;
String m_fileName;
};
} /* namespace xmrig */
#endif /* XMRIG_JSONCHAIN_H */

View File

@@ -0,0 +1,38 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/io/json/JsonRequest.h"
#include "rapidjson/document.h"
void xmrig::JsonRequest::create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params)
{
auto &allocator = doc.GetAllocator();
doc.AddMember("id", id, allocator);
doc.AddMember("jsonrpc", "2.0", allocator);
doc.AddMember("method", rapidjson::StringRef(method), allocator);
doc.AddMember("params", params, allocator);
}

View File

@@ -0,0 +1,45 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSONREQUEST_H
#define XMRIG_JSONREQUEST_H
#include "rapidjson/fwd.h"
namespace xmrig {
class JsonRequest
{
public:
static void create(rapidjson::Document &doc, int64_t id, const char *method, rapidjson::Value &params);
};
} /* namespace xmrig */
#endif /* XMRIG_JSONREQUEST_H */

View File

@@ -26,7 +26,7 @@
#include <fstream>
#include "base/io/Json.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/ostreamwrapper.h"

View File

@@ -35,7 +35,7 @@
#include <fstream>
#include "base/io/Json.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/ostreamwrapper.h"
@@ -102,7 +102,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
return false;
}
# elif defined(__GNUC__)
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_TRUNC);
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC);
if (fd == -1) {
return false;
}

250
src/base/io/log/Log.cpp Normal file
View File

@@ -0,0 +1,250 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include <algorithm>
#include <string.h>
#include <string>
#include <time.h>
#include <uv.h>
#include <vector>
#include "base/io/log/Log.h"
#include "base/kernel/interfaces/ILogBackend.h"
#include "base/tools/Chrono.h"
namespace xmrig {
static const char *colors_map[] = {
RED_BOLD_S, // EMERG
RED_BOLD_S, // ALERT
RED_BOLD_S, // CRIT
RED_S, // ERR
YELLOW_S, // WARNING
WHITE_BOLD_S, // NOTICE
nullptr, // INFO
# ifdef WIN32
BLACK_BOLD_S // DEBUG
# else
BRIGHT_BLACK_S // DEBUG
# endif
};
class LogPrivate
{
public:
inline LogPrivate() :
m_buf()
{
uv_mutex_init(&m_mutex);
}
inline ~LogPrivate()
{
uv_mutex_destroy(&m_mutex);
for (ILogBackend *backend : m_backends) {
delete backend;
}
}
inline void add(ILogBackend *backend) { m_backends.push_back(backend); }
void print(Log::Level level, const char *fmt, va_list args)
{
size_t size = 0;
size_t offset = 0;
lock();
timestamp(level, size, offset);
color(level, size);
const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args);
if (rc < 0) {
return unlock();
}
size += std::min(static_cast<size_t>(rc), sizeof (m_buf) - offset - 32);
endl(size);
std::string txt(m_buf);
size_t i;
while ((i = txt.find(CSI)) != std::string::npos) {
txt.erase(i, txt.find('m', i) - i + 1);
}
if (!m_backends.empty()) {
for (ILogBackend *backend : m_backends) {
backend->print(level, m_buf, offset, size, true);
backend->print(level, txt.c_str(), offset, txt.size(), false);
}
}
else {
fputs(txt.c_str(), stdout);
fflush(stdout);
}
unlock();
}
private:
inline void lock() { uv_mutex_lock(&m_mutex); }
inline void unlock() { uv_mutex_unlock(&m_mutex); }
inline void timestamp(Log::Level level, size_t &size, size_t &offset)
{
if (level == Log::NONE) {
return;
}
const uint64_t ms = Chrono::currentMSecsSinceEpoch();
time_t now = ms / 1000;
tm stime;
# ifdef _WIN32
localtime_s(&stime, &now);
# else
localtime_r(&now, &stime);
# endif
const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
static_cast<int>(ms % 1000)
);
if (rc > 0) {
size = offset = static_cast<size_t>(rc);
}
}
inline void color(Log::Level level, size_t &size)
{
if (level == Log::NONE) {
return;
}
const char *color = colors_map[level];
if (color == nullptr) {
return;
}
const size_t s = strlen(color);
memcpy(m_buf + size, color, s);
size += s;
}
inline void endl(size_t &size)
{
# ifdef _WIN32
memcpy(m_buf + size, CLEAR "\r\n", 7);
size += 6;
# else
memcpy(m_buf + size, CLEAR "\n", 6);
size += 5;
# endif
}
char m_buf[4096];
std::vector<ILogBackend*> m_backends;
uv_mutex_t m_mutex;
};
bool Log::colors = true;
LogPrivate *Log::d = new LogPrivate();
} /* namespace xmrig */
void xmrig::Log::add(ILogBackend *backend)
{
if (d) {
d->add(backend);
}
}
void xmrig::Log::destroy()
{
delete d;
d = nullptr;
}
void xmrig::Log::print(const char *fmt, ...)
{
if (!d) {
return;
}
va_list args;
va_start(args, fmt);
d->print(NONE, fmt, args);
va_end(args);
}
void xmrig::Log::print(Level level, const char *fmt, ...)
{
if (!d) {
return;
}
va_list args;
va_start(args, fmt);
d->print(level, fmt, args);
va_end(args);
}

139
src/base/io/log/Log.h Normal file
View File

@@ -0,0 +1,139 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_LOG_H
#define XMRIG_LOG_H
namespace xmrig {
class ILogBackend;
class LogPrivate;
class Log
{
public:
enum Level : int {
NONE = -1,
EMERG, // system is unusable
ALERT, // action must be taken immediately
CRIT, // critical conditions
ERR, // error conditions
WARNING, // warning conditions
NOTICE, // normal but significant condition
INFO, // informational
DEBUG, // debug-level messages
};
static void add(ILogBackend *backend);
static void destroy();
static void print(const char *fmt, ...);
static void print(Level level, const char *fmt, ...);
static bool colors;
private:
static LogPrivate *d;
};
#define CSI "\x1B[" // Control Sequence Introducer (ANSI spec name)
#define CLEAR CSI "0m" // all attributes off
#define BRIGHT_BLACK_S CSI "0;90m" // somewhat MD.GRAY
#define BLACK_S CSI "0;30m"
#define BLACK_BOLD_S CSI "1;30m" // another name for GRAY
#define RED_S CSI "0;31m"
#define RED_BOLD_S CSI "1;31m"
#define GREEN_S CSI "0;32m"
#define GREEN_BOLD_S CSI "1;32m"
#define YELLOW_S CSI "0;33m"
#define YELLOW_BOLD_S CSI "1;33m"
#define BLUE_S CSI "0;34m"
#define BLUE_BOLD_S CSI "1;34m"
#define MAGENTA_S CSI "0;35m"
#define MAGENTA_BOLD_S CSI "1;35m"
#define CYAN_S CSI "0;36m"
#define CYAN_BOLD_S CSI "1;36m"
#define WHITE_S CSI "0;37m" // another name for LT.GRAY
#define WHITE_BOLD_S CSI "1;37m" // actually white
#define BLUE_BG_S CSI "44m"
#define BLUE_BG_BOLD_S CSI "44;1m"
#define MAGENTA_BG_S CSI "45m"
#define MAGENTA_BG_BOLD_S CSI "45;1m"
//color wrappings
#define BLACK(x) BLACK_S x CLEAR
#define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR
#define RED(x) RED_S x CLEAR
#define RED_BOLD(x) RED_BOLD_S x CLEAR
#define GREEN(x) GREEN_S x CLEAR
#define GREEN_BOLD(x) GREEN_BOLD_S x CLEAR
#define YELLOW(x) YELLOW_S x CLEAR
#define YELLOW_BOLD(x) YELLOW_BOLD_S x CLEAR
#define BLUE(x) BLUE_S x CLEAR
#define BLUE_BOLD(x) BLUE_BOLD_S x CLEAR
#define MAGENTA(x) MAGENTA_S x CLEAR
#define MAGENTA_BOLD(x) MAGENTA_BOLD_S x CLEAR
#define CYAN(x) CYAN_S x CLEAR
#define CYAN_BOLD(x) CYAN_BOLD_S x CLEAR
#define WHITE(x) WHITE_S x CLEAR
#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR
#define BLUE_BG(x) BLUE_BG_S x CLEAR
#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR
#define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR
#define MAGENTA_BG_BOLD(x) MAGENTA_BG_BOLD_S x CLEAR
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
#define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__)
#define LOG_CRIT(x, ...) xmrig::Log::print(xmrig::Log::CRIT, x, ##__VA_ARGS__)
#define LOG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
#define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__)
#define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__)
#ifdef APP_DEBUG
# define LOG_DEBUG(x, ...) xmrig::Log::print(xmrig::Log::DEBUG, x, ##__VA_ARGS__)
#else
# define LOG_DEBUG(x, ...)
#endif
#if defined(APP_DEBUG) || defined(APP_DEVEL)
# define LOG_DEBUG_ERR(x, ...) xmrig::Log::print(xmrig::Log::ERR, x, ##__VA_ARGS__)
# define LOG_DEBUG_WARN(x, ...) xmrig::Log::print(xmrig::Log::WARNING, x, ##__VA_ARGS__)
#else
# define LOG_DEBUG_ERR(x, ...)
# define LOG_DEBUG_WARN(x, ...)
#endif
} /* namespace xmrig */
#endif /* XMRIG_LOG_H */

View File

@@ -5,7 +5,9 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,36 +24,26 @@
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
# include <winsock2.h>
# include <windows.h>
#endif
#include "common/log/ConsoleLog.h"
#include "common/log/Log.h"
#include "core/Config.h"
#include "core/Controller.h"
#include "base/tools/Handle.h"
#include "base/io/log/backends/ConsoleLog.h"
#include "base/io/log/Log.h"
ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
m_stream(nullptr),
m_controller(controller)
xmrig::ConsoleLog::ConsoleLog() :
m_stream(nullptr)
{
if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) {
m_tty = new uv_tty_t;
if (uv_tty_init(uv_default_loop(), m_tty, 1, 0) < 0) {
Log::colors = false;
return;
}
uv_tty_set_mode(&m_tty, UV_TTY_MODE_NORMAL);
m_uvBuf.base = m_buf;
m_stream = reinterpret_cast<uv_stream_t*>(&m_tty);
uv_tty_set_mode(m_tty, UV_TTY_MODE_NORMAL);
m_stream = reinterpret_cast<uv_stream_t*>(m_tty);
# ifdef WIN32
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
@@ -66,44 +58,35 @@ ConsoleLog::ConsoleLog(xmrig::Controller *controller) :
}
void ConsoleLog::message(Level level, const char* fmt, va_list args)
xmrig::ConsoleLog::~ConsoleLog()
{
time_t now = time(nullptr);
tm stime;
Handle::close(m_tty);
}
void xmrig::ConsoleLog::print(int, const char *line, size_t, size_t size, bool colors)
{
if (Log::colors != colors) {
return;
}
# ifdef _WIN32
localtime_s(&stime, &now);
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), static_cast<unsigned int>(size));
# else
localtime_r(&now, &stime);
uv_buf_t buf = uv_buf_init(const_cast<char *>(line), size);
# endif
const bool isColors = m_controller->config()->isColors();
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
Log::colorByLevel(level, isColors),
fmt,
Log::endl(isColors)
);
print(args);
if (!isWritable()) {
fputs(line, stdout);
fflush(stdout);
}
else {
uv_try_write(m_stream, &buf, 1);
}
}
void ConsoleLog::text(const char* fmt, va_list args)
{
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s", fmt, Log::endl(m_controller->config()->isColors()));
print(args);
}
bool ConsoleLog::isWritable() const
bool xmrig::ConsoleLog::isWritable() const
{
if (!m_stream || uv_is_writable(m_stream) != 1) {
return false;
@@ -112,20 +95,3 @@ bool ConsoleLog::isWritable() const
const uv_handle_type type = uv_guess_handle(1);
return type == UV_TTY || type == UV_NAMED_PIPE;
}
void ConsoleLog::print(va_list args)
{
m_uvBuf.len = vsnprintf(m_buf, sizeof(m_buf) - 1, m_fmt, args);
if (m_uvBuf.len <= 0) {
return;
}
if (!isWritable()) {
fputs(m_buf, stdout);
fflush(stdout);
}
else {
uv_try_write(m_stream, &m_uvBuf, 1);
}
}

View File

@@ -0,0 +1,60 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CONSOLELOG_H
#define XMRIG_CONSOLELOG_H
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tty_s uv_tty_t;
#include "base/kernel/interfaces/ILogBackend.h"
namespace xmrig {
class ConsoleLog : public ILogBackend
{
public:
ConsoleLog();
~ConsoleLog() override;
protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
private:
bool isWritable() const;
uv_stream_t *m_stream;
uv_tty_t *m_tty;
};
} /* namespace xmrig */
#endif /* XMRIG_CONSOLELOG_H */

View File

@@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
@@ -23,42 +24,44 @@
*/
#include "base/io/Watcher.h"
#include "base/kernel/interfaces/IConfigListener.h"
#include "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h"
#include "common/log/Log.h"
#include "core/ConfigCreator.h"
#include <string.h>
#include <uv.h>
xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigCreator *creator, IConfigListener *listener) :
m_creator(creator),
m_listener(listener)
#include "base/io/log/backends/FileLog.h"
xmrig::FileLog::FileLog(const char *fileName)
{
m_watcher = new Watcher(path, this);
uv_fs_t req;
m_file = uv_fs_open(uv_default_loop(), &req, fileName, O_CREAT | O_APPEND | O_WRONLY, 0644, nullptr);
uv_fs_req_cleanup(&req);
}
xmrig::ConfigWatcher::~ConfigWatcher()
void xmrig::FileLog::print(int, const char *line, size_t, size_t size, bool colors)
{
delete m_watcher;
}
void xmrig::ConfigWatcher::onFileChanged(const String &fileName)
{
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
IConfig *config = m_creator->create();
ConfigLoader::loadFromFile(config, fileName);
if (!config->finalize()) {
LOG_ERR("reloading failed");
delete config;
if (m_file < 0 || colors) {
return;
}
m_listener->onNewConfig(config);
# ifdef _WIN32
uv_buf_t buf = uv_buf_init(strdup(line), static_cast<unsigned int>(size));
# else
uv_buf_t buf = uv_buf_init(strdup(line), size);
# endif
uv_fs_t *req = new uv_fs_t;
req->data = buf.base;
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, -1, FileLog::onWrite);
}
void xmrig::FileLog::onWrite(uv_fs_t *req)
{
delete [] static_cast<char *>(req->data);
uv_fs_req_cleanup(req);
delete req;
}

View File

@@ -5,6 +5,7 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
@@ -22,36 +23,36 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_SUBMITRESULT_H
#define XMRIG_SUBMITRESULT_H
#ifndef XMRIG_FILELOG_H
#define XMRIG_FILELOG_H
#include <uv.h>
typedef struct uv_fs_s uv_fs_t;
#include "base/kernel/interfaces/ILogBackend.h"
namespace xmrig {
class SubmitResult
class FileLog : public ILogBackend
{
public:
inline SubmitResult() : reqId(0), seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {}
SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0);
FileLog(const char *fileName);
void done();
int64_t reqId;
int64_t seq;
uint32_t diff;
uint64_t actualDiff;
uint64_t elapsed;
protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
private:
uint64_t start;
static void onWrite(uv_fs_t *req);
int m_file;
};
} /* namespace xmrig */
#endif /* XMRIG_SUBMITRESULT_H */
#endif /* XMRIG_FILELOG_H */

View File

@@ -0,0 +1,53 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <syslog.h>
#include "base/io/log/backends/SysLog.h"
#include "version.h"
xmrig::SysLog::SysLog()
{
openlog(APP_ID, LOG_PID, LOG_USER);
}
xmrig::SysLog::~SysLog()
{
closelog();
}
void xmrig::SysLog::print(int level, const char *line, size_t offset, size_t, bool colors)
{
if (colors) {
return;
}
syslog(level == -1 ? LOG_INFO : level, "%s", line + offset);
}

View File

@@ -0,0 +1,50 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_SYSLOG_H
#define XMRIG_SYSLOG_H
#include "base/kernel/interfaces/ILogBackend.h"
namespace xmrig {
class SysLog : public ILogBackend
{
public:
SysLog();
~SysLog();
protected:
void print(int level, const char *line, size_t offset, size_t size, bool colors) override;
};
} /* namespace xmrig */
#endif /* XMRIG_SYSLOG_H */

320
src/base/kernel/Base.cpp Normal file
View File

@@ -0,0 +1,320 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <memory>
#include "base/io/json/Json.h"
#include "base/io/json/JsonChain.h"
#include "base/io/log/backends/ConsoleLog.h"
#include "base/io/log/backends/FileLog.h"
#include "base/io/log/Log.h"
#include "base/io/Watcher.h"
#include "base/kernel/Base.h"
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/kernel/Platform.h"
#include "base/kernel/Process.h"
#include "core/config/Config.h"
#include "core/config/ConfigTransform.h"
#ifdef HAVE_SYSLOG_H
# include "base/io/log/backends/SysLog.h"
#endif
#ifdef XMRIG_FEATURE_API
# include "api/Api.h"
# include "api/interfaces/IApiRequest.h"
#endif
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
# include "core/config/Config_default.h"
#endif
class xmrig::BasePrivate
{
public:
inline BasePrivate(Process *process) :
api(nullptr),
config(nullptr),
process(process),
watcher(nullptr)
{}
inline ~BasePrivate()
{
# ifdef XMRIG_FEATURE_API
delete api;
# endif
delete config;
delete watcher;
}
inline bool read(const JsonChain &chain, std::unique_ptr<Config> &config)
{
config = std::unique_ptr<Config>(new Config());
return config->read(chain, chain.fileName());
}
inline Config *load()
{
JsonChain chain;
ConfigTransform transform;
std::unique_ptr<Config> config;
transform.load(chain, process, transform);
if (read(chain, config)) {
return config.release();
}
chain.addFile(process->location(Process::ExeLocation, "config.json"));
if (read(chain, config)) {
return config.release();
}
# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
chain.addRaw(default_config);
if (read(chain, config)) {
return config.release();
}
# endif
return nullptr;
}
inline void replace(Config *newConfig)
{
Config *previousConfig = config;
config = newConfig;
for (IBaseListener *listener : listeners) {
listener->onConfigChanged(config, previousConfig);
}
delete previousConfig;
}
Api *api;
Config *config;
Process *process;
std::vector<IBaseListener *> listeners;
Watcher *watcher;
};
xmrig::Base::Base(Process *process)
: d_ptr(new BasePrivate(process))
{
}
xmrig::Base::~Base()
{
delete d_ptr;
}
bool xmrig::Base::isReady() const
{
return d_ptr->config != nullptr;
}
int xmrig::Base::init()
{
d_ptr->config = d_ptr->load();
if (!d_ptr->config) {
LOG_EMERG("No valid configuration found. Exiting.");
return 1;
}
# ifdef XMRIG_FEATURE_API
d_ptr->api = new Api(this);
d_ptr->api->addListener(this);
# endif
Platform::init(config()->userAgent());
# ifndef XMRIG_PROXY_PROJECT
Platform::setProcessPriority(config()->cpu().priority());
# endif
if (!config()->isBackground()) {
Log::add(new ConsoleLog());
}
if (config()->logFile()) {
Log::add(new FileLog(config()->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (config()->isSyslog()) {
Log::add(new SysLog());
}
# endif
return 0;
}
void xmrig::Base::start()
{
# ifdef XMRIG_FEATURE_API
api()->start();
# endif
if (config()->isShouldSave()) {
config()->save();
}
if (config()->isWatch()) {
d_ptr->watcher = new Watcher(config()->fileName(), this);
}
}
void xmrig::Base::stop()
{
# ifdef XMRIG_FEATURE_API
api()->stop();
# endif
delete d_ptr->watcher;
d_ptr->watcher = nullptr;
}
xmrig::Api *xmrig::Base::api() const
{
assert(d_ptr->api != nullptr);
return d_ptr->api;
}
bool xmrig::Base::reload(const rapidjson::Value &json)
{
JsonReader reader(json);
if (reader.isEmpty()) {
return false;
}
Config *config = new Config();
if (!config->read(reader, d_ptr->config->fileName())) {
delete config;
return false;
}
const bool saved = config->save();
if (config->isWatch() && d_ptr->watcher && saved) {
delete config;
return true;
}
d_ptr->replace(config);
return true;
}
xmrig::Config *xmrig::Base::config() const
{
assert(d_ptr->config != nullptr);
return d_ptr->config;
}
void xmrig::Base::addListener(IBaseListener *listener)
{
d_ptr->listeners.push_back(listener);
}
void xmrig::Base::onFileChanged(const String &fileName)
{
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
JsonChain chain;
chain.addFile(fileName);
Config *config = new Config();
if (!config->read(chain, chain.fileName())) {
LOG_ERR("reloading failed");
delete config;
return;
}
d_ptr->replace(config);
}
#ifdef XMRIG_FEATURE_API
void xmrig::Base::onRequest(IApiRequest &request)
{
if (request.method() == IApiRequest::METHOD_GET) {
if (request.url() == "/1/config") {
if (request.isRestricted()) {
return request.done(403);
}
request.accept();
config()->getJSON(request.doc());
}
}
else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) {
if (request.url() == "/1/config") {
request.accept();
if (!reload(request.json())) {
return request.done(400);
}
request.done(204);
}
}
}
#endif

View File

@@ -22,32 +22,55 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSON_H
#define XMRIG_JSON_H
#ifndef XMRIG_BASE_H
#define XMRIG_BASE_H
#include "api/interfaces/IApiListener.h"
#include "base/kernel/interfaces/IConfigListener.h"
#include "base/kernel/interfaces/IWatcherListener.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Json
class Api;
class BasePrivate;
class Config;
class IBaseListener;
class Process;
class Base : public IWatcherListener, public IApiListener
{
public:
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
static unsigned getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue = 0);
Base(Process *process);
~Base() override;
static bool get(const char *fileName, rapidjson::Document &doc);
static bool save(const char *fileName, const rapidjson::Document &doc);
virtual bool isReady() const;
virtual int init();
virtual void start();
virtual void stop();
Api *api() const;
bool reload(const rapidjson::Value &json);
Config *config() const;
void addListener(IBaseListener *listener);
protected:
void onFileChanged(const String &fileName) override;
# ifdef XMRIG_FEATURE_API
void onRequest(IApiRequest &request) override;
# endif
private:
BasePrivate *d_ptr;
};
} /* namespace xmrig */
#endif /* XMRIG_JSON_H */
#endif /* XMRIG_BASE_H */

View File

@@ -27,19 +27,14 @@
#include <uv.h>
#ifndef XMRIG_NO_HTTPD
# include <microhttpd.h>
#endif
#ifndef XMRIG_NO_TLS
#ifdef XMRIG_FEATURE_TLS
# include <openssl/opensslv.h>
#endif
#include "base/kernel/Entry.h"
#include "base/kernel/Process.h"
#include "core/usage.h"
#include "core/config/usage.h"
#include "version.h"
@@ -73,11 +68,7 @@ static int showVersion()
printf("\nlibuv/%s\n", uv_version_string());
# ifndef XMRIG_NO_HTTPD
printf("microhttpd/%s\n", MHD_get_version());
# endif
# if !defined(XMRIG_NO_TLS) && defined(OPENSSL_VERSION_TEXT)
# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT)
{
constexpr const char *v = OPENSSL_VERSION_TEXT + 8;
printf("OpenSSL/%.*s\n", static_cast<int>(strchr(v, ' ') - v), v);

View File

@@ -27,7 +27,7 @@
#include <uv.h>
#ifndef XMRIG_NO_TLS
#ifdef XMRIG_FEATURE_TLS
# include <openssl/ssl.h>
# include <openssl/err.h>
#endif
@@ -41,7 +41,7 @@ xmrig::String Platform::m_userAgent;
void Platform::init(const char *userAgent)
{
# ifndef XMRIG_NO_TLS
# ifdef XMRIG_FEATURE_TLS
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();

View File

@@ -35,6 +35,15 @@
class Platform
{
public:
static inline bool trySetThreadAffinity(int64_t cpu_id)
{
if (cpu_id < 0) {
return false;
}
return setThreadAffinity(static_cast<uint64_t>(cpu_id));
}
static bool setThreadAffinity(uint64_t cpu_id);
static uint32_t setTimerResolution(uint32_t resolution);
static void init(const char *userAgent);

View File

@@ -29,7 +29,7 @@
#include <uv.h>
#include "log/Log.h"
#include "base/io/log/Log.h"
#include "Platform.h"
#include "version.h"

View File

@@ -28,6 +28,7 @@
#include "base/kernel/Process.h"
#include "base/tools/Chrono.h"
static size_t location(xmrig::Process::Location location, char *buf, size_t max)
@@ -50,7 +51,7 @@ static size_t location(xmrig::Process::Location location, char *buf, size_t max)
xmrig::Process::Process(int argc, char **argv) :
m_arguments(argc, argv)
{
srand(static_cast<unsigned int>(static_cast<uintptr_t>(time(nullptr)) ^ reinterpret_cast<uintptr_t>(this)));
srand(static_cast<unsigned int>(Chrono::currentMSecsSinceEpoch() ^ reinterpret_cast<uintptr_t>(this)));
}

View File

@@ -5,8 +5,8 @@
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -44,20 +44,31 @@ xmrig::Signals::Signals(ISignalListener *listener)
m_signals[i] = signal;
uv_signal_init(uv_default_loop(), signal);
uv_signal_start(signal, xmrig::Signals::onSignal, signums[i]);
uv_signal_start(signal, Signals::onSignal, signums[i]);
}
}
xmrig::Signals::~Signals()
{
stop();
}
void xmrig::Signals::stop()
{
if (!m_signals[0]) {
return;
}
for (size_t i = 0; i < kSignalsCount; ++i) {
Handle::close(m_signals[i]);
m_signals[i] = nullptr;
}
}
void xmrig::Signals::onSignal(uv_signal_t *handle, int signum)
{
static_cast<xmrig::Signals *>(handle->data)->m_listener->onSignal(signum);
static_cast<Signals *>(handle->data)->m_listener->onSignal(signum);
}

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