Merge branch 'master' into base_origin_feb14

This commit is contained in:
enWILLYado 2018-03-18 22:48:46 +01:00
commit afd97d26fe
102 changed files with 7287 additions and 1396 deletions

5
.gitignore vendored
View file

@ -1,2 +1,5 @@
/build
/build*
/CMakeLists.txt.user
/vs/*/
*.opensdf
*.sdf

136
README.md
View file

@ -1,133 +1,25 @@
# XMRig
:warning: **You must update miners to version 2.5 before March 28 due [Monero PoW change](https://getmonero.org/2018/02/11/PoW-change-and-key-reuse.html).**
[![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub Release Date](https://img.shields.io/github/release-date-pre/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/releases)
[![GitHub license](https://img.shields.io/github/license/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/blob/master/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/network)
# XMRig (enWILLYado version)
[XMRig](https://github.com/xmrig) is a team that has some high performance Monero (XMR) miners, with official support for Windows.
This fork is originally based on the [CPU-mining](https://github.com/xmrig/xmrig) version with some optimizations/rewrites, interesting features for final users and a little code refactors.
XMRig is a high performance Monero (XMR) CPU miner, with official support for Windows.
Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 completely rewritten from scratch on C++.
* This software is like the [CPU-mining](https://github.com/xmrig/xmrig) version; but there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia) and [AMD GPU version]( https://github.com/xmrig/xmrig-amd).
* 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" >
## Own features
#### Table of contents
* [Features](#features)
* [Download](#download)
* [Usage](#usage)
* [Algorithm variations](#algorithm-variations)
* [Build](https://github.com/xmrig/xmrig/wiki/Build)
* [Common Issues](#common-issues)
* [Other information](#other-information)
* [Donations](#donations)
* [Release checksums](#release-checksums)
* [Contacts](#contacts)
## Features
* High performance.
* Official Windows support.
* Small Windows executable, without dependencies.
* x86/x64 support.
* Support for backup (failover) mining server.
* keepalived support.
* Command line options compatible with cpuminer.
* CryptoNight-Lite support for AEON.
* Smart automatic [CPU configuration](https://github.com/xmrig/xmrig/wiki/Threads).
* Nicehash support
* It's open source software.
## Download
* Binary releases: https://github.com/xmrig/xmrig/releases
* Git tree: https://github.com/xmrig/xmrig.git
* Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build).
## Usage
Use [config.xmrig.com](https://config.xmrig.com/xmrig) to generate, edit or share configurations.
### Options
```
-a, --algo=ALGO cryptonight (default) or cryptonight-lite
-o, --url=URL URL of mining server
-O, --userpass=U:P username:password pair for mining server
-u, --user=USERNAME username for mining server
-p, --pass=PASSWORD password for mining server
-t, --threads=N number of miner threads
-v, --av=N algorithm variation, 0 auto select
-k, --keepalive send keepalived for prevent timeout (need pool support)
-r, --retries=N number of times to retry before switch to backup server (default: 5)
-R, --retry-pause=N time to pause between retries (default: 5)
--cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)
--no-huge-pages disable huge pages support
--no-color disable colored output
--donate-level=N donate level, default 5% (5 minutes in 100 minutes)
--user-agent set custom user-agent string for pool
-B, --background run the miner in the background
-c, --config=FILE load a JSON-format configuration file
-l, --log-file=FILE log all output to a file
--max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)
--safe safe adjust threads and av settings for current CPU
--nicehash enable nicehash/xmrig-proxy support
--print-time=N print hashrate report every N seconds
--api-port=N port for the miner API
--api-access-token=T access token for API
--api-worker-id=ID custom worker-id for API
-h, --help display this help and exit
-V, --version output version information and exit
```
Also you can use configuration via config file, default **config.json**. You can load multiple config files and combine it with command line options.
## Algorithm variations
Since version 0.8.0.
* `--av=1` For CPUs with hardware AES.
* `--av=2` Lower power mode (double hash) of `1`.
* `--av=3` Software AES implementation.
* `--av=4` Lower power mode (double hash) of `3`.
## Common Issues
### HUGE PAGES unavailable
* Run XMRig as Administrator.
* Since version 0.8.0 XMRig automatically enables SeLockMemoryPrivilege for current user, but reboot or sign out still required. [Manual instruction](https://msdn.microsoft.com/en-gb/library/ms190730.aspx).
## Other information
* No HTTP support, only stratum protocol support.
* No TLS support.
* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
### CPU mining performance
* **Intel i7-7700** - 307 H/s (4 threads)
* **AMD Ryzen 7 1700X** - 560 H/s (8 threads)
Please note performance is highly dependent on system load. The numbers above are obtained on an idle system. Tasks heavily using a processor cache, such as video playback, can greatly degrade hashrate. Optimal number of threads depends on the size of the L3 cache of a processor, 1 thread requires 2 MB of cache.
### Maximum performance checklist
* Idle operating system.
* Do not exceed optimal thread count.
* Use modern CPUs with AES-NI instruction set.
* Try setup optimal cpu affinity.
* Enable fast memory (Large/Huge pages).
* Connect to pool or proxies over HTTP PROXY.
* Include basic encrypted communications.
## Donations
* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
## Release checksums
### SHA-256
```
232ea929f7219c8de81c7e6fcae7437d40d8128cf55b597a6e1fca0cd77f9f5b xmrig-2.5.0-xenial-amd64.tar.gz/xmrig-2.5.0/xmrig
6149ffed21e740cac12aa61b2fdd17248cbd3e51bab2289d2766aad1d29df910 xmrig-2.5.0-gcc-win32.zip/xmrig.exe
9c89f80e21db906439a7a1b333b8215dbe07d8e42f98a63f6c10c954288a7108 xmrig-2.5.0-gcc-win64.zip/xmrig.exe
b50773c5a74ca9921597a1152e2469ec266cc89eb9765038db7e876f0bcece73 xmrig-2.5.0-msvc-win64.zip/xmrig.exe
```
* XMR: `433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi`
* BTC: `13MTEjDv8JmS4suaRx6CcWNthR1vwPr7Ce`
* DOGE: `DHif8RTy8E6K4b71u3fXXSk7AEyiuN2sUi`
## Contacts
* support@xmrig.com
* [reddit](https://www.reddit.com/user/XMRig/)
* xmrig@enwillyado.com
* [telegram](https://telegram.me/enWILLYado)
¡Se habla español!

View file

@ -8,11 +8,11 @@ endif()
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 -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -DFOUR_WAY -fomit-frame-pointer -Wno-strict-aliasing -msse -msse2 -msse3 -mmmx -m3dnow")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -ffast-math -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fpermissive -DFOUR_WAY -fomit-frame-pointer -Wno-strict-aliasing -msse -msse2 -msse3 -mmmx -m3dnow")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -ffast-math -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
if (XMRIG_ARMv8)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto")
@ -21,20 +21,20 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -flax-vector-conversions")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native -maes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -maes")
endif()
if (WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -flto")
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -flto")
endif()
add_definitions(/D_GNU_SOURCE)
if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
endif()
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")

33
src/3rdparty/align.h vendored Normal file
View file

@ -0,0 +1,33 @@
/* 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 __ALIGN_H__
#define __ALIGN_H__
#ifdef _MSC_VER
# define VAR_ALIGN(x, decl) __declspec(align(x)) decl
#else
# define VAR_ALIGN(x, decl) decl __attribute__ ((aligned(x)))
#endif
#endif /* __ALIGN_H__ */

View file

@ -36,6 +36,10 @@
#include <string.h>
#include <stdlib.h>
#ifndef VERSION
#define VERSION "7.10"
#endif
/* Implementation: */
static int _libcpiud_errno = ERR_OK;
@ -46,6 +50,11 @@ int set_error(cpu_error_t err)
return (int) err;
}
static void raw_data_t_constructor(struct cpu_raw_data_t* raw)
{
memset(raw, 0, sizeof(struct cpu_raw_data_t));
}
static void cpu_id_t_constructor(struct cpu_id_t* id)
{
memset(id, 0, sizeof(struct cpu_id_t));
@ -55,6 +64,37 @@ static void cpu_id_t_constructor(struct cpu_id_t* id)
id->sse_size = -1;
}
static int parse_token(const char* expected_token, const char* token,
const char* value, uint32_t array[][4], int limit, int* recognized)
{
char format[32];
int veax, vebx, vecx, vedx;
int index;
if(*recognized)
{
return 1; /* already recognized */
}
if(strncmp(token, expected_token, strlen(expected_token)))
{
return 1; /* not what we search for */
}
sprintf(format, "%s[%%d]", expected_token);
*recognized = 1;
if(1 == sscanf(token, format, &index) && index >= 0 && index < limit)
{
if(4 == sscanf(value, "%x%x%x%x", &veax, &vebx, &vecx, &vedx))
{
array[index][0] = veax;
array[index][1] = vebx;
array[index][2] = vecx;
array[index][3] = vedx;
return 1;
}
}
return 0;
}
/* get_total_cpus() system specific code: uses OS routines to determine total number of CPUs */
#ifdef __APPLE__
#include <unistd.h>
@ -328,6 +368,31 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat
return set_error(ERR_OK);
}
static void make_list_from_string(const char* csv, struct cpu_list_t* list)
{
int i, n, l, last;
l = (int) strlen(csv);
n = 0;
for(i = 0; i < l; i++) if(csv[i] == ',')
{
n++;
}
n++;
list->num_entries = n;
list->names = (char**) malloc(sizeof(char*) * n);
last = -1;
n = 0;
for(i = 0; i <= l; i++) if(i == l || csv[i] == ',')
{
list->names[n] = (char*) malloc(i - last);
memcpy(list->names[n], &csv[last + 1], i - last - 1);
list->names[n][i - last - 1] = '\0';
n++;
last = i;
}
}
/* Interface: */
int cpuid_get_total_cpus(void)
@ -398,6 +463,140 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data)
return set_error(ERR_OK);
}
int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
{
int i;
FILE* f;
if(!strcmp(filename, ""))
{
f = stdout;
}
else
{
f = fopen(filename, "wt");
}
if(!f)
{
return set_error(ERR_OPEN);
}
fprintf(f, "version=%s\n", VERSION);
for(i = 0; i < MAX_CPUID_LEVEL; i++)
fprintf(f, "basic_cpuid[%d]=%08x %08x %08x %08x\n", i,
data->basic_cpuid[i][0], data->basic_cpuid[i][1],
data->basic_cpuid[i][2], data->basic_cpuid[i][3]);
for(i = 0; i < MAX_EXT_CPUID_LEVEL; i++)
fprintf(f, "ext_cpuid[%d]=%08x %08x %08x %08x\n", i,
data->ext_cpuid[i][0], data->ext_cpuid[i][1],
data->ext_cpuid[i][2], data->ext_cpuid[i][3]);
for(i = 0; i < MAX_INTELFN4_LEVEL; i++)
fprintf(f, "intel_fn4[%d]=%08x %08x %08x %08x\n", i,
data->intel_fn4[i][0], data->intel_fn4[i][1],
data->intel_fn4[i][2], data->intel_fn4[i][3]);
for(i = 0; i < MAX_INTELFN11_LEVEL; i++)
fprintf(f, "intel_fn11[%d]=%08x %08x %08x %08x\n", i,
data->intel_fn11[i][0], data->intel_fn11[i][1],
data->intel_fn11[i][2], data->intel_fn11[i][3]);
for(i = 0; i < MAX_INTELFN12H_LEVEL; i++)
fprintf(f, "intel_fn12h[%d]=%08x %08x %08x %08x\n", i,
data->intel_fn12h[i][0], data->intel_fn12h[i][1],
data->intel_fn12h[i][2], data->intel_fn12h[i][3]);
for(i = 0; i < MAX_INTELFN14H_LEVEL; i++)
fprintf(f, "intel_fn14h[%d]=%08x %08x %08x %08x\n", i,
data->intel_fn14h[i][0], data->intel_fn14h[i][1],
data->intel_fn14h[i][2], data->intel_fn14h[i][3]);
if(strcmp(filename, ""))
{
fclose(f);
}
return set_error(ERR_OK);
}
int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename)
{
int i, len;
char line[100];
char token[100];
char* value;
int syntax;
int cur_line = 0;
int recognized;
FILE* f;
raw_data_t_constructor(data);
if(!strcmp(filename, ""))
{
f = stdin;
}
else
{
f = fopen(filename, "rt");
}
if(!f)
{
return set_error(ERR_OPEN);
}
while(fgets(line, sizeof(line), f))
{
++cur_line;
len = (int) strlen(line);
if(len < 2)
{
continue;
}
if(line[len - 1] == '\n')
{
line[--len] = '\0';
}
for(i = 0; i < len && line[i] != '='; i++)
if(i >= len && i < 1 && len - i - 1 <= 0)
{
fclose(f);
return set_error(ERR_BADFMT);
}
strncpy(token, line, i);
token[i] = '\0';
value = &line[i + 1];
/* try to recognize the line */
recognized = 0;
if(!strcmp(token, "version") || !strcmp(token, "build_date"))
{
recognized = 1;
}
syntax = 1;
syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, MAX_CPUID_LEVEL, &recognized);
syntax = syntax &&
parse_token("ext_cpuid", token, value, data->ext_cpuid, MAX_EXT_CPUID_LEVEL, &recognized);
syntax = syntax &&
parse_token("intel_fn4", token, value, data->intel_fn4, MAX_INTELFN4_LEVEL, &recognized);
syntax = syntax &&
parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_LEVEL, &recognized);
syntax = syntax &&
parse_token("intel_fn12h", token, value, data->intel_fn12h, MAX_INTELFN12H_LEVEL, &recognized);
syntax = syntax &&
parse_token("intel_fn14h", token, value, data->intel_fn14h, MAX_INTELFN14H_LEVEL, &recognized);
if(!syntax)
{
warnf("Error: %s:%d: Syntax error\n", filename, cur_line);
fclose(f);
return set_error(ERR_BADFMT);
}
if(!recognized)
{
warnf("Warning: %s:%d not understood!\n", filename, cur_line);
}
}
if(strcmp(filename, ""))
{
fclose(f);
}
return set_error(ERR_OK);
}
int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
{
int r;
@ -435,7 +634,264 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
return cpu_ident_internal(raw, data, &throwaway);
}
const char* cpu_feature_str(cpu_feature_t feature)
{
const struct
{
cpu_feature_t feature;
const char* name;
}
matchtable[] =
{
{ CPU_FEATURE_FPU, "fpu" },
{ CPU_FEATURE_VME, "vme" },
{ CPU_FEATURE_DE, "de" },
{ CPU_FEATURE_PSE, "pse" },
{ CPU_FEATURE_TSC, "tsc" },
{ CPU_FEATURE_MSR, "msr" },
{ CPU_FEATURE_PAE, "pae" },
{ CPU_FEATURE_MCE, "mce" },
{ CPU_FEATURE_CX8, "cx8" },
{ CPU_FEATURE_APIC, "apic" },
{ CPU_FEATURE_MTRR, "mtrr" },
{ CPU_FEATURE_SEP, "sep" },
{ CPU_FEATURE_PGE, "pge" },
{ CPU_FEATURE_MCA, "mca" },
{ CPU_FEATURE_CMOV, "cmov" },
{ CPU_FEATURE_PAT, "pat" },
{ CPU_FEATURE_PSE36, "pse36" },
{ CPU_FEATURE_PN, "pn" },
{ CPU_FEATURE_CLFLUSH, "clflush" },
{ CPU_FEATURE_DTS, "dts" },
{ CPU_FEATURE_ACPI, "acpi" },
{ CPU_FEATURE_MMX, "mmx" },
{ CPU_FEATURE_FXSR, "fxsr" },
{ CPU_FEATURE_SSE, "sse" },
{ CPU_FEATURE_SSE2, "sse2" },
{ CPU_FEATURE_SS, "ss" },
{ CPU_FEATURE_HT, "ht" },
{ CPU_FEATURE_TM, "tm" },
{ CPU_FEATURE_IA64, "ia64" },
{ CPU_FEATURE_PBE, "pbe" },
{ CPU_FEATURE_PNI, "pni" },
{ CPU_FEATURE_PCLMUL, "pclmul" },
{ CPU_FEATURE_DTS64, "dts64" },
{ CPU_FEATURE_MONITOR, "monitor" },
{ CPU_FEATURE_DS_CPL, "ds_cpl" },
{ CPU_FEATURE_VMX, "vmx" },
{ CPU_FEATURE_SMX, "smx" },
{ CPU_FEATURE_EST, "est" },
{ CPU_FEATURE_TM2, "tm2" },
{ CPU_FEATURE_SSSE3, "ssse3" },
{ CPU_FEATURE_CID, "cid" },
{ CPU_FEATURE_CX16, "cx16" },
{ CPU_FEATURE_XTPR, "xtpr" },
{ CPU_FEATURE_PDCM, "pdcm" },
{ CPU_FEATURE_DCA, "dca" },
{ CPU_FEATURE_SSE4_1, "sse4_1" },
{ CPU_FEATURE_SSE4_2, "sse4_2" },
{ CPU_FEATURE_SYSCALL, "syscall" },
{ CPU_FEATURE_XD, "xd" },
{ CPU_FEATURE_X2APIC, "x2apic"},
{ CPU_FEATURE_MOVBE, "movbe" },
{ CPU_FEATURE_POPCNT, "popcnt" },
{ CPU_FEATURE_AES, "aes" },
{ CPU_FEATURE_XSAVE, "xsave" },
{ CPU_FEATURE_OSXSAVE, "osxsave" },
{ CPU_FEATURE_AVX, "avx" },
{ CPU_FEATURE_MMXEXT, "mmxext" },
{ CPU_FEATURE_3DNOW, "3dnow" },
{ CPU_FEATURE_3DNOWEXT, "3dnowext" },
{ CPU_FEATURE_NX, "nx" },
{ CPU_FEATURE_FXSR_OPT, "fxsr_opt" },
{ CPU_FEATURE_RDTSCP, "rdtscp" },
{ CPU_FEATURE_LM, "lm" },
{ CPU_FEATURE_LAHF_LM, "lahf_lm" },
{ CPU_FEATURE_CMP_LEGACY, "cmp_legacy" },
{ CPU_FEATURE_SVM, "svm" },
{ CPU_FEATURE_SSE4A, "sse4a" },
{ CPU_FEATURE_MISALIGNSSE, "misalignsse" },
{ CPU_FEATURE_ABM, "abm" },
{ CPU_FEATURE_3DNOWPREFETCH, "3dnowprefetch" },
{ CPU_FEATURE_OSVW, "osvw" },
{ CPU_FEATURE_IBS, "ibs" },
{ CPU_FEATURE_SSE5, "sse5" },
{ CPU_FEATURE_SKINIT, "skinit" },
{ CPU_FEATURE_WDT, "wdt" },
{ CPU_FEATURE_TS, "ts" },
{ CPU_FEATURE_FID, "fid" },
{ CPU_FEATURE_VID, "vid" },
{ CPU_FEATURE_TTP, "ttp" },
{ CPU_FEATURE_TM_AMD, "tm_amd" },
{ CPU_FEATURE_STC, "stc" },
{ CPU_FEATURE_100MHZSTEPS, "100mhzsteps" },
{ CPU_FEATURE_HWPSTATE, "hwpstate" },
{ CPU_FEATURE_CONSTANT_TSC, "constant_tsc" },
{ CPU_FEATURE_XOP, "xop" },
{ CPU_FEATURE_FMA3, "fma3" },
{ CPU_FEATURE_FMA4, "fma4" },
{ CPU_FEATURE_TBM, "tbm" },
{ CPU_FEATURE_F16C, "f16c" },
{ CPU_FEATURE_RDRAND, "rdrand" },
{ CPU_FEATURE_CPB, "cpb" },
{ CPU_FEATURE_APERFMPERF, "aperfmperf" },
{ CPU_FEATURE_PFI, "pfi" },
{ CPU_FEATURE_PA, "pa" },
{ CPU_FEATURE_AVX2, "avx2" },
{ CPU_FEATURE_BMI1, "bmi1" },
{ CPU_FEATURE_BMI2, "bmi2" },
{ CPU_FEATURE_HLE, "hle" },
{ CPU_FEATURE_RTM, "rtm" },
{ CPU_FEATURE_AVX512F, "avx512f" },
{ CPU_FEATURE_AVX512DQ, "avx512dq" },
{ CPU_FEATURE_AVX512PF, "avx512pf" },
{ CPU_FEATURE_AVX512ER, "avx512er" },
{ CPU_FEATURE_AVX512CD, "avx512cd" },
{ CPU_FEATURE_SHA_NI, "sha_ni" },
{ CPU_FEATURE_AVX512BW, "avx512bw" },
{ CPU_FEATURE_AVX512VL, "avx512vl" },
{ CPU_FEATURE_SGX, "sgx" },
{ CPU_FEATURE_RDSEED, "rdseed" },
{ CPU_FEATURE_ADX, "adx" },
};
unsigned i, n = COUNT_OF(matchtable);
if(n != NUM_CPU_FEATURES)
{
warnf("Warning: incomplete library, feature matchtable size differs from the actual number of features.\n");
}
for(i = 0; i < n; i++)
if(matchtable[i].feature == feature)
{
return matchtable[i].name;
}
return "";
}
const char* cpuid_error(void)
{
const struct
{
cpu_error_t error;
const char* description;
}
matchtable[] =
{
{ ERR_OK , "No error"},
{ ERR_NO_CPUID , "CPUID instruction is not supported"},
{ ERR_NO_RDTSC , "RDTSC instruction is not supported"},
{ ERR_NO_MEM , "Memory allocation failed"},
{ ERR_OPEN , "File open operation failed"},
{ ERR_BADFMT , "Bad file format"},
{ ERR_NOT_IMP , "Not implemented"},
{ ERR_CPU_UNKN , "Unsupported processor"},
{ ERR_NO_RDMSR , "RDMSR instruction is not supported"},
{ ERR_NO_DRIVER, "RDMSR driver error (generic)"},
{ ERR_NO_PERMS , "No permissions to install RDMSR driver"},
{ ERR_EXTRACT , "Cannot extract RDMSR driver (read only media?)"},
{ ERR_HANDLE , "Bad handle"},
{ ERR_INVMSR , "Invalid MSR"},
{ ERR_INVCNB , "Invalid core number"},
{ ERR_HANDLE_R , "Error on handle read"},
{ ERR_INVRANGE , "Invalid given range"},
};
unsigned i;
for(i = 0; i < COUNT_OF(matchtable); i++)
if(_libcpiud_errno == matchtable[i].error)
{
return matchtable[i].description;
}
return "Unknown error";
}
const char* cpuid_lib_version(void)
{
return VERSION;
}
libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t new_fn)
{
libcpuid_warn_fn_t ret = _warn_fun;
_warn_fun = new_fn;
return ret;
}
void cpuid_set_verbosiness_level(int level)
{
_current_verboselevel = level;
}
cpu_vendor_t cpuid_get_vendor(void)
{
static cpu_vendor_t vendor = VENDOR_UNKNOWN;
uint32_t raw_vendor[4];
char vendor_str[VENDOR_STR_MAX];
if(vendor == VENDOR_UNKNOWN)
{
if(!cpuid_present())
{
set_error(ERR_NO_CPUID);
}
else
{
cpu_exec_cpuid(0, raw_vendor);
vendor = cpuid_vendor_identify(raw_vendor, vendor_str);
}
}
return vendor;
}
void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list)
{
switch(vendor)
{
case VENDOR_INTEL:
cpuid_get_list_intel(list);
break;
case VENDOR_AMD:
cpuid_get_list_amd(list);
break;
case VENDOR_CYRIX:
make_list_from_string("Cx486,Cx5x86,6x86,6x86MX,M II,MediaGX,MediaGXi,MediaGXm", list);
break;
case VENDOR_NEXGEN:
make_list_from_string("Nx586", list);
break;
case VENDOR_TRANSMETA:
make_list_from_string("Crusoe,Efficeon", list);
break;
case VENDOR_UMC:
make_list_from_string("UMC x86 CPU", list);
break;
case VENDOR_CENTAUR:
make_list_from_string("VIA C3,VIA C7,VIA Nano", list);
break;
case VENDOR_RISE:
make_list_from_string("Rise mP6", list);
break;
case VENDOR_SIS:
make_list_from_string("SiS mP6", list);
break;
case VENDOR_NSC:
make_list_from_string("Geode GXm,Geode GXLV,Geode GX1,Geode GX2", list);
break;
default:
warnf("Unknown vendor passed to cpuid_get_cpu_list()\n");
break;
}
}
void cpuid_free_cpu_list(struct cpu_list_t* list)
{
int i;
if(list->num_entries <= 0)
{
return;
}
for(i = 0; i < list->num_entries; i++)
{
free(list->names[i]);
}
free(list->names);
}

View file

@ -85,7 +85,11 @@
@{ */
/* Include some integer type specifications: */
#ifdef _WIN32
#include "libcpuid_types.h"
#else
# include <stdint.h>
#endif
/* Some limits and other constants */
#include "libcpuid_constants.h"
@ -619,6 +623,39 @@ void cpu_exec_cpuid_ext(uint32_t* regs);
*/
int cpuid_get_raw_data(struct cpu_raw_data_t* data);
/**
* @brief Writes the raw CPUID data to a text file
* @param data - a pointer to cpu_raw_data_t structure
* @param filename - the path of the file, where the serialized data should be
* written. If empty, stdout will be used.
* @note This is intended primarily for debugging. On some processor, which is
* not currently supported or not completely recognized by cpu_identify,
* one can still successfully get the raw data and write it to a file.
* libcpuid developers can later import this file and debug the detection
* code as if running on the actual hardware.
* The file is simple text format of "something=value" pairs. Version info
* is also written, but the format is not intended to be neither backward-
* nor forward compatible.
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
/**
* @brief Reads raw CPUID data from file
* @param data - a pointer to cpu_raw_data_t structure. The deserialized data will
* be written here.
* @param filename - the path of the file, containing the serialized raw data.
* If empty, stdin will be used.
* @note This function may fail, if the file is created by different version of
* the library. Also, see the notes on cpuid_serialize_raw_data.
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename);
/**
* @brief Identifies the CPU
* @param raw - Input - a pointer to the raw CPUID data, which is obtained
@ -644,6 +681,222 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data);
*/
int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data);
/**
* @brief Returns the short textual representation of a CPU flag
* @param feature - the feature, whose textual representation is wanted.
* @returns a constant string like "fpu", "tsc", "sse2", etc.
* @note the names of the returned flags are compatible with those from
* /proc/cpuinfo in Linux, with the exception of `tm_amd'
*/
const char* cpu_feature_str(cpu_feature_t feature);
/**
* @brief Returns textual description of the last error
*
* libcpuid stores an `errno'-style error status, whose description
* can be obtained with this function.
* @note This function is not thread-safe
* @see cpu_error_t
*/
const char* cpuid_error(void);
/**
* @brief Executes RDTSC
*
* The RDTSC (ReaD Time Stamp Counter) instruction gives access to an
* internal 64-bit counter, which usually increments at each clock cycle.
* This can be used for various timing routines, and as a very precise
* clock source. It is set to zero on system startup. Beware that may not
* increment at the same frequency as the CPU. Consecutive calls of RDTSC
* are, however, guaranteed to return monotonically-increasing values.
*
* @param result - a pointer to a 64-bit unsigned integer, where the TSC value
* will be stored
*
* @note If 100% compatibility is a concern, you must first check if the
* RDTSC instruction is present (if it is not, your program will crash
* with "invalid opcode" exception). Only some very old processors (i486,
* early AMD K5 and some Cyrix CPUs) lack that instruction - they should
* have become exceedingly rare these days. To verify RDTSC presence,
* run cpu_identify() and check flags[CPU_FEATURE_TSC].
*
* @note The monotonically increasing nature of the TSC may be violated
* on SMP systems, if their TSC clocks run at different rate. If the OS
* doesn't account for that, the TSC drift may become arbitrary large.
*/
void cpu_rdtsc(uint64_t* result);
/**
* @brief Store TSC and timing info
*
* This function stores the current TSC value and current
* time info from a precise OS-specific clock source in the cpu_mark_t
* structure. The sys_clock field contains time with microsecond resolution.
* The values can later be used to measure time intervals, number of clocks,
* FPU frequency, etc.
* @see cpu_rdtsc
*
* @param mark [out] - a pointer to a cpu_mark_t structure
*/
void cpu_tsc_mark(struct cpu_mark_t* mark);
/**
* @brief Calculate TSC and timing difference
*
* @param mark - input/output: a pointer to a cpu_mark_t sturcture, which has
* already been initialized by cpu_tsc_mark. The difference in
* TSC and time will be written here.
*
* This function calculates the TSC and time difference, by obtaining the
* current TSC and timing values and subtracting the contents of the `mark'
* structure from them. Results are written in the same structure.
*
* Example:
* @code
* ...
* struct cpu_mark_t mark;
* cpu_tsc_mark(&mark);
* foo();
* cpu_tsc_unmark(&mark);
* printf("Foo finished. Executed in %llu cycles and %llu usecs\n",
* mark.tsc, mark.sys_clock);
* ...
* @endcode
*/
void cpu_tsc_unmark(struct cpu_mark_t* mark);
/**
* @brief Calculates the CPU clock
*
* @param mark - pointer to a cpu_mark_t structure, which has been initialized
* with cpu_tsc_mark and later `stopped' with cpu_tsc_unmark.
*
* @note For reliable results, the marked time interval should be at least about
* 10 ms.
*
* @returns the CPU clock frequency, in MHz. Due to measurement error, it will
* differ from the true value in a few least-significant bits. Accuracy depends
* on the timing interval - the more, the better. If the timing interval is
* insufficient, the result is -1. Also, see the comment on cpu_clock_measure
* for additional issues and pitfalls in using RDTSC for CPU frequency
* measurements.
*/
int cpu_clock_by_mark(struct cpu_mark_t* mark);
/**
* @brief Returns the CPU clock, as reported by the OS
*
* This function uses OS-specific functions to obtain the CPU clock. It may
* differ from the true clock for several reasons:<br><br>
*
* i) The CPU might be in some power saving state, while the OS reports its
* full-power frequency, or vice-versa.<br>
* ii) In some cases you can raise or lower the CPU frequency with overclocking
* utilities and the OS will not notice.
*
* @returns the CPU clock frequency in MHz. If the OS is not (yet) supported
* or lacks the necessary reporting machinery, the return value is -1
*/
int cpu_clock_by_os(void);
/**
* @brief Measure the CPU clock frequency
*
* @param millis - How much time to waste in the busy-wait cycle. In millisecs.
* Useful values 10 - 1000
* @param quad_check - Do a more thorough measurement if nonzero
* (see the explanation).
*
* The function performs a busy-wait cycle for the given time and calculates
* the CPU frequency by the difference of the TSC values. The accuracy of the
* calculation depends on the length of the busy-wait cycle: more is better,
* but 100ms should be enough for most purposes.
*
* While this will calculate the CPU frequency correctly in most cases, there are
* several reasons why it might be incorrect:<br>
*
* i) RDTSC doesn't guarantee it will run at the same clock as the CPU.
* Apparently there aren't CPUs at the moment, but still, there's no
* guarantee.<br>
* ii) The CPU might be in a low-frequency power saving mode, and the CPU
* might be switched to higher frequency at any time. If this happens
* during the measurement, the result can be anywhere between the
* low and high frequencies. Also, if you're interested in the
* high frequency value only, this function might return the low one
* instead.<br>
* iii) On SMP systems exhibiting TSC drift (see \ref cpu_rdtsc)
*
* the quad_check option will run four consecutive measurements and
* then return the average of the two most-consistent results. The total
* runtime of the function will still be `millis' - consider using
* a bit more time for the timing interval.
*
* Finally, for benchmarking / CPU intensive applications, the best strategy is
* to use the cpu_tsc_mark() / cpu_tsc_unmark() / cpu_clock_by_mark() method.
* Begin by mark()-ing about one second after application startup (allowing the
* power-saving manager to kick in and rise the frequency during that time),
* then unmark() just before application finishing. The result will most
* acurately represent at what frequency your app was running.
*
* @returns the CPU clock frequency in MHz (within some measurement error
* margin). If RDTSC is not supported, the result is -1.
*/
int cpu_clock_measure(int millis, int quad_check);
/**
* @brief Measure the CPU clock frequency using instruction-counting
*
* @param millis - how much time to allocate for each run, in milliseconds
* @param runs - how many runs to perform
*
* The function performs a busy-wait cycle using a known number of "heavy" (SSE)
* instructions. These instructions run at (more or less guaranteed) 1 IPC rate,
* so by running a busy loop for a fixed amount of time, and measuring the
* amount of instructions done, the CPU clock is accurately measured.
*
* Of course, this function is still affected by the power-saving schemes, so
* the warnings as of cpu_clock_measure() still apply. However, this function is
* immune to problems with detection, related to the Intel Nehalem's "Turbo"
* mode, where the internal clock is raised, but the RDTSC rate is unaffected.
*
* The function will run for about (millis * runs) milliseconds.
* You can make only a single busy-wait run (runs == 1); however, this can
* be affected by task scheduling (which will break the counting), so allowing
* more than one run is recommended. As run length is not imperative for
* accurate readings (e.g., 50ms is sufficient), you can afford a lot of short
* runs, e.g. 10 runs of 50ms or 20 runs of 25ms.
*
* Recommended values - millis = 50, runs = 4. For more robustness,
* increase the number of runs.
*
* NOTE: on Bulldozer and later CPUs, the busy-wait cycle runs at 1.4 IPC, thus
* the results are skewed. This is corrected internally by dividing the resulting
* value by 1.4.
* However, this only occurs if the thread is executed on a single CMT
* module - if there are other threads competing for resources, the results are
* unpredictable. Make sure you run cpu_clock_by_ic() on a CPU that is free from
* competing threads, or if there are such threads, they shouldn't exceed the
* number of modules. On a Bulldozer X8, that means 4 threads.
*
* @returns the CPU clock frequency in MHz (within some measurement error
* margin). If SSE is not supported, the result is -1. If the input parameters
* are incorrect, or some other internal fault is detected, the result is -2.
*/
int cpu_clock_by_ic(int millis, int runs);
/**
* @brief Get the CPU clock frequency (all-in-one method)
*
* This is an all-in-one method for getting the CPU clock frequency.
* It tries to use the OS for that. If the OS doesn't have this info, it
* uses cpu_clock_measure with 200ms time interval and quadruple checking.
*
* @returns the CPU clock frequency in MHz. If every possible method fails,
* the result is -1.
*/
int cpu_clock(void);
/**
* @brief The return value of cpuid_get_epc().
* @details
@ -677,6 +930,232 @@ struct cpu_epc_t cpuid_get_epc(int index, const struct cpu_raw_data_t* raw);
*/
const char* cpuid_lib_version(void);
typedef void (*libcpuid_warn_fn_t)(const char* msg);
/**
* @brief Sets the warning print function
*
* In some cases, the internal libcpuid machinery would like to emit useful
* debug warnings. By default, these warnings are written to stderr. However,
* you can set a custom function that will receive those warnings.
*
* @param warn_fun - the warning function you want to set. If NULL, warnings
* are disabled. The function takes const char* argument.
*
* @returns the current warning function. You can use the return value to
* keep the previous warning function and restore it at your discretion.
*/
libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t warn_fun);
/**
* @brief Sets the verbosiness level
*
* When the verbosiness level is above zero, some functions might print
* diagnostic information about what are they doing. The higher the level is,
* the more detail is printed. Level zero is guaranteed to omit all such
* output. The output is written using the same machinery as the warnings,
* @see cpuid_set_warn_function()
*
* @param level the desired verbosiness level. Useful values 0..2 inclusive
*/
void cpuid_set_verbosiness_level(int level);
/**
* @brief Obtains the CPU vendor from CPUID from the current CPU
* @note The result is cached.
* @returns VENDOR_UNKNOWN if failed, otherwise the CPU vendor type.
* @see cpu_vendor_t
*/
cpu_vendor_t cpuid_get_vendor(void);
/**
* @brief a structure that holds a list of processor names
*/
struct cpu_list_t
{
/** Number of entries in the list */
int num_entries;
/** Pointers to names. There will be num_entries of them */
char** names;
};
/**
* @brief Gets a list of all known CPU names from a specific vendor.
*
* This function compiles a list of all known CPU (code)names
* (i.e. the possible values of cpu_id_t::cpu_codename) for the given vendor.
*
* There are about 100 entries for Intel and AMD, and a few for the other
* vendors. The list is written out in approximate chronological introduction
* order of the parts.
*
* @param vendor the vendor to be queried
* @param list [out] the resulting list will be written here.
* NOTE: As the memory is dynamically allocated, be sure to call
* cpuid_free_cpu_list() after you're done with the data
* @see cpu_list_t
*/
void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list);
/**
* @brief Frees a CPU list
*
* This function deletes all the memory associated with a CPU list, as obtained
* by cpuid_get_cpu_list()
*
* @param list - the list to be free()'d.
*/
void cpuid_free_cpu_list(struct cpu_list_t* list);
struct msr_driver_t;
/**
* @brief Starts/opens a driver, needed to read MSRs (Model Specific Registers)
*
* On systems that support it, this function will create a temporary
* system driver, that has privileges to execute the RDMSR instruction.
* After the driver is created, you can read MSRs by calling \ref cpu_rdmsr
*
* @returns a handle to the driver on success, and NULL on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
struct msr_driver_t* cpu_msr_driver_open(void);
/**
* @brief Similar to \ref cpu_msr_driver_open, but accept one parameter
*
* This function works on certain operating systems (GNU/Linux, FreeBSD)
*
* @param core_num specify the core number for MSR.
* The first core number is 0.
* The last core number is \ref cpuid_get_total_cpus - 1.
*
* @returns a handle to the driver on success, and NULL on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
struct msr_driver_t* cpu_msr_driver_open_core(unsigned core_num);
/**
* @brief Reads a Model-Specific Register (MSR)
*
* If the CPU has MSRs (as indicated by the CPU_FEATURE_MSR flag), you can
* read a MSR with the given index by calling this function.
*
* There are several prerequisites you must do before reading MSRs:
* 1) You must ensure the CPU has RDMSR. Check the CPU_FEATURE_MSR flag
* in cpu_id_t::flags
* 2) You must ensure that the CPU implements the specific MSR you intend to
* read.
* 3) You must open a MSR-reader driver. RDMSR is a privileged instruction and
* needs ring-0 access in order to work. This temporary driver is created
* by calling \ref cpu_msr_driver_open
*
* @param handle - a handle to the MSR reader driver, as created by
* cpu_msr_driver_open
* @param msr_index - the numeric ID of the MSR you want to read
* @param result - a pointer to a 64-bit integer, where the MSR value is stored
*
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int cpu_rdmsr(struct msr_driver_t* handle, uint32_t msr_index, uint64_t* result);
typedef enum
{
INFO_MPERF, /*!< Maximum performance frequency clock. This
is a counter, which increments as a
proportion of the actual processor speed. */
INFO_APERF, /*!< Actual performance frequency clock. This
accumulates the core clock counts when the
core is active. */
INFO_MIN_MULTIPLIER, /*!< Minimum CPU:FSB ratio for this CPU,
multiplied by 100. */
INFO_CUR_MULTIPLIER, /*!< Current CPU:FSB ratio, multiplied by 100.
e.g., a CPU:FSB value of 18.5 reads as
"1850". */
INFO_MAX_MULTIPLIER, /*!< Maximum CPU:FSB ratio for this CPU,
multiplied by 100. */
INFO_TEMPERATURE, /*!< The current core temperature in Celsius. */
INFO_THROTTLING, /*!< 1 if the current logical processor is
throttling. 0 if it is running normally. */
INFO_VOLTAGE, /*!< The current core voltage in Volt,
multiplied by 100. */
INFO_BCLK, /*!< See \ref INFO_BUS_CLOCK. */
INFO_BUS_CLOCK, /*!< The main bus clock in MHz,
e.g., FSB/QPI/DMI/HT base clock,
multiplied by 100. */
} cpu_msrinfo_request_t;
/**
* @brief Similar to \ref cpu_rdmsr, but extract a range of bits
*
* @param handle - a handle to the MSR reader driver, as created by
* cpu_msr_driver_open
* @param msr_index - the numeric ID of the MSR you want to read
* @param highbit - the high bit in range, must be inferior to 64
* @param lowbit - the low bit in range, must be equal or superior to 0
* @param result - a pointer to a 64-bit integer, where the MSR value is stored
*
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int cpu_rdmsr_range(struct msr_driver_t* handle, uint32_t msr_index, uint8_t highbit,
uint8_t lowbit, uint64_t* result);
/**
* @brief Reads extended CPU information from Model-Specific Registers.
* @param handle - a handle to an open MSR driver, @see cpu_msr_driver_open
* @param which - which info field should be returned. A list of
* available information entities is listed in the
* cpu_msrinfo_request_t enum.
* @retval - if the requested information is available for the current
* processor model, the respective value is returned.
* if no information is available, or the CPU doesn't support
* the query, the special value CPU_INVALID_VALUE is returned
* @note This function is not MT-safe. If you intend to call it from multiple
* threads, guard it through a mutex or a similar primitive.
*/
int cpu_msrinfo(struct msr_driver_t* handle, cpu_msrinfo_request_t which);
#define CPU_INVALID_VALUE 0x3fffffff
/**
* @brief Writes the raw MSR data to a text file
* @param data - a pointer to msr_driver_t structure
* @param filename - the path of the file, where the serialized data should be
* written. If empty, stdout will be used.
* @note This is intended primarily for debugging. On some processor, which is
* not currently supported or not completely recognized by cpu_identify,
* one can still successfully get the raw data and write it to a file.
* libcpuid developers can later import this file and debug the detection
* code as if running on the actual hardware.
* The file is simple text format of "something=value" pairs. Version info
* is also written, but the format is not intended to be neither backward-
* nor forward compatible.
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int msr_serialize_raw_data(struct msr_driver_t* handle, const char* filename);
/**
* @brief Closes an open MSR driver
*
* This function unloads the MSR driver opened by cpu_msr_driver_open and
* frees any resources associated with it.
*
* @param handle - a handle to the MSR reader driver, as created by
* cpu_msr_driver_open
*
* @returns zero if successful, and some negative number on error.
* The error message can be obtained by calling \ref cpuid_error.
* @see cpu_error_t
*/
int cpu_msr_driver_close(struct msr_driver_t* handle);
#ifdef __cplusplus
}; /* extern "C" */
#endif

View file

@ -32,6 +32,36 @@
#ifndef __LIBCPUID_TYPES_H__
#define __LIBCPUID_TYPES_H__
#include <stdint.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if defined(HAVE_STDINT_H)
# include <stdint.h>
#else
/* we have to provide our own: */
# if !defined(HAVE_INT32_T) && !defined(__int32_t_defined)
typedef int int32_t;
# endif
# if !defined(HAVE_UINT32_T) && !defined(__uint32_t_defined)
typedef unsigned uint32_t;
# endif
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
#if (defined _MSC_VER) && (_MSC_VER <= 1300)
/* MSVC 6.0: no long longs ... */
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
/* all other sane compilers: */
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#endif
#endif
#endif /* __LIBCPUID_TYPES_H__ */

View file

@ -32,6 +32,8 @@
#include "libcpuid.h"
#include "libcpuid_util.h"
int _current_verboselevel;
void match_features(const struct feature_map_t* matchtable, int count, uint32_t reg, struct cpu_id_t* data)
{
int i;
@ -42,6 +44,165 @@ void match_features(const struct feature_map_t* matchtable, int count, uint32_t
}
}
static void default_warn(const char* msg)
{
fprintf(stderr, "%s", msg);
}
libcpuid_warn_fn_t _warn_fun = default_warn;
#if defined(_MSC_VER)
# define vsnprintf _vsnprintf
#endif
void warnf(const char* format, ...)
{
char buff[1024];
va_list va;
if(!_warn_fun)
{
return;
}
va_start(va, format);
vsnprintf(buff, sizeof(buff), format, va);
va_end(va);
_warn_fun(buff);
}
void debugf(int verboselevel, const char* format, ...)
{
char buff[1024];
va_list va;
if(verboselevel > _current_verboselevel)
{
return;
}
va_start(va, format);
vsnprintf(buff, sizeof(buff), format, va);
va_end(va);
_warn_fun(buff);
}
static int popcount64(uint64_t mask)
{
int num_set_bits = 0;
while(mask)
{
mask &= mask - 1;
num_set_bits++;
}
return num_set_bits;
}
static int score(const struct match_entry_t* entry, const struct cpu_id_t* data,
int brand_code, uint64_t bits, int model_code)
{
int res = 0;
if(entry->family == data->family)
{
res += 2;
}
if(entry->model == data->model)
{
res += 2;
}
if(entry->stepping == data->stepping)
{
res += 2;
}
if(entry->ext_family == data->ext_family)
{
res += 2;
}
if(entry->ext_model == data->ext_model)
{
res += 2;
}
if(entry->ncores == data->num_cores)
{
res += 2;
}
if(entry->l2cache == data->l2_cache)
{
res += 1;
}
if(entry->l3cache == data->l3_cache)
{
res += 1;
}
if(entry->brand_code == brand_code)
{
res += 2;
}
if(entry->model_code == model_code)
{
res += 2;
}
res += popcount64(entry->model_bits & bits) * 2;
return res;
}
int match_cpu_codename(const struct match_entry_t* matchtable, int count,
struct cpu_id_t* data, int brand_code, uint64_t bits,
int model_code)
{
int bestscore = -1;
int bestindex = 0;
int i, t;
debugf(3, "Matching cpu f:%d, m:%d, s:%d, xf:%d, xm:%d, ncore:%d, l2:%d, bcode:%d, bits:%I64u, code:%d\n",
data->family, data->model, data->stepping, data->ext_family,
data->ext_model, data->num_cores, data->l2_cache, brand_code, (unsigned long long) bits, model_code);
for(i = 0; i < count; i++)
{
t = score(&matchtable[i], data, brand_code, bits, model_code);
debugf(3, "Entry %d, `%s', score %d\n", i, matchtable[i].name, t);
if(t > bestscore)
{
debugf(2, "Entry `%s' selected - best score so far (%d)\n", matchtable[i].name, t);
bestscore = t;
bestindex = i;
}
}
strcpy(data->cpu_codename, matchtable[bestindex].name);
return bestscore;
}
void generic_get_cpu_list(const struct match_entry_t* matchtable, int count,
struct cpu_list_t* list)
{
int i, j, n, good;
n = 0;
list->names = (char**) malloc(sizeof(char*) * count);
for(i = 0; i < count; i++)
{
if(strstr(matchtable[i].name, "Unknown"))
{
continue;
}
good = 1;
for(j = n - 1; j >= 0; j--)
if(!strcmp(list->names[j], matchtable[i].name))
{
good = 0;
break;
}
if(!good)
{
continue;
}
#if defined(_MSC_VER)
list->names[n++] = _strdup(matchtable[i].name);
#else
list->names[n++] = strdup(matchtable[i].name);
#endif
}
list->num_entries = n;
}
static int xmatch_entry(char c, const char* p)
{
int i, j;
@ -126,3 +287,21 @@ int match_all(uint64_t bits, uint64_t mask)
{
return (bits & mask) == mask;
}
void debug_print_lbits(int debuglevel, uint64_t mask)
{
int i, first = 0;
for(i = 0; i < 64; i++) if(mask & (((uint64_t) 1) << i))
{
if(first)
{
first = 0;
}
else
{
debugf(2, " + ");
}
debugf(2, "LBIT(%d)", i);
}
debugf(2, "\n");
}

View file

@ -50,6 +50,20 @@ struct match_entry_t
int match_cpu_codename(const struct match_entry_t* matchtable, int count,
struct cpu_id_t* data, int brand_code, uint64_t bits,
int model_code);
void warnf(const char* format, ...)
#ifdef __GNUC__
__attribute__((format(printf, 1, 2)))
#endif
;
void debugf(int verboselevel, const char* format, ...)
#ifdef __GNUC__
__attribute__((format(printf, 2, 3)))
#endif
;
void generic_get_cpu_list(const struct match_entry_t* matchtable, int count,
struct cpu_list_t* list);
/*
* Seek for a pattern in `haystack'.
* Pattern may be an fixed string, or contain the special metacharacters
@ -72,9 +86,15 @@ struct cpu_id_t* get_cached_cpuid(void);
/* returns true if all bits of mask are present in `bits'. */
int match_all(uint64_t bits, uint64_t mask);
/* print what bits a mask consists of */
void debug_print_lbits(int debuglevel, uint64_t mask);
/*
* Sets the current errno
*/
int set_error(cpu_error_t err);
extern libcpuid_warn_fn_t _warn_fun;
extern int _current_verboselevel;
#endif /* __LIBCPUID_UTIL_H__ */

595
src/3rdparty/libcpuid/msrdriver.c vendored Normal file
View file

@ -0,0 +1,595 @@
/*
* Copyright 2009 Veselin Georgiev,
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @File msrdriver.c
* @Brief Contains the binary images of the x86 and x64 MSR drivers for Windows
* @Date 2009-09-29
*
* The driver is courtesy of Nick 'Bombera' Gabareff, and its source is actually
* available, see the contrib/ dir.
*
* However, for simplicity, here we just include the images of the compiled .SYS
* files.
* They are extracted to the filesystem on demand and loaded in the kernel
* by the cpu_msr_driver_open() function
*/
#ifdef _WIN32
#include "asm-bits.h"
//begin {
int cc_x86driver_code_size = 4608;
uint8_t cc_x86driver_code[4608] =
{
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xb8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d,
0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20,
0x44, 0x4f, 0x53, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x9f, 0x99, 0x48, 0xdf, 0xdb, 0xf8, 0x26, 0x8c, 0xdb, 0xf8, 0x26, 0x8c, 0xdb, 0xf8, 0x26, 0x8c,
0xdb, 0xf8, 0x27, 0x8c, 0xdd, 0xf8, 0x26, 0x8c, 0x21, 0xdb, 0x3f, 0x8c, 0xd8, 0xf8, 0x26, 0x8c, 0xfc, 0x3e,
0x57, 0x8c, 0xda, 0xf8, 0x26, 0x8c, 0xfc, 0x3e, 0x5a, 0x8c, 0xda, 0xf8, 0x26, 0x8c, 0xfc, 0x3e, 0x5e, 0x8c,
0xda, 0xf8, 0x26, 0x8c, 0x52, 0x69, 0x63, 0x68, 0xdb, 0xf8, 0x26, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x4c, 0x01, 0x07, 0x00, 0x12, 0x9b, 0x9b, 0x4a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x02, 0x21, 0x0b, 0x01, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0xa9, 0xd1, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xc0, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x74,
0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x68, 0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x00, 0x48, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xc8, 0x50, 0x41, 0x47, 0x45, 0x30, 0x44, 0x45, 0x46,
0x8c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x49, 0x4e, 0x49, 0x54,
0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xe2,
0x2e, 0x72, 0x73, 0x72, 0x63, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x42, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x63, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x70,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x4c,
0x24, 0x08, 0x83, 0x61, 0x18, 0x00, 0x83, 0x61, 0x1c, 0x00, 0x32, 0xd2, 0xff, 0x15, 0x08, 0x20, 0x01, 0x00,
0x33, 0xc0, 0xc2, 0x08, 0x00, 0x56, 0x8b, 0x74, 0x24, 0x0c, 0x8b, 0x46, 0x60, 0x81, 0x78, 0x0c, 0x0c, 0xe0,
0x22, 0x00, 0x57, 0x75, 0x3c, 0x83, 0x78, 0x04, 0x08, 0x72, 0x36, 0x83, 0x78, 0x08, 0x04, 0x75, 0x07, 0x8b,
0x46, 0x0c, 0x8b, 0x08, 0xeb, 0x05, 0xb9, 0x9c, 0x01, 0x00, 0x00, 0x8b, 0x7e, 0x0c, 0x0f, 0x32, 0x89, 0x07,
0x89, 0x57, 0x04, 0xc7, 0x46, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x33, 0xff, 0x32, 0xd2, 0x8b, 0xce, 0xff, 0x15,
0x08, 0x20, 0x01, 0x00, 0x8b, 0xc7, 0x5f, 0x5e, 0xc2, 0x08, 0x00, 0x83, 0x66, 0x1c, 0x00, 0xbf, 0x01, 0x00,
0x00, 0xc0, 0x89, 0x7e, 0x18, 0xeb, 0xe1, 0x55, 0x8b, 0xec, 0x51, 0x51, 0x8b, 0x45, 0x08, 0xff, 0x70, 0x04,
0xff, 0x15, 0x04, 0x20, 0x01, 0x00, 0x68, 0x3c, 0x20, 0x01, 0x00, 0x8d, 0x45, 0xf8, 0x50, 0xff, 0x15, 0x00,
0x20, 0x01, 0x00, 0x8d, 0x45, 0xf8, 0x50, 0xff, 0x15, 0x14, 0x20, 0x01, 0x00, 0xc9, 0xc2, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0x86, 0x50, 0x00, 0x00,
0x9c, 0x50, 0x00, 0x00, 0xb4, 0x50, 0x00, 0x00, 0x44, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00,
0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00,
0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x44, 0x00, 0x6f, 0x00,
0x73, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x5c, 0x00,
0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x8b, 0xec, 0x83,
0xec, 0x14, 0x56, 0x8b, 0x35, 0x00, 0x20, 0x01, 0x00, 0x57, 0x68, 0x1c, 0x20, 0x01, 0x00, 0x8d, 0x45, 0xf4,
0x50, 0xff, 0xd6, 0x8b, 0x7d, 0x08, 0x8d, 0x45, 0xfc, 0x50, 0x6a, 0x00, 0x6a, 0x00, 0x6a, 0x22, 0x8d, 0x45,
0xf4, 0x50, 0x6a, 0x04, 0x57, 0xff, 0x15, 0x10, 0x20, 0x01, 0x00, 0x85, 0xc0, 0x75, 0x4f, 0x68, 0x3c, 0x20,
0x01, 0x00, 0x8d, 0x45, 0xec, 0x50, 0xff, 0xd6, 0x8d, 0x45, 0xf4, 0x50, 0x8d, 0x45, 0xec, 0x50, 0xff, 0x15,
0x0c, 0x20, 0x01, 0x00, 0x8b, 0xf0, 0x85, 0xf6, 0x74, 0x0d, 0xff, 0x75, 0xfc, 0xff, 0x15, 0x04, 0x20, 0x01,
0x00, 0x8b, 0xc6, 0xeb, 0x23, 0x8b, 0x45, 0xfc, 0xa3, 0x00, 0x30, 0x01, 0x00, 0xb8, 0x00, 0x10, 0x01, 0x00,
0x89, 0x47, 0x38, 0x89, 0x47, 0x40, 0xc7, 0x47, 0x34, 0x75, 0x10, 0x01, 0x00, 0xc7, 0x47, 0x70, 0x19, 0x10,
0x01, 0x00, 0x33, 0xc0, 0x5f, 0x5e, 0xc9, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x28, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x50,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0x86, 0x50,
0x00, 0x00, 0x9c, 0x50, 0x00, 0x00, 0xb4, 0x50, 0x00, 0x00, 0x44, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4b, 0x01, 0x49, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63,
0x4c, 0x69, 0x6e, 0x6b, 0x00, 0x00, 0x0b, 0x04, 0x52, 0x74, 0x6c, 0x49, 0x6e, 0x69, 0x74, 0x55, 0x6e, 0x69,
0x63, 0x6f, 0x64, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x49, 0x01, 0x49, 0x6f, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0xda, 0x01, 0x49, 0x6f, 0x66, 0x43,
0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x00, 0x41, 0x01,
0x49, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63, 0x4c, 0x69,
0x6e, 0x6b, 0x00, 0x00, 0x38, 0x01, 0x49, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69,
0x63, 0x65, 0x00, 0x00, 0x6e, 0x74, 0x6f, 0x73, 0x6b, 0x72, 0x6e, 0x6c, 0x2e, 0x65, 0x78, 0x65, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x00, 0x00, 0x30, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x09, 0x04, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x5c, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5c, 0x03, 0x34, 0x00, 0x00, 0x00, 0x56, 0x00, 0x53, 0x00, 0x5f, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00,
0x53, 0x00, 0x49, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x5f, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x46, 0x00, 0x4f, 0x00,
0x00, 0x00, 0x00, 0x00, 0xbd, 0x04, 0xef, 0xfe, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xba, 0x02, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00,
0x67, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00,
0x00, 0x00, 0x96, 0x02, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x34, 0x00, 0x30, 0x00, 0x39, 0x00, 0x30, 0x00,
0x34, 0x00, 0x62, 0x00, 0x30, 0x00, 0x00, 0x00, 0x58, 0x00, 0x20, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00,
0x6d, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x53, 0x00,
0x52, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00,
0x33, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00,
0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x64, 0x00, 0x72, 0x00, 0x69, 0x00, 0x76, 0x00,
0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x42, 0x00, 0x11, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00,
0x70, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00,
0x00, 0x00, 0x49, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x65, 0x00,
0x65, 0x00, 0x64, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x60, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x44, 0x00,
0x65, 0x00, 0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00,
0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00,
0x20, 0x00, 0x33, 0x00, 0x32, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x4b, 0x00,
0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x64, 0x00,
0x75, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x36, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00,
0x6c, 0x00, 0x65, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00,
0x2c, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00, 0x49, 0x00,
0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x4e, 0x00, 0x61, 0x00,
0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x13, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x65, 0x00, 0x67, 0x00, 0x61, 0x00,
0x6c, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00,
0x74, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x47, 0x00, 0x61, 0x00,
0x62, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x76, 0x00, 0x20, 0x00, 0x27, 0x00, 0x32, 0x00, 0x30, 0x00,
0x30, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x4f, 0x00, 0x72, 0x00,
0x69, 0x00, 0x67, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00,
0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00,
0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00,
0x54, 0x00, 0x1a, 0x00, 0x01, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00,
0x74, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x6f, 0x00,
0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x32, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x70, 0x00,
0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00,
0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x0b, 0x00, 0x01, 0x00,
0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00, 0x56, 0x00, 0x65, 0x00,
0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x20, 0x00,
0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x00, 0x61, 0x00, 0x72, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00,
0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x04, 0x00,
0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x74, 0x00,
0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x10, 0x30, 0x5c, 0x30, 0x82, 0x30, 0x87, 0x30, 0x91, 0x30, 0x9b, 0x30, 0x00, 0x40, 0x00, 0x00, 0x1c, 0x00,
0x00, 0x00, 0x09, 0x30, 0x0f, 0x30, 0x2f, 0x30, 0x38, 0x30, 0x4c, 0x30, 0x5b, 0x30, 0x67, 0x30, 0x6c, 0x30,
0x79, 0x30, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
int cc_x64driver_code_size = 5120;
uint8_t cc_x64driver_code[5120] =
{
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xb8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d,
0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20,
0x44, 0x4f, 0x53, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xb7, 0x04, 0xa8, 0xc2, 0xf3, 0x65, 0xc6, 0x91, 0xf3, 0x65, 0xc6, 0x91, 0xf3, 0x65, 0xc6, 0x91,
0xf3, 0x65, 0xc7, 0x91, 0xf4, 0x65, 0xc6, 0x91, 0x85, 0xf8, 0xbd, 0x91, 0xf0, 0x65, 0xc6, 0x91, 0x85, 0xf8,
0xab, 0x91, 0xf0, 0x65, 0xc6, 0x91, 0x30, 0x6a, 0x98, 0x91, 0xf2, 0x65, 0xc6, 0x91, 0x85, 0xf8, 0xbe, 0x91,
0xf2, 0x65, 0xc6, 0x91, 0x52, 0x69, 0x63, 0x68, 0xf3, 0x65, 0xc6, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x64, 0x86, 0x07, 0x00,
0x41, 0xc8, 0x6d, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x22, 0x00, 0x0b, 0x02,
0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x60, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x79, 0x44, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x60, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
0x00, 0x70, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00,
0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x00, 0x10,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x68, 0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x48, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00,
0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xc8, 0x2e, 0x70,
0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x48, 0x50, 0x41, 0x47, 0x45, 0x30, 0x44, 0x45, 0x46, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x49, 0x4e, 0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00,
0x00, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xe2, 0x2e, 0x72, 0x73, 0x72, 0x63, 0x00, 0x00, 0x00,
0xc0, 0x03, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0xec, 0x28,
0x33, 0xc9, 0x48, 0x8b, 0xc2, 0x89, 0x4a, 0x30, 0x48, 0x89, 0x4a, 0x38, 0x33, 0xd2, 0x48, 0x8b, 0xc8, 0xff,
0x15, 0xfd, 0x0f, 0x00, 0x00, 0x33, 0xc0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x48, 0x83, 0xec, 0x28, 0x48, 0x8b, 0x82, 0xb8, 0x00, 0x00,
0x00, 0x4c, 0x8b, 0xca, 0x81, 0x78, 0x18, 0x0c, 0xe0, 0x22, 0x00, 0x75, 0x43, 0x83, 0x78, 0x08, 0x08, 0x72,
0x3d, 0x83, 0x78, 0x10, 0x04, 0x75, 0x08, 0x48, 0x8b, 0x42, 0x18, 0x8b, 0x08, 0xeb, 0x05, 0xb9, 0x9c, 0x01,
0x00, 0x00, 0x4c, 0x8b, 0x42, 0x18, 0x0f, 0x32, 0x48, 0xc1, 0xe2, 0x20, 0x49, 0x8b, 0xc9, 0x48, 0x0b, 0xc2,
0x33, 0xd2, 0x49, 0x89, 0x00, 0x49, 0xc7, 0x41, 0x38, 0x08, 0x00, 0x00, 0x00, 0xff, 0x15, 0x95, 0x0f, 0x00,
0x00, 0x33, 0xc0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xc7, 0x42, 0x30, 0x01, 0x00, 0x00, 0xc0, 0x48, 0xc7, 0x42,
0x38, 0x00, 0x00, 0x00, 0x00, 0x49, 0x8b, 0xc9, 0x33, 0xd2, 0xff, 0x15, 0x74, 0x0f, 0x00, 0x00, 0xb8, 0x01,
0x00, 0x00, 0xc0, 0x48, 0x83, 0xc4, 0x28, 0xc3, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x48, 0x83, 0xec, 0x38, 0x48, 0x8b, 0x49, 0x08, 0xff, 0x15,
0x32, 0x0f, 0x00, 0x00, 0x48, 0x8d, 0x15, 0x1b, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x4c, 0x24, 0x20, 0xff, 0x15,
0x18, 0x0f, 0x00, 0x00, 0x48, 0x8d, 0x4c, 0x24, 0x20, 0xff, 0x15, 0x05, 0x0f, 0x00, 0x00, 0x48, 0x83, 0xc4,
0x38, 0xc3, 0x5c, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00,
0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00,
0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x61, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x41, 0xc8, 0x6d, 0x49, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
0x5c, 0x20, 0x00, 0x00, 0x5c, 0x06, 0x00, 0x00, 0x52, 0x53, 0x44, 0x53, 0xd9, 0x5e, 0xab, 0x47, 0xc4, 0xf2,
0x4f, 0x40, 0xaa, 0xe9, 0x90, 0x47, 0x67, 0x30, 0xa5, 0xfa, 0x03, 0x00, 0x00, 0x00, 0x44, 0x3a, 0x5c, 0x74,
0x6d, 0x70, 0x5c, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5c, 0x6f, 0x62, 0x6a, 0x66, 0x72, 0x65, 0x5f, 0x77,
0x6e, 0x65, 0x74, 0x5f, 0x41, 0x4d, 0x44, 0x36, 0x34, 0x5c, 0x61, 0x6d, 0x64, 0x36, 0x34, 0x5c, 0x54, 0x6d,
0x70, 0x52, 0x64, 0x72, 0x2e, 0x70, 0x64, 0x62, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x04, 0x42,
0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x04, 0x42, 0x00, 0x00, 0x01, 0x04, 0x01, 0x00, 0x04, 0x62, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x10, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0xe4, 0x20, 0x00, 0x00, 0x21, 0x08,
0x02, 0x00, 0x08, 0x74, 0x13, 0x00, 0x10, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0xe4, 0x20, 0x00, 0x00,
0x01, 0x0c, 0x03, 0x00, 0x0c, 0x34, 0x12, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xcd, 0x5d, 0x20, 0xd2, 0x66, 0xd4, 0xff, 0xff, 0x32, 0xa2, 0xdf, 0x2d, 0x99, 0x2b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x32, 0x10, 0x00, 0x00, 0xa8, 0x20, 0x00, 0x00, 0x40, 0x10,
0x00, 0x00, 0xbe, 0x10, 0x00, 0x00, 0xb0, 0x20, 0x00, 0x00, 0xd0, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
0xb8, 0x20, 0x00, 0x00, 0x10, 0x50, 0x00, 0x00, 0x74, 0x50, 0x00, 0x00, 0xe4, 0x20, 0x00, 0x00, 0x74, 0x50,
0x00, 0x00, 0xe8, 0x50, 0x00, 0x00, 0xd0, 0x20, 0x00, 0x00, 0xe8, 0x50, 0x00, 0x00, 0xf5, 0x50, 0x00, 0x00,
0xc0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0xec, 0x78, 0x48, 0x89, 0x9c, 0x24,
0x90, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xd9, 0x48, 0x8d, 0x15, 0x0a, 0x01, 0x00, 0x00, 0x48, 0x8d, 0x4c, 0x24,
0x48, 0xff, 0x15, 0xd7, 0xcf, 0xff, 0xff, 0x41, 0xb9, 0x22, 0x00, 0x00, 0x00, 0x4c, 0x8d, 0x5c, 0x24, 0x40,
0x4c, 0x89, 0x5c, 0x24, 0x30, 0x4c, 0x8d, 0x44, 0x24, 0x48, 0x41, 0x8d, 0x51, 0xe6, 0x48, 0x8b, 0xcb, 0xc6,
0x44, 0x24, 0x28, 0x00, 0xc7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0xff, 0x15, 0xc0, 0xcf, 0xff, 0xff,
0x85, 0xc0, 0x0f, 0x85, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x15, 0x91, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x4c,
0x24, 0x58, 0x48, 0x89, 0xbc, 0x24, 0x98, 0x00, 0x00, 0x00, 0xff, 0x15, 0x86, 0xcf, 0xff, 0xff, 0x48, 0x8d,
0x54, 0x24, 0x48, 0x48, 0x8d, 0x4c, 0x24, 0x58, 0xff, 0x15, 0x86, 0xcf, 0xff, 0xff, 0x85, 0xc0, 0x8b, 0xf8,
0x74, 0x0f, 0x48, 0x8b, 0x4c, 0x24, 0x40, 0xff, 0x15, 0x6d, 0xcf, 0xff, 0xff, 0x8b, 0xc7, 0xeb, 0x39, 0x48,
0x8b, 0x44, 0x24, 0x40, 0x48, 0x89, 0x05, 0x5d, 0xe0, 0xff, 0xff, 0x48, 0x8d, 0x05, 0x16, 0xc0, 0xff, 0xff,
0x48, 0x89, 0x43, 0x68, 0x48, 0x8d, 0x05, 0x4b, 0xbf, 0xff, 0xff, 0x48, 0x89, 0x43, 0x70, 0x48, 0x89, 0x83,
0x80, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x05, 0x69, 0xbf, 0xff, 0xff, 0x48, 0x89, 0x83, 0xe0, 0x00, 0x00, 0x00,
0x33, 0xc0, 0x48, 0x8b, 0xbc, 0x24, 0x98, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x9c, 0x24, 0x90, 0x00, 0x00, 0x00,
0x48, 0x83, 0xc4, 0x78, 0xc3, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x5c, 0x00,
0x44, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00,
0x73, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00,
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x5c, 0x00, 0x44, 0x00, 0x65, 0x00, 0x76, 0x00,
0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00,
0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x8b, 0x05, 0xf1, 0xd0, 0xff, 0xff, 0x49, 0xb9, 0x32, 0xa2, 0xdf, 0x2d, 0x99, 0x2b, 0x00, 0x00, 0x48,
0x85, 0xc0, 0x74, 0x05, 0x49, 0x3b, 0xc1, 0x75, 0x2f, 0x4c, 0x8d, 0x05, 0xd6, 0xd0, 0xff, 0xff, 0x48, 0xb8,
0x20, 0x03, 0x00, 0x00, 0x80, 0xf7, 0xff, 0xff, 0x48, 0x8b, 0x00, 0x49, 0x33, 0xc0, 0x49, 0xb8, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x49, 0x23, 0xc0, 0x49, 0x0f, 0x44, 0xc1, 0x48, 0x89, 0x05, 0xae, 0xd0,
0xff, 0xff, 0x48, 0xf7, 0xd0, 0x48, 0x89, 0x05, 0x9c, 0xd0, 0xff, 0xff, 0xe9, 0xa7, 0xef, 0xff, 0xff, 0xcc,
0xcc, 0xcc, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x61, 0x00, 0x00,
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x61,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x49, 0x6f, 0x66, 0x43,
0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x00, 0x00, 0x61, 0x01,
0x49, 0x6f, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63, 0x4c, 0x69,
0x6e, 0x6b, 0x00, 0x00, 0x3e, 0x04, 0x52, 0x74, 0x6c, 0x49, 0x6e, 0x69, 0x74, 0x55, 0x6e, 0x69, 0x63, 0x6f,
0x64, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x5f, 0x01, 0x49, 0x6f, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x55, 0x01, 0x49, 0x6f, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, 0x63, 0x4c, 0x69, 0x6e, 0x6b, 0x00, 0x00, 0x4c, 0x01,
0x49, 0x6f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x00, 0x6e, 0x74,
0x6f, 0x73, 0x6b, 0x72, 0x6e, 0x6c, 0x2e, 0x65, 0x78, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x09, 0x04, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x60, 0x70, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03,
0x34, 0x00, 0x00, 0x00, 0x56, 0x00, 0x53, 0x00, 0x5f, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 0x53, 0x00,
0x49, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x5f, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x00, 0x00,
0x00, 0x00, 0xbd, 0x04, 0xef, 0xfe, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xbe, 0x02, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00,
0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x00, 0x00,
0x9a, 0x02, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x34, 0x00, 0x30, 0x00, 0x39, 0x00, 0x30, 0x00, 0x34, 0x00,
0x62, 0x00, 0x30, 0x00, 0x00, 0x00, 0x58, 0x00, 0x20, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00,
0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x53, 0x00, 0x52, 0x00,
0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x36, 0x00,
0x34, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x65, 0x00, 0x72, 0x00,
0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x64, 0x00, 0x72, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00,
0x72, 0x00, 0x00, 0x00, 0x42, 0x00, 0x11, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00,
0x61, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00,
0x49, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x53, 0x00, 0x74, 0x00, 0x65, 0x00, 0x65, 0x00,
0x64, 0x00, 0x73, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x44, 0x00, 0x65, 0x00,
0x73, 0x00, 0x63, 0x00, 0x72, 0x00, 0x69, 0x00, 0x70, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x20, 0x00,
0x36, 0x00, 0x34, 0x00, 0x2d, 0x00, 0x62, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x4b, 0x00, 0x65, 0x00,
0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00,
0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x36, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00,
0x65, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00,
0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x01, 0x00, 0x49, 0x00, 0x6e, 0x00,
0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00,
0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00, 0x64, 0x00, 0x72, 0x00, 0x00, 0x00,
0x00, 0x00, 0x4a, 0x00, 0x13, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x65, 0x00, 0x67, 0x00, 0x61, 0x00, 0x6c, 0x00,
0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00,
0x00, 0x00, 0x4e, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x47, 0x00, 0x61, 0x00, 0x62, 0x00,
0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x76, 0x00, 0x20, 0x00, 0x27, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00,
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x4f, 0x00, 0x72, 0x00, 0x69, 0x00,
0x67, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x65, 0x00,
0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x52, 0x00,
0x64, 0x00, 0x72, 0x00, 0x36, 0x00, 0x34, 0x00, 0x2e, 0x00, 0x73, 0x00, 0x79, 0x00, 0x73, 0x00, 0x00, 0x00,
0x00, 0x00, 0x54, 0x00, 0x1a, 0x00, 0x01, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00,
0x63, 0x00, 0x74, 0x00, 0x4e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00,
0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x32, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 0x00, 0x6d, 0x00,
0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00,
0x52, 0x00, 0x65, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x0b, 0x00,
0x01, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, 0x00, 0x63, 0x00, 0x74, 0x00, 0x56, 0x00,
0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x31, 0x00, 0x2c, 0x00,
0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00,
0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x00, 0x61, 0x00, 0x72, 0x00, 0x46, 0x00, 0x69, 0x00,
0x6c, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
0x04, 0x00, 0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x6c, 0x00, 0x61, 0x00,
0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x04, 0xb0, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
//} end
#endif // _WIN32
int msrdriver_dummy; // a dummy to avoid a linker warning on OS X.

1291
src/3rdparty/libcpuid/rdmsr.c vendored Normal file

File diff suppressed because it is too large Load diff

409
src/3rdparty/libcpuid/rdtsc.c vendored Normal file
View file

@ -0,0 +1,409 @@
/*
* Copyright 2008 Veselin Georgiev,
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include "libcpuid.h"
#include "libcpuid_util.h"
#include "asm-bits.h"
#include "rdtsc.h"
#ifdef _WIN32
#include <windows.h>
void sys_precise_clock(uint64_t* result)
{
double c, f;
LARGE_INTEGER freq, counter;
QueryPerformanceCounter(&counter);
QueryPerformanceFrequency(&freq);
c = (double) counter.QuadPart;
f = (double) freq.QuadPart;
*result = (uint64_t)(c * 1000000.0 / f);
}
#else
/* assuming Linux, Mac OS or other POSIX */
#include <sys/time.h>
void sys_precise_clock(uint64_t* result)
{
struct timeval tv;
gettimeofday(&tv, NULL);
*result = (uint64_t) tv.tv_sec * (uint64_t) 1000000 +
(uint64_t) tv.tv_usec;
}
#endif /* _WIN32 */
/* out = a - b */
static void mark_t_subtract(struct cpu_mark_t* a, struct cpu_mark_t* b, struct cpu_mark_t* out)
{
out->tsc = a->tsc - b->tsc;
out->sys_clock = a->sys_clock - b->sys_clock;
}
void cpu_tsc_mark(struct cpu_mark_t* mark)
{
cpu_rdtsc(&mark->tsc);
sys_precise_clock(&mark->sys_clock);
}
void cpu_tsc_unmark(struct cpu_mark_t* mark)
{
struct cpu_mark_t temp;
cpu_tsc_mark(&temp);
mark_t_subtract(&temp, mark, mark);
}
int cpu_clock_by_mark(struct cpu_mark_t* mark)
{
uint64_t result;
/* Check if some subtraction resulted in a negative number: */
if((mark->tsc >> 63) != 0 || (mark->sys_clock >> 63) != 0)
{
return -1;
}
/* Divide-by-zero check: */
if(mark->sys_clock == 0)
{
return -1;
}
/* Check if the result fits in 32bits */
result = mark->tsc / mark->sys_clock;
if(result > (uint64_t) 0x7fffffff)
{
return -1;
}
return (int) result;
}
#ifdef _WIN32
int cpu_clock_by_os(void)
{
HKEY key;
DWORD result;
DWORD size = 4;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), 0, KEY_READ,
&key) != ERROR_SUCCESS)
{
return -1;
}
if(RegQueryValueEx(key, TEXT("~MHz"), NULL, NULL, (LPBYTE) &result, (LPDWORD) &size) != ERROR_SUCCESS)
{
RegCloseKey(key);
return -1;
}
RegCloseKey(key);
return (int)result;
}
#else
#ifdef __APPLE__
#include <sys/types.h>
#include <sys/sysctl.h>
/* Assuming Mac OS X with hw.cpufrequency sysctl */
int cpu_clock_by_os(void)
{
long long result = -1;
size_t size = sizeof(result);
if(sysctlbyname("hw.cpufrequency", &result, &size, NULL, 0))
{
return -1;
}
return (int)(result / (long long) 1000000);
}
#else
/* Assuming Linux with /proc/cpuinfo */
int cpu_clock_by_os(void)
{
FILE* f;
char line[1024], *s;
int result;
f = fopen("/proc/cpuinfo", "rt");
if(!f)
{
return -1;
}
while(fgets(line, sizeof(line), f))
{
if(!strncmp(line, "cpu MHz", 7))
{
s = strchr(line, ':');
if(s && 1 == sscanf(s, ":%d.", &result))
{
fclose(f);
return result;
}
}
}
fclose(f);
return -1;
}
#endif /* __APPLE__ */
#endif /* _WIN32 */
/* Emulate doing useful CPU intensive work */
static int busy_loop(int amount)
{
int i, j, k, s = 0;
static volatile int data[42] = {32, 12, -1, 5, 23, 0 };
for(i = 0; i < amount; i++)
for(j = 0; j < 65536; j++)
for(k = 0; k < 42; k++)
{
s += data[k];
}
return s;
}
int busy_loop_delay(int milliseconds)
{
int cycles = 0, r = 0, first = 1;
uint64_t a, b, c;
sys_precise_clock(&a);
while(1)
{
sys_precise_clock(&c);
if((c - a) / 1000 > milliseconds)
{
return r;
}
r += busy_loop(cycles);
if(first)
{
first = 0;
}
else
{
if(c - b < 1000)
{
cycles *= 2;
}
if(c - b > 10000)
{
cycles /= 2;
}
}
b = c;
}
}
int cpu_clock_measure(int millis, int quad_check)
{
struct cpu_mark_t begin[4], end[4], temp, temp2;
int results[4], cycles, n, k, i, j, bi, bj, mdiff, diff, _zero = 0;
uint64_t tl;
if(millis < 1)
{
return -1;
}
tl = millis * (uint64_t) 1000;
if(quad_check)
{
tl /= 4;
}
n = quad_check ? 4 : 1;
cycles = 1;
for(k = 0; k < n; k++)
{
cpu_tsc_mark(&begin[k]);
end[k] = begin[k];
do
{
/* Run busy loop, and fool the compiler that we USE the garbishy
value it calculates */
_zero |= (1 & busy_loop(cycles));
cpu_tsc_mark(&temp);
mark_t_subtract(&temp, &end[k], &temp2);
/* If busy loop is too short, increase it */
if(temp2.sys_clock < tl / 8)
{
cycles *= 2;
}
end[k] = temp;
}
while(end[k].sys_clock - begin[k].sys_clock < tl);
mark_t_subtract(&end[k], &begin[k], &temp);
results[k] = cpu_clock_by_mark(&temp);
}
if(n == 1)
{
return results[0];
}
mdiff = 0x7fffffff;
bi = bj = -1;
for(i = 0; i < 4; i++)
{
for(j = i + 1; j < 4; j++)
{
diff = results[i] - results[j];
if(diff < 0)
{
diff = -diff;
}
if(diff < mdiff)
{
mdiff = diff;
bi = i;
bj = j;
}
}
}
if(results[bi] == -1)
{
return -1;
}
return (results[bi] + results[bj] + _zero) / 2;
}
static void adjust_march_ic_multiplier(const struct cpu_id_t* id, int* numerator, int* denom)
{
/*
* for cpu_clock_by_ic: we need to know how many clocks does a typical ADDPS instruction
* take, when issued in rapid succesion without dependencies. The whole idea of
* cpu_clock_by_ic was that this is easy to determine, at least it was back in 2010. Now
* it's getting progressively more hairy, but here are the current measurements:
*
* 1. For CPUs with 64-bit SSE units, ADDPS issue rate is 0.5 IPC (one insn in 2 clocks)
* 2. For CPUs with 128-bit SSE units, issue rate is exactly 1.0 IPC
* 3. For Bulldozer and later, it is 1.4 IPC (we multiply by 5/7)
* 4. For Skylake and later, it is 1.6 IPC (we multiply by 5/8)
*/
//
if(id->sse_size < 128)
{
debugf(1, "SSE execution path is 64-bit\n");
// on a CPU with half SSE unit length, SSE instructions execute at 0.5 IPC;
// the resulting value must be multiplied by 2:
*numerator = 2;
}
else
{
debugf(1, "SSE execution path is 128-bit\n");
}
//
// Bulldozer or later: assume 1.4 IPC
if(id->vendor == VENDOR_AMD && id->ext_family >= 21)
{
debugf(1, "cpu_clock_by_ic: Bulldozer (or later) detected, dividing result by 1.4\n");
*numerator = 5;
*denom = 7; // multiply by 5/7, to divide by 1.4
}
//
// Skylake or later: assume 1.6 IPC
if(id->vendor == VENDOR_INTEL && id->ext_model >= 94)
{
debugf(1, "cpu_clock_by_ic: Skylake (or later) detected, dividing result by 1.6\n");
*numerator = 5;
*denom = 8; // to divide by 1.6, multiply by 5/8
}
}
int cpu_clock_by_ic(int millis, int runs)
{
int max_value = 0, cur_value, i, ri, cycles_inner, cycles_outer, c;
struct cpu_id_t* id;
uint64_t t0, t1, tl, hz;
int multiplier_numerator = 1, multiplier_denom = 1;
if(millis <= 0 || runs <= 0)
{
return -2;
}
id = get_cached_cpuid();
// if there aren't SSE instructions - we can't run the test at all
if(!id || !id->flags[CPU_FEATURE_SSE])
{
return -1;
}
//
adjust_march_ic_multiplier(id, &multiplier_numerator, &multiplier_denom);
//
tl = millis * 125; // (*1000 / 8)
cycles_inner = 128;
cycles_outer = 1;
do
{
if(cycles_inner < 1000000000)
{
cycles_inner *= 2;
}
else
{
cycles_outer *= 2;
}
sys_precise_clock(&t0);
for(i = 0; i < cycles_outer; i++)
{
busy_sse_loop(cycles_inner);
}
sys_precise_clock(&t1);
}
while(t1 - t0 < tl);
debugf(2, "inner: %d, outer: %d\n", cycles_inner, cycles_outer);
for(ri = 0; ri < runs; ri++)
{
sys_precise_clock(&t0);
c = 0;
do
{
c++;
for(i = 0; i < cycles_outer; i++)
{
busy_sse_loop(cycles_inner);
}
sys_precise_clock(&t1);
}
while(t1 - t0 < tl * (uint64_t) 8);
// cpu_Hz = cycles_inner * cycles_outer * 256 / (t1 - t0) * 1000000
debugf(2, "c = %d, td = %d\n", c, (int)(t1 - t0));
hz = ((uint64_t) cycles_inner * (uint64_t) 256 + 12) *
(uint64_t) cycles_outer * (uint64_t) multiplier_numerator * (uint64_t) c * (uint64_t) 1000000
/ ((t1 - t0) * (uint64_t) multiplier_denom);
cur_value = (int)(hz / 1000000);
if(cur_value > max_value)
{
max_value = cur_value;
}
}
return max_value;
}
int cpu_clock(void)
{
int result;
result = cpu_clock_by_os();
if(result <= 0)
{
result = cpu_clock_measure(200, 1);
}
return result;
}

33
src/3rdparty/libcpuid/rdtsc.h vendored Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright 2010 Veselin Georgiev,
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RDTSC_H__
#define __RDTSC_H__
void sys_precise_clock(uint64_t* result);
int busy_loop_delay(int milliseconds);
#endif /* __RDTSC_H__ */

View file

@ -58,6 +58,238 @@ enum _amd_model_codes_t
_1600,
};
const struct match_entry_t cpudb_amd[] =
{
{ -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD CPU" },
/* 486 and the likes */
{ 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 486" },
{ 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2" },
{ 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX2WB" },
{ 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4" },
{ 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "AMD 486DX4WB" },
/* Pentia clones */
{ 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown AMD 586" },
{ 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
{ 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
{ 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
{ 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K5" },
/* The K6 */
{ 5, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" },
{ 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6" },
{ 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2" },
{ 5, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-III" },
{ 5, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
{ 5, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
{ 5, 12, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown K6" },
{ 5, 13, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "K6-2+" },
/* Athlon et al. */
{ 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" },
{ 6, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (Slot-A)" },
{ 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Duron (Spitfire)" },
{ 6, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon (ThunderBird)" },
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon" },
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon (Palomino)" },
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _MP_ , 0, "Athlon MP (Palomino)" },
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Palomino)" },
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP" },
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Athlon XP" },
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Morgan)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ , 0, "Athlon XP (Thoroughbred)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP (Thoroughbred)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, DURON_ , 0, "Duron (Applebred)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
{ 6, 8, -1, -1, -1, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
{ 6, 8, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thoroughbred)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _MP_ , 0, "Athlon MP (Thoroughbred)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ , 0, "Mobile Athlon (T-Bred)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ | _LV_, 0, "Mobile Athlon (T-Bred)" },
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Athlon XP (Barton)" },
{ 6, 10, -1, -1, -1, 1, 512, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP (Barton)" },
{ 6, 10, -1, -1, -1, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron (Barton)" },
{ 6, 10, -1, -1, -1, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron (Thorton)" },
{ 6, 10, -1, -1, -1, 1, 256, -1, NC, ATHLON_ | _XP_ , 0, "Athlon XP (Thorton)" },
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _MP_ , 0, "Athlon MP (Barton)" },
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ , 0, "Mobile Athlon (Barton)" },
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, ATHLON_ | _XP_ | _M_ | _LV_, 0, "Mobile Athlon (Barton)" },
/* K8 Architecture */
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown K8" },
{ 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Unknown K9" },
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, 0 , 0, "Unknown A64" },
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" },
{ 15, -1, -1, 15, -1, 2, -1, -1, NC, OPTERON_ | _X2 , 0, "Opteron (Dual Core)" },
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, OPTERON_ , 0, "Opteron" },
{ 15, 3, -1, 15, -1, 2, -1, -1, NC, OPTERON_ | _X2 , 0, "Opteron (Dual Core)" },
{ 15, -1, -1, 15, -1, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (512K)" },
{ 15, -1, -1, 15, -1, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (1024K)" },
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_ | _FX , 0, "Athlon FX" },
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, ATHLON_ | _64_ | _FX , 0, "Athlon 64 FX" },
{ 15, 3, -1, 15, 35, 2, -1, -1, NC, ATHLON_ | _64_ | _FX , 0, "Athlon 64 FX X2 (Toledo)" },
{ 15, -1, -1, 15, -1, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (512K)" },
{ 15, -1, -1, 15, -1, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (1024K)" },
{ 15, -1, -1, 15, -1, 1, 512, -1, NC, TURION_ | _64_ , 0, "Turion 64 (512K)" },
{ 15, -1, -1, 15, -1, 1, 1024, -1, NC, TURION_ | _64_ , 0, "Turion 64 (1024K)" },
{ 15, -1, -1, 15, -1, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion 64 X2 (512K)" },
{ 15, -1, -1, 15, -1, 2, 1024, -1, NC, TURION_ | _X2 , 0, "Turion 64 X2 (1024K)" },
{ 15, -1, -1, 15, -1, 1, 128, -1, NC, SEMPRON_ , 0, "A64 Sempron (128K)" },
{ 15, -1, -1, 15, -1, 1, 256, -1, NC, SEMPRON_ , 0, "A64 Sempron (256K)" },
{ 15, -1, -1, 15, -1, 1, 512, -1, NC, SEMPRON_ , 0, "A64 Sempron (512K)" },
{ 15, -1, -1, 15, 0x4f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Orleans/512K)" },
{ 15, -1, -1, 15, 0x5f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Orleans/512K)" },
{ 15, -1, -1, 15, 0x2f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Venice/512K)" },
{ 15, -1, -1, 15, 0x2c, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Venice/512K)" },
{ 15, -1, -1, 15, 0x1f, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Winchester/512K)" },
{ 15, -1, -1, 15, 0x0c, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Newcastle/512K)" },
{ 15, -1, -1, 15, 0x27, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (San Diego/512K)" },
{ 15, -1, -1, 15, 0x37, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (San Diego/512K)" },
{ 15, -1, -1, 15, 0x04, 1, 512, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (ClawHammer/512K)" },
{ 15, -1, -1, 15, 0x5f, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (Orleans/1024K)" },
{ 15, -1, -1, 15, 0x27, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (San Diego/1024K)" },
{ 15, -1, -1, 15, 0x04, 1, 1024, -1, NC, ATHLON_ | _64_ , 0, "Athlon 64 (ClawHammer/1024K)" },
{ 15, -1, -1, 15, 0x4b, 2, 256, -1, NC, SEMPRON_ , 0, "Athlon 64 X2 (Windsor/256K)" },
{ 15, -1, -1, 15, 0x23, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Toledo/512K)" },
{ 15, -1, -1, 15, 0x4b, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Windsor/512K)" },
{ 15, -1, -1, 15, 0x43, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Windsor/512K)" },
{ 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Brisbane/512K)" },
{ 15, -1, -1, 15, 0x2b, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Manchester/512K)"},
{ 15, -1, -1, 15, 0x23, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Toledo/1024K)" },
{ 15, -1, -1, 15, 0x43, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon 64 X2 (Windsor/1024K)" },
{ 15, -1, -1, 15, 0x08, 1, 128, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/128K)"},
{ 15, -1, -1, 15, 0x08, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Dublin/256K)"},
{ 15, -1, -1, 15, 0x0c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Paris)" },
{ 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
{ 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
{ 15, -1, -1, 15, 0x1c, 1, 128, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/128K)"},
{ 15, -1, -1, 15, 0x1c, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Sonora/256K)"},
{ 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
{ 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
{ 15, -1, -1, 15, 0x2c, 1, 128, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Albany/128K)"},
{ 15, -1, -1, 15, 0x2c, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Albany/256K)"},
{ 15, -1, -1, 15, 0x2f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/128K)" },
{ 15, -1, -1, 15, 0x2f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Palermo/256K)" },
{ 15, -1, -1, 15, 0x4f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" },
{ 15, -1, -1, 15, 0x4f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" },
{ 15, -1, -1, 15, 0x5f, 1, 128, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/128K)" },
{ 15, -1, -1, 15, 0x5f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Manila/256K)" },
{ 15, -1, -1, 15, 0x6b, 2, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/256K)"},
{ 15, -1, -1, 15, 0x6b, 2, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 Dual (Sherman/512K)"},
{ 15, -1, -1, 15, 0x7f, 1, 256, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/256K)" },
{ 15, -1, -1, 15, 0x7f, 1, 512, -1, NC, SEMPRON_ , 0, "Sempron 64 (Sparta/512K)" },
{ 15, -1, -1, 15, 0x4c, 1, 256, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Keene/256K)"},
{ 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, MOBILE_ | SEMPRON_ , 0, "Mobile Sempron 64 (Keene/512K)"},
{ 15, -1, -1, 15, -1, 2, -1, -1, NC, SEMPRON_ , 0, "Sempron Dual Core" },
{ 15, -1, -1, 15, 0x24, 1, 512, -1, NC, TURION_ | _64_ , 0, "Turion 64 (Lancaster/512K)" },
{ 15, -1, -1, 15, 0x24, 1, 1024, -1, NC, TURION_ | _64_ , 0, "Turion 64 (Lancaster/1024K)" },
{ 15, -1, -1, 15, 0x48, 2, 256, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Taylor)" },
{ 15, -1, -1, 15, 0x48, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Trinidad)" },
{ 15, -1, -1, 15, 0x4c, 1, 512, -1, NC, TURION_ | _64_ , 0, "Turion 64 (Richmond)" },
{ 15, -1, -1, 15, 0x68, 2, 256, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Tyler/256K)" },
{ 15, -1, -1, 15, 0x68, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Tyler/512K)" },
{ 15, -1, -1, 17, 3, 2, 512, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Griffin/512K)" },
{ 15, -1, -1, 17, 3, 2, 1024, -1, NC, TURION_ | _X2 , 0, "Turion X2 (Griffin/1024K)" },
/* K10 Architecture (2007) */
{ 15, -1, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Unknown AMD Phenom" },
{ 15, 2, -1, 16, -1, 1, -1, -1, PHENOM, 0 , 0, "Phenom" },
{ 15, 2, -1, 16, -1, 3, -1, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman)" },
{ 15, 2, -1, 16, -1, 4, -1, -1, PHENOM, 0 , 0, "Phenom X4 (Agena)" },
{ 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/256K)" },
{ 15, 2, -1, 16, -1, 3, 512, -1, PHENOM, 0 , 0, "Phenom X3 (Toliman/512K)" },
{ 15, 2, -1, 16, -1, 4, 128, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/128K)" },
{ 15, 2, -1, 16, -1, 4, 256, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/256K)" },
{ 15, 2, -1, 16, -1, 4, 512, -1, PHENOM, 0 , 0, "Phenom X4 (Agena/512K)" },
{ 15, 2, -1, 16, -1, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon X2 (Kuma)" },
/* Phenom II derivates: */
{ 15, 4, -1, 16, -1, 4, -1, -1, NC, 0 , 0, "Phenom (Deneb-based)" },
{ 15, 4, -1, 16, -1, 1, 1024, -1, NC, SEMPRON_ , 0, "Sempron (Sargas)" },
{ 15, 4, -1, 16, -1, 2, 512, -1, PHENOM2, 0 , 0, "Phenom II X2 (Callisto)" },
{ 15, 4, -1, 16, -1, 3, 512, -1, PHENOM2, 0 , 0, "Phenom II X3 (Heka)" },
{ 15, 4, -1, 16, -1, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4" },
{ 15, 4, -1, 16, 4, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" },
{ 15, 5, -1, 16, 5, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Deneb)" },
{ 15, 4, -1, 16, 10, 4, 512, -1, PHENOM2, 0 , 0, "Phenom II X4 (Zosma)" },
{ 15, 4, -1, 16, 10, 6, 512, -1, PHENOM2, 0 , 0, "Phenom II X6 (Thuban)" },
/* Athlon II derivates: */
{ 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_ | _X2 , 0, "Athlon II (Champlain)" },
{ 15, 6, -1, 16, 6, 2, 512, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon II X2 (Regor)" },
{ 15, 6, -1, 16, 6, 2, 1024, -1, NC, ATHLON_ | _64_ | _X2 , 0, "Athlon II X2 (Regor)" },
{ 15, 5, -1, 16, 5, 3, 512, -1, NC, ATHLON_ | _64_ | _X3 , 0, "Athlon II X3 (Rana)" },
{ 15, 5, -1, 16, 5, 4, 512, -1, NC, ATHLON_ | _64_ | _X4 , 0, "Athlon II X4 (Propus)" },
/* Llano APUs (2011): */
{ 15, 1, -1, 18, 1, 2, -1, -1, FUSION_EA, 0 , 0, "Llano X2" },
{ 15, 1, -1, 18, 1, 3, -1, -1, FUSION_EA, 0 , 0, "Llano X3" },
{ 15, 1, -1, 18, 1, 4, -1, -1, FUSION_EA, 0 , 0, "Llano X4" },
/* Family 14h: Bobcat Architecture (2011) */
{ 15, 2, -1, 20, -1, 1, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario" },
{ 15, 2, -1, 20, -1, 2, -1, -1, FUSION_C, 0 , 0, "Brazos Ontario (Dual-core)" },
{ 15, 1, -1, 20, -1, 1, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate" },
{ 15, 1, -1, 20, -1, 2, -1, -1, FUSION_E, 0 , 0, "Brazos Zacate (Dual-core)" },
{ 15, 2, -1, 20, -1, 2, -1, -1, FUSION_Z, 0 , 0, "Brazos Desna (Dual-core)" },
/* Family 15h: Bulldozer Architecture (2011) */
{ 15, -1, -1, 21, 0, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" },
{ 15, -1, -1, 21, 1, 4, -1, -1, NC, 0 , 0, "Bulldozer X2" },
{ 15, -1, -1, 21, 1, 6, -1, -1, NC, 0 , 0, "Bulldozer X3" },
{ 15, -1, -1, 21, 1, 8, -1, -1, NC, 0 , 0, "Bulldozer X4" },
/* 2nd-gen, Piledriver core (2012): */
{ 15, -1, -1, 21, 2, 4, -1, -1, NC, 0 , 0, "Vishera X2" },
{ 15, -1, -1, 21, 2, 6, -1, -1, NC, 0 , 0, "Vishera X3" },
{ 15, -1, -1, 21, 2, 8, -1, -1, NC, 0 , 0, "Vishera X4" },
{ 15, 0, -1, 21, 16, 2, -1, -1, FUSION_A, 0 , 0, "Trinity X2" },
{ 15, 0, -1, 21, 16, 4, -1, -1, FUSION_A, 0 , 0, "Trinity X4" },
{ 15, 3, -1, 21, 19, 2, -1, -1, FUSION_A, 0 , 0, "Richland X2" },
{ 15, 3, -1, 21, 19, 4, -1, -1, FUSION_A, 0 , 0, "Richland X4" },
/* 3rd-gen, Steamroller core (2014): */
{ 15, 0, -1, 21, 48, 2, -1, -1, FUSION_A, 0 , 0, "Kaveri X2" },
{ 15, 0, -1, 21, 48, 4, -1, -1, FUSION_A, 0 , 0, "Kaveri X4" },
{ 15, 8, -1, 21, 56, 4, -1, -1, FUSION_A, 0 , 0, "Godavari X4" },
/* 4th-gen, Excavator core (2015): */
{ 15, 1, -1, 21, 96, 2, -1, -1, FUSION_A, 0 , 0, "Carrizo X2" },
{ 15, 1, -1, 21, 96, 4, -1, -1, FUSION_A, 0 , 0, "Carrizo X4" },
{ 15, 5, -1, 21, 101, 2, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X2" },
{ 15, 5, -1, 21, 101, 4, -1, -1, FUSION_A, 0 , 0, "Bristol Ridge X4" },
{ 15, 0, -1, 21, 112, 2, -1, -1, FUSION_A, 0 , 0, "Stoney Ridge X2" },
{ 15, 0, -1, 21, 112, 2, -1, -1, FUSION_E, 0 , 0, "Stoney Ridge X2" },
/* Family 16h: Jaguar Architecture (2013) */
{ 15, 0, -1, 22, 0, 2, -1, -1, FUSION_A, 0 , 0, "Kabini X2" },
{ 15, 0, -1, 22, 0, 4, -1, -1, FUSION_A, 0 , 0, "Kabini X4" },
/* 2nd-gen, Puma core (2013): */
{ 15, 0, -1, 22, 48, 2, -1, -1, FUSION_E, 0 , 0, "Mullins X2" },
{ 15, 0, -1, 22, 48, 4, -1, -1, FUSION_A, 0 , 0, "Mullins X4" },
/* Family 17h: Zen Architecture (2017) */
{ 15, -1, -1, 23, 1, 8, -1, -1, NC, 0 , 0, "Ryzen 7" },
{ 15, -1, -1, 23, 1, 6, -1, -1, NC, 0 , _1600, "Ryzen 5" },
{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1500, "Ryzen 5" },
{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , _1400, "Ryzen 5" },
{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Ryzen 3" },
//{ 15, -1, -1, 23, 1, 4, -1, -1, NC, 0 , 0, "Raven Ridge" }, //TBA
/* Newer Opterons: */
{ 15, 9, -1, 22, 9, 8, -1, -1, NC, OPTERON_ , 0, "Magny-Cours Opteron" },
};
static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
const struct feature_map_t matchtable_edx81[] =
@ -190,10 +422,217 @@ static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id
}
}
static int amd_has_turion_modelname(const char* bs)
{
/* We search for something like TL-60. Ahh, I miss regexes...*/
int i, l, k;
char code[3] = {0};
const char* codes[] = { "ML", "MT", "MK", "TK", "TL", "RM", "ZM", "" };
l = (int) strlen(bs);
for(i = 3; i < l - 2; i++)
{
if(bs[i] == '-' &&
isupper(bs[i - 1]) && isupper(bs[i - 2]) && !isupper(bs[i - 3]) &&
isdigit(bs[i + 1]) && isdigit(bs[i + 2]) && !isdigit(bs[i + 3]))
{
code[0] = bs[i - 2];
code[1] = bs[i - 1];
for(k = 0; codes[k][0]; k++)
if(!strcmp(codes[k], code))
{
return 1;
}
}
}
return 0;
}
static struct amd_code_and_bits_t decode_amd_codename_part1(const char* bs)
{
amd_code_t code = NC;
uint64_t bits = 0;
struct amd_code_and_bits_t result;
if(strstr(bs, "Dual Core") ||
strstr(bs, "Dual-Core") ||
strstr(bs, " X2 "))
{
bits |= _X2;
}
if(strstr(bs, " X4 "))
{
bits |= _X4;
}
if(strstr(bs, " X3 "))
{
bits |= _X3;
}
if(strstr(bs, "Opteron"))
{
bits |= OPTERON_;
}
if(strstr(bs, "Phenom"))
{
code = (strstr(bs, "II")) ? PHENOM2 : PHENOM;
}
if(amd_has_turion_modelname(bs))
{
bits |= TURION_;
}
if(strstr(bs, "Athlon(tm)"))
{
bits |= ATHLON_;
}
if(strstr(bs, "Sempron(tm)"))
{
bits |= SEMPRON_;
}
if(strstr(bs, "Duron"))
{
bits |= DURON_;
}
if(strstr(bs, " 64 "))
{
bits |= _64_;
}
if(strstr(bs, " FX"))
{
bits |= _FX;
}
if(strstr(bs, " MP"))
{
bits |= _MP_;
}
if(strstr(bs, "Athlon(tm) 64") || strstr(bs, "Athlon(tm) II X") || match_pattern(bs, "Athlon(tm) X#"))
{
bits |= ATHLON_ | _64_;
}
if(strstr(bs, "Turion"))
{
bits |= TURION_;
}
if(strstr(bs, "mobile") || strstr(bs, "Mobile"))
{
bits |= MOBILE_;
}
if(strstr(bs, "XP"))
{
bits |= _XP_;
}
if(strstr(bs, "XP-M"))
{
bits |= _M_;
}
if(strstr(bs, "(LV)"))
{
bits |= _LV_;
}
if(strstr(bs, " APU "))
{
bits |= _APU_;
}
if(match_pattern(bs, "C-##"))
{
code = FUSION_C;
}
if(match_pattern(bs, "E-###"))
{
code = FUSION_E;
}
if(match_pattern(bs, "Z-##"))
{
code = FUSION_Z;
}
if(match_pattern(bs, "[EA]#-####"))
{
code = FUSION_EA;
}
result.code = code;
result.bits = bits;
return result;
}
static int decode_amd_ryzen_model_code(const char* bs)
{
const struct
{
int model_code;
const char* match_str;
} patterns[] =
{
{ _1600, "1600" },
{ _1500, "1500" },
{ _1400, "1400" },
};
int i;
for(i = 0; i < COUNT_OF(patterns); i++)
if(strstr(bs, patterns[i].match_str))
{
return patterns[i].model_code;
}
//
return 0;
}
static void decode_amd_codename(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
struct internal_id_info_t* internal)
{
struct amd_code_and_bits_t code_and_bits = decode_amd_codename_part1(data->brand_str);
int i = 0;
char* code_str = NULL;
int model_code;
for(i = 0; i < COUNT_OF(amd_code_str); i++)
{
if(code_and_bits.code == amd_code_str[i].code)
{
code_str = amd_code_str[i].str;
break;
}
}
if(/*code == ATHLON_64_X2*/ match_all(code_and_bits.bits, ATHLON_ | _64_ | _X2) && data->l2_cache < 512)
{
code_and_bits.bits &= ~(ATHLON_ | _64_);
code_and_bits.bits |= SEMPRON_;
}
if(code_str)
{
debugf(2, "Detected AMD brand code: %d (%s)\n", code_and_bits.code, code_str);
}
else
{
debugf(2, "Detected AMD brand code: %d\n", code_and_bits.code);
}
if(code_and_bits.bits)
{
debugf(2, "Detected AMD bits: ");
debug_print_lbits(2, code_and_bits.bits);
}
// is it Ryzen? if so, we need to detect discern between the four-core 1400/1500 (Ryzen 5) and the four-core Ryzen 3:
model_code = (data->ext_family == 23) ? decode_amd_ryzen_model_code(data->brand_str) : 0;
internal->code.amd = code_and_bits.code;
internal->bits = code_and_bits.bits;
internal->score = match_cpu_codename(cpudb_amd, COUNT_OF(cpudb_amd), data, code_and_bits.code,
code_and_bits.bits, model_code);
}
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal)
{
load_amd_features(raw, data);
decode_amd_cache_info(raw, data);
decode_amd_number_of_cores(raw, data);
decode_amd_codename(raw, data, internal);
return 0;
}
void cpuid_get_list_amd(struct cpu_list_t* list)
{
generic_get_cpu_list(cpudb_amd, COUNT_OF(cpudb_amd), list);
}

View file

@ -27,5 +27,6 @@
#define __RECOG_AMD_H__
int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal);
void cpuid_get_list_amd(struct cpu_list_t* list);
#endif /* __RECOG_AMD_H__ */

View file

@ -66,6 +66,298 @@ enum _intel_model_t
};
typedef enum _intel_model_t intel_model_t;
const struct match_entry_t cpudb_intel[] =
{
{ -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Intel CPU" },
/* i486 */
{ 4, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown i486" },
{ 4, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-25/33" },
{ 4, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX-50" },
{ 4, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX" },
{ 4, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2" },
{ 4, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SL" },
{ 4, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 SX2" },
{ 4, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX2 WriteBack" },
{ 4, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4" },
{ 4, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "i486 DX4 WriteBack" },
/* All Pentia:
Pentium 1 */
{ 5, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium" },
{ 5, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium A-Step" },
{ 5, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.8u)" },
{ 5, 2, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
{ 5, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium OverDrive" },
{ 5, 4, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
{ 5, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium 1 (0.35u)" },
{ 5, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium MMX (0.25u)" },
/* Pentium 2 / 3 / M / Conroe / whatsnext - all P6 based. */
{ 6, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown P6" },
{ 6, 0, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" },
{ 6, 1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium Pro" },
{ 6, 3, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Klamath)" },
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Deschutes)" },
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile Pentium II (Tonga)"},
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium II (Dixon)" },
{ 6, 3, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Klamath)" },
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Drake)" },
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-II Xeon (Dixon)" },
{ 6, 5, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Covington)" },
{ 6, 6, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-II Celeron (Mendocino)" },
/* -------------------------------------------------- */
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Katmai)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"},
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Coppermine)"},
{ 6, 11, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Pentium III (Tualatin)" },
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tanner)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" },
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Cascades)" },
{ 6, 11, -1, -1, -1, 1, -1, -1, NC, XEON_ , 0, "P-III Xeon (Tualatin)" },
{ 6, 7, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Katmai)" },
{ 6, 8, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" },
{ 6, 10, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Coppermine)" },
{ 6, 11, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "P-III Celeron (Tualatin)" },
/* Netburst based (Pentium 4 and later)
classic P4s */
{ 15, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium 4" },
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "Unknown P-4 Celeron" },
{ 15, -1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Unknown Xeon" },
{ 15, 0, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" },
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Willamette)" },
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Northwood)" },
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Prescott)" },
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium 4 (Cedar Mill)" },
{ 15, 0, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Willamette)" },
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Willamette)" },
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Northwood)" },
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Prescott)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Prescott)" },
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, MOBILE_ | PENTIUM_, 0, "Mobile P-4 (Cedar Mill)" },
/* server CPUs */
{ 15, 0, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" },
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" },
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Prestonia)" },
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ | _MP_ , 0, "Xeon (Gallatin)" },
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, IRWIN, XEON_ , 0, "Xeon (Irwindale)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ | _MP_ , 0, "Xeon (Cranford)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, POTOMAC, XEON_ , 0, "Xeon (Potomac)" },
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Dempsey)" },
/* Pentium Ds */
{ 15, 4, 4, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (SmithField)" },
{ 15, 4, 7, 15, -1, 1, -1, -1, NC, 0 , 0, "Pentium D (SmithField)" },
{ 15, 6, -1, 15, -1, 1, -1, -1, PENTIUM_D, 0 , 0, "Pentium D (Presler)" },
/* Celeron and Celeron Ds */
{ 15, 1, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Willamette)" },
{ 15, 2, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron (Northwood)" },
{ 15, 3, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" },
{ 15, 4, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Prescott)" },
{ 15, 6, -1, 15, -1, 1, -1, -1, NC, CELERON_ , 0, "P-4 Celeron D (Cedar Mill)" },
/* -------------------------------------------------- */
/* Intel Core microarchitecture - P6-based */
{ 6, 9, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Pentium M" },
{ 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Unknown Pentium M" },
{ 6, 9, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Banias)" },
{ 6, 9, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Banias)" },
{ 6, 9, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" },
{ 6, 13, -1, -1, -1, 1, -1, -1, NC, PENTIUM_ , 0, "Pentium M (Dothan)" },
{ 6, 13, -1, -1, -1, 1, -1, -1, PENTIUM_M, 0 , 0, "Pentium M (Dothan)" },
{ 6, 13, -1, -1, -1, 1, -1, -1, NC, CELERON_ , 0, "Celeron M" },
{ 6, 12, -1, -1, -1, -1, -1, -1, NC, ATOM_ , 0, "Unknown Atom" },
{ 6, 12, -1, -1, -1, -1, -1, -1, DIAMONDVILLE, ATOM_, 0, "Atom (Diamondville)" },
{ 6, 12, -1, -1, -1, -1, -1, -1, SILVERTHORNE, ATOM_, 0, "Atom (Silverthorne)" },
{ 6, 12, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" },
{ 6, 6, -1, -1, -1, -1, -1, -1, CEDARVIEW, ATOM_ , 0, "Atom (Cedarview)" },
{ 6, 12, -1, -1, -1, -1, -1, -1, PINEVIEW, ATOM_ , 0, "Atom (Pineview)" },
/* -------------------------------------------------- */
{ 6, 14, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Yonah" },
{ 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" },
{ 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO, 0 , 0, "Yonah (Core Duo)" },
{ 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, MOBILE_, 0, "Yonah (Core Solo)" },
{ 6, 14, -1, -1, -1, 2, -1, -1, CORE_DUO , MOBILE_, 0, "Yonah (Core Duo)" },
{ 6, 14, -1, -1, -1, 1, -1, -1, CORE_SOLO, 0 , 0, "Yonah (Core Solo)" },
{ 6, 15, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Core 2" },
{ 6, 15, -1, -1, -1, 2, 4096, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo)" },
{ 6, 15, -1, -1, -1, 2, 1024, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 1024K" },
{ 6, 15, -1, -1, -1, 2, 512, -1, CORE_DUO, 0 , 0, "Conroe (Core 2 Duo) 512K" },
{ 6, 15, -1, -1, -1, 4, -1, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" },
{ 6, 15, -1, -1, -1, 4, 4096, -1, QUAD_CORE, 0 , 0, "Kentsfield (Core 2 Quad)" },
{ 6, 15, -1, -1, -1, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
{ 6, 15, -1, -1, -1, 2, 2048, -1, CORE_DUO, 0 , 0, "Allendale (Core 2 Duo)" },
{ 6, 15, -1, -1, -1, 2, -1, -1, MOBILE_CORE_DUO, 0, 0, "Merom (Core 2 Duo)" },
{ 6, 15, -1, -1, -1, 2, 2048, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 2048K" },
{ 6, 15, -1, -1, -1, 2, 4096, -1, MEROM, 0 , 0, "Merom (Core 2 Duo) 4096K" },
{ 6, 15, -1, -1, 15, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" },
{ 6, 6, -1, -1, 22, 1, -1, -1, NC, CELERON_ , 0, "Conroe-L (Celeron)" },
{ 6, 15, -1, -1, 15, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" },
{ 6, 6, -1, -1, 22, 2, -1, -1, NC, CELERON_ , 0, "Conroe-L (Allendale)" },
{ 6, 6, -1, -1, 22, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" },
{ 6, 7, -1, -1, 23, 1, -1, -1, NC, 0 , 0, "Unknown Core ?" },
{ 6, 6, -1, -1, 22, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
{ 6, 7, -1, -1, 23, 400, -1, -1, MORE_THAN_QUADCORE, 0, 0, "More than quad-core" },
{ 6, 7, -1, -1, 23, 1, -1, -1, CORE_SOLO , 0, 0, "Unknown Core 45nm" },
{ 6, 7, -1, -1, 23, 1, -1, -1, CORE_DUO , 0, 0, "Unknown Core 45nm" },
{ 6, 7, -1, -1, 23, 2, 1024, -1, WOLFDALE , 0, 0, "Celeron Wolfdale 1M" },
{ 6, 7, -1, -1, 23, 2, 2048, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 2M" },
{ 6, 7, -1, -1, 23, 2, 3072, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 3M" },
{ 6, 7, -1, -1, 23, 2, 6144, -1, WOLFDALE , 0, 0, "Wolfdale (Core 2 Duo) 6M" },
{ 6, 7, -1, -1, 23, 1, -1, -1, MOBILE_CORE_DUO , 0, 0, "Penryn (Core 2 Duo)" },
{ 6, 7, -1, -1, 23, 2, 1024, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo)" },
{ 6, 7, -1, -1, 23, 2, 3072, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 3M" },
{ 6, 7, -1, -1, 23, 2, 6144, -1, PENRYN , 0, 0, "Penryn (Core 2 Duo) 6M" },
{ 6, 7, -1, -1, 23, 4, 2048, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 2M"},
{ 6, 7, -1, -1, 23, 4, 3072, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 3M"},
{ 6, 7, -1, -1, 23, 4, 6144, -1, NC , 0, 0, "Yorkfield (Core 2 Quad) 6M"},
/* Core microarchitecture-based Xeons: */
{ 6, 14, -1, -1, 14, 1, -1, -1, NC, XEON_ , 0, "Xeon LV" },
{ 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _5100, "Xeon (Woodcrest)" },
{ 6, 15, -1, -1, 15, 2, 2048, -1, NC, XEON_ , _3000, "Xeon (Conroe/2M)" },
{ 6, 15, -1, -1, 15, 2, 4096, -1, NC, XEON_ , _3000, "Xeon (Conroe/4M)" },
{ 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , X3200, "Xeon (Kentsfield)" },
{ 6, 15, -1, -1, 15, 4, 4096, -1, NC, XEON_ , _5300, "Xeon (Clovertown)" },
{ 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _3100, "Xeon (Wolfdale)" },
{ 6, 7, -1, -1, 23, 2, 6144, -1, NC, XEON_ , _5200, "Xeon (Wolfdale DP)" },
{ 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , _5400, "Xeon (Harpertown)" },
{ 6, 7, -1, -1, 23, 4, 3072, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/3M)" },
{ 6, 7, -1, -1, 23, 4, 6144, -1, NC, XEON_ , X3300, "Xeon (Yorkfield/6M)" },
/* Nehalem CPUs (45nm): */
{ 6, 10, -1, -1, 26, 4, -1, -1, GAINESTOWN, XEON_ , 0, "Gainestown (Xeon)" },
{ 6, 10, -1, -1, 26, 4, -1, 4096, GAINESTOWN, XEON_ , 0, "Gainestown 4M (Xeon)" },
{ 6, 10, -1, -1, 26, 4, -1, 8192, GAINESTOWN, XEON_ , 0, "Gainestown 8M (Xeon)" },
{ 6, 10, -1, -1, 26, 4, -1, -1, NC, XEON_ | _7 , 0, "Bloomfield (Xeon)" },
{ 6, 10, -1, -1, 26, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Bloomfield (Core i7)" },
{ 6, 10, -1, -1, 30, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Lynnfield (Core i7)" },
{ 6, 5, -1, -1, 37, 4, -1, 8192, NC, CORE_ | _I_ | _5 , 0, "Lynnfield (Core i5)" },
/* Westmere CPUs (32nm): */
{ 6, 5, -1, -1, 37, 2, -1, -1, NC, 0 , 0, "Unknown Core i3/i5" },
{ 6, 12, -1, -1, 44, -1, -1, -1, WESTMERE, XEON_ , 0, "Westmere (Xeon)" },
{ 6, 12, -1, -1, 44, -1, -1, 12288, WESTMERE, XEON_ , 0, "Gulftown (Xeon)" },
{ 6, 12, -1, -1, 44, 4, -1, 12288, NC, CORE_ | _I_ | _7 , 0, "Gulftown (Core i7)" },
{ 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_ | _I_ | _5 , 0, "Clarkdale (Core i5)" },
{ 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_ | _I_ | _3 , 0, "Clarkdale (Core i3)" },
{ 6, 5, -1, -1, 37, 2, -1, -1, NC, PENTIUM_ , 0, "Arrandale" },
{ 6, 5, -1, -1, 37, 2, -1, 4096, NC, CORE_ | _I_ | _7 , 0, "Arrandale (Core i7)" },
{ 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_ | _I_ | _5 , 0, "Arrandale (Core i5)" },
{ 6, 5, -1, -1, 37, 2, -1, 3072, NC, CORE_ | _I_ | _3 , 0, "Arrandale (Core i3)" },
/* Sandy Bridge CPUs (32nm): */
{ 6, 10, -1, -1, 42, -1, -1, -1, NC, 0 , 0, "Unknown Sandy Bridge" },
{ 6, 10, -1, -1, 42, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge (Xeon)" },
{ 6, 10, -1, -1, 42, -1, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Sandy Bridge (Core i7)" },
{ 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Sandy Bridge (Core i7)" },
{ 6, 10, -1, -1, 42, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Sandy Bridge (Core i5)" },
{ 6, 10, -1, -1, 42, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Sandy Bridge (Core i3)" },
{ 6, 10, -1, -1, 42, 2, -1, -1, NC, PENTIUM_ , 0, "Sandy Bridge (Pentium)" },
{ 6, 10, -1, -1, 42, 1, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" },
{ 6, 10, -1, -1, 42, 2, -1, -1, NC, CELERON_ , 0, "Sandy Bridge (Celeron)" },
{ 6, 13, -1, -1, 45, -1, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Sandy Bridge-E" },
{ 6, 13, -1, -1, 45, -1, -1, -1, NC, XEON_ , 0, "Sandy Bridge-E (Xeon)" },
/* Ivy Bridge CPUs (22nm): */
{ 6, 10, -1, -1, 58, -1, -1, -1, NC, XEON_ , 0, "Ivy Bridge (Xeon)" },
{ 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Ivy Bridge (Core i7)" },
{ 6, 10, -1, -1, 58, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Ivy Bridge (Core i5)" },
{ 6, 10, -1, -1, 58, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Ivy Bridge (Core i3)" },
{ 6, 10, -1, -1, 58, 2, -1, -1, NC, PENTIUM_ , 0, "Ivy Bridge (Pentium)" },
{ 6, 10, -1, -1, 58, 1, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" },
{ 6, 10, -1, -1, 58, 2, -1, -1, NC, CELERON_ , 0, "Ivy Bridge (Celeron)" },
{ 6, 14, -1, -1, 62, -1, -1, -1, NC, 0 , 0, "Ivy Bridge-E" },
/* Haswell CPUs (22nm): */
{ 6, 12, -1, -1, 60, -1, -1, -1, NC, XEON_ , 0, "Haswell (Xeon)" },
{ 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Haswell (Core i7)" },
{ 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Haswell (Core i7)" },
{ 6, 6, -1, -1, 70, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Haswell (Core i7)" },
{ 6, 12, -1, -1, 60, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
{ 6, 5, -1, -1, 69, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
{ 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Haswell (Core i5)" },
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Haswell (Core i3)" },
{ 6, 5, -1, -1, 69, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Haswell (Core i3)" },
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, PENTIUM_ , 0, "Haswell (Pentium)" },
{ 6, 12, -1, -1, 60, 2, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" },
{ 6, 12, -1, -1, 60, 1, -1, -1, NC, CELERON_ , 0, "Haswell (Celeron)" },
{ 6, 15, -1, -1, 63, -1, -1, -1, NC, 0 , 0, "Haswell-E" },
/* Broadwell CPUs (14nm): */
{ 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell (Core i7)" },
{ 6, 7, -1, -1, 71, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell (Core i5)" },
{ 6, 13, -1, -1, 61, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-U (Core i7)" },
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-U (Core i7)" },
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell-U (Core i5)" },
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Broadwell-U (Core i3)" },
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, PENTIUM_ , 0, "Broadwell-U (Pentium)" },
{ 6, 13, -1, -1, 61, 2, -1, -1, NC, CELERON_ , 0, "Broadwell-U (Celeron)" },
{ 6, 13, -1, -1, 61, 2, -1, -1, NA, 0 , 0, "Broadwell-U (Core M)" },
{ 6, 15, -1, -1, 79, -1, -1, -1, NC, XEON_ , 0, "Broadwell-E (Xeon)" },
{ 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Broadwell-E (Core i3)" },
{ 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell-E (Core i5)" },
{ 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Broadwell-E (Core i5)" },
{ 6, 15, -1, -1, 79, 2, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-E (Core i7)" },
{ 6, 15, -1, -1, 79, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Broadwell-E (Core i7)" },
/* Skylake CPUs (14nm): */
{ 6, 14, -1, -1, 94, -1, -1, -1, NC, XEON_ , 0, "Skylake (Xeon)" },
{ 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Skylake (Core i7)" },
{ 6, 14, -1, -1, 94, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Skylake (Core i5)" },
{ 6, 14, -1, -1, 94, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Skylake (Core i3)" },
{ 6, 14, -1, -1, 94, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" },
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, PENTIUM_ , 0, "Skylake (Pentium)" },
{ 6, 14, -1, -1, 94, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" },
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CELERON_ , 0, "Skylake (Celeron)" },
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_ | _M_ | _7 , 0, "Skylake (Core m7)" },
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_ | _M_ | _5 , 0, "Skylake (Core m5)" },
{ 6, 14, -1, -1, 78, 2, -1, -1, NC, CORE_ | _M_ | _3 , 0, "Skylake (Core m3)" },
{ 6, 5, -1, -1, 85, 8, -1, -1, NC, XEON_, 0, "Skylake (Xeon Scalable)" },
/* Kaby Lake CPUs (14nm): */
{ 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Kaby Lake (Core i7)" },
{ 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Kaby Lake (Core i5)" },
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Kaby Lake (Core i3)" },
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, PENTIUM_ , 0, "Kaby Lake (Pentium)" },
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, CELERON_ , 0, "Kaby Lake (Celeron)" },
{ 6, 14, -1, -1, 158, 2, -1, -1, NC, CORE_ | _M_ | _3 , 0, "Kaby Lake (Core m3)" },
/* Coffee Lake CPUs (14nm): */
{ 6, 14, -1, -1, 158, 6, -1, -1, NC, CORE_ | _I_ | _7 , 0, "Coffee Lake (Core i7)" },
{ 6, 14, -1, -1, 158, 6, -1, -1, NC, CORE_ | _I_ | _5 , 0, "Coffee Lake (Core i5)" },
{ 6, 14, -1, -1, 158, 4, -1, -1, NC, CORE_ | _I_ | _3 , 0, "Coffee Lake (Core i3)" },
/* Itaniums */
{ 7, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Itanium" },
{ 15, -1, -1, 16, -1, 1, -1, -1, NC, 0 , 0, "Itanium 2" },
};
static void load_intel_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
const struct feature_map_t matchtable_edx1[] =
@ -321,6 +613,8 @@ static void decode_intel_deterministic_cache_info(struct cpu_raw_data_t* raw,
}
else
{
warnf("deterministic_cache: unknown level/typenumber combo (%d/%d), cannot\n", level, typenumber);
warnf("deterministic_cache: recognize cache type\n");
continue;
}
ways = ((raw->intel_fn4[ecx][1] >> 22) & 0x3ff) + 1;
@ -491,6 +785,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
code = matchtable[i].c;
break;
}
debugf(2, "intel matchtable result is %d\n", code);
if(bits & XEON_)
{
if(match_pattern(bs, "W35##") || match_pattern(bs, "[ELXW]75##"))
@ -583,6 +878,104 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
return result;
}
static intel_model_t get_model_code(struct cpu_id_t* data)
{
int i = 0;
int l = (int) strlen(data->brand_str);
const char* bs = data->brand_str;
int mod_flags = 0, model_no = 0, ndigs = 0;
/* If the CPU is a Core ix, then just return the model number generation: */
if((i = match_pattern(bs, "Core(TM) i[357]")) != 0)
{
i += 11;
if(i + 4 >= l)
{
return UNKNOWN;
}
if(bs[i] == '2')
{
return _2xxx;
}
if(bs[i] == '3')
{
return _3xxx;
}
return UNKNOWN;
}
/* For Core2-based Xeons: */
while(i < l - 3)
{
if(bs[i] == 'C' && bs[i + 1] == 'P' && bs[i + 2] == 'U')
{
break;
}
i++;
}
if(i >= l - 3)
{
return UNKNOWN;
}
i += 3;
while(i < l - 4 && bs[i] == ' ')
{
i++;
}
if(i >= l - 4)
{
return UNKNOWN;
}
while(i < l - 4 && !isdigit(bs[i]))
{
if(bs[i] >= 'A' && bs[i] <= 'Z')
{
mod_flags |= (1 << (bs[i] - 'A'));
}
i++;
}
if(i >= l - 4)
{
return UNKNOWN;
}
while(isdigit(bs[i]))
{
ndigs++;
model_no = model_no * 10 + (int)(bs[i] - '0');
i++;
}
if(ndigs != 4)
{
return UNKNOWN;
}
#define HAVE(ch, flags) ((flags & (1 << ((int)(ch-'A')))) != 0)
switch(model_no / 100)
{
case 30:
return _3000;
case 31:
return _3100;
case 32:
{
return (HAVE('X', mod_flags)) ? X3200 : _3200;
}
case 33:
{
return (HAVE('X', mod_flags)) ? X3300 : _3300;
}
case 51:
return _5100;
case 52:
return _5200;
case 53:
return _5300;
case 54:
return _5400;
default:
return UNKNOWN;
}
#undef HAVE
}
static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct cpu_id_t* data)
{
struct cpu_epc_t epc;
@ -625,12 +1018,14 @@ static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct c
epc = cpuid_get_epc(i, raw);
if(epc.length == 0)
{
debugf(2, "SGX: epc section request for %d returned null, no more EPC sections.\n", i);
data->sgx.num_epc_sections = i;
break;
}
}
if(data->sgx.num_epc_sections == -1)
{
debugf(1, "SGX: warning: seems to be infinitude of EPC sections.\n");
data->sgx.num_epc_sections = 1000000;
}
}
@ -668,6 +1063,9 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
struct internal_id_info_t* internal)
{
intel_code_and_bits_t brand;
intel_model_t model_code;
int i;
char* brand_code_str = NULL;
load_intel_features(raw, data);
if(raw->basic_cpuid[0][0] >= 4)
@ -682,15 +1080,46 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
decode_intel_number_of_cores(raw, data);
brand = get_brand_code_and_bits(data);
model_code = get_model_code(data);
for(i = 0; i < COUNT_OF(intel_bcode_str); i++)
{
if(brand.code == intel_bcode_str[i].code)
{
brand_code_str = intel_bcode_str[i].str;
break;
}
}
if(brand_code_str)
{
debugf(2, "Detected Intel brand code: %d (%s)\n", brand.code, brand_code_str);
}
else
{
debugf(2, "Detected Intel brand code: %d\n", brand.code);
}
if(brand.bits)
{
debugf(2, "Detected Intel bits: ");
debug_print_lbits(2, brand.bits);
}
debugf(2, "Detected Intel model code: %d\n", model_code);
internal->code.intel = brand.code;
internal->bits = brand.bits;
if(data->flags[CPU_FEATURE_SGX])
{
debugf(2, "SGX seems to be present, decoding...\n");
// if SGX is indicated by the CPU, verify its presence:
decode_intel_sgx_features(raw, data);
}
internal->score = match_cpu_codename(cpudb_intel, COUNT_OF(cpudb_intel), data,
brand.code, brand.bits, model_code);
return 0;
}
void cpuid_get_list_intel(struct cpu_list_t* list)
{
generic_get_cpu_list(cpudb_intel, COUNT_OF(cpudb_intel), list);
}

View file

@ -28,5 +28,6 @@
int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data,
struct internal_id_info_t* internal);
void cpuid_get_list_intel(struct cpu_list_t* list);
#endif /*__RECOG_INTEL_H__*/

View file

@ -50,6 +50,13 @@ RAPIDJSON_DIAG_OFF(switch - enum)
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#include <utility> // std::move
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
RAPIDJSON_NAMESPACE_BEGIN
@ -484,8 +491,8 @@ namespace internal
// select candidates according to nested encoding and allocator types
template <typename T> struct
IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
: IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
: IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
// helper to match arbitrary GenericValue instantiations, including derived classes
template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
@ -868,7 +875,7 @@ explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT :
\param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
\see CopyFrom()
*/
template< typename SourceAllocator >
template<typename SourceAllocator>
GenericValue(const GenericValue<Encoding, SourceAllocator> & rhs, Allocator & allocator);
//! Constructor for boolean value.

View file

@ -30,8 +30,8 @@ namespace internal
#ifdef __GNUC__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(effc++)
RAPIDJSON_DIAG_OFF(array -
bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
RAPIDJSON_DIAG_OFF(array-bounds)
// some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
#endif
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa,

View file

@ -113,8 +113,8 @@ namespace internal
template <typename CT, typename T>
struct IsMoreConst
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
: AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
template <typename T> struct IsPointer : FalseType {};
template <typename T> struct IsPointer<T*> : TrueType {};
@ -125,7 +125,7 @@ namespace internal
#if RAPIDJSON_HAS_CXX11_TYPETRAITS
template <typename B, typename D> struct IsBaseOf
: BoolType< ::std::is_base_of<B, D>::value> {};
: BoolType<::std::is_base_of<B, D>::value> {};
#else // simplified version adopted from Boost
@ -134,8 +134,8 @@ namespace internal
RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
typedef char (&Yes)[1];
typedef char (&No) [2];
typedef char(&Yes)[1];
typedef char(&No) [2];
template <typename T>
static Yes Check(const D*, T);
@ -151,7 +151,7 @@ namespace internal
};
template <typename B, typename D> struct IsBaseOf
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D>>>::Type {};
: OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D>>>::Type {};
#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
@ -188,7 +188,7 @@ namespace internal
template <typename T> struct RemoveSfinaeTag;
template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)>
{
typedef T Type;
typedef T Type;
};
#define RAPIDJSON_REMOVEFPTR_(type) \

View file

@ -195,11 +195,11 @@ typedef struct
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#define SCNdPTR "I64d"
#define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#define SCNdPTR "ld"
#define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
@ -261,15 +261,15 @@ typedef struct
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#define SCNoPTR "I64o"
#define SCNuPTR "I64u"
#define SCNxPTR "I64x"
#define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#define SCNoPTR "lo"
#define SCNuPTR "lu"
#define SCNxPTR "lx"
#define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]

View file

@ -1,7 +1,7 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2013 Alexander Chemeris
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@ -13,9 +13,8 @@
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the product nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@ -30,10 +29,6 @@
//
///////////////////////////////////////////////////////////////////////////////
// The above software in this distribution may have been modified by
// THL A29 Limited ("Tencent Modifications").
// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
@ -45,68 +40,27 @@
#pragma once
#endif
// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.
#if _MSC_VER >= 1600 // [
#include <stdint.h>
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
#undef INT8_C
#undef INT16_C
#undef INT32_C
#undef INT64_C
#undef UINT8_C
#undef UINT16_C
#undef UINT32_C
#undef UINT64_C
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
// Check out Issue 9 for the details.
#ifndef INTMAX_C // [
# define INTMAX_C INT64_C
#endif // INTMAX_C ]
#ifndef UINTMAX_C // [
# define UINTMAX_C UINT64_C
#endif // UINTMAX_C ]
#endif // __STDC_CONSTANT_MACROS ]
#else // ] _MSC_VER >= 1700 [
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}'
// or compiler would give many errors like this:
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#if defined(__cplusplus) && !defined(_M_ARM)
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#if defined(__cplusplus) && !defined(_M_ARM)
#include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
#define _W64 __w64
#else
#define _W64
#endif
#endif
@ -218,13 +172,13 @@ typedef uint64_t uintmax_t;
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
@ -235,30 +189,30 @@ typedef uint64_t uintmax_t;
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#define PTRDIFF_MIN _I64_MIN
#define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#define PTRDIFF_MIN _I32_MIN
#define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#ifdef _WIN64 // [
#define SIZE_MAX _UI64_MAX
#else // _WIN64 ][
#define SIZE_MAX _UI32_MAX
#endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
@ -284,17 +238,10 @@ typedef uint64_t uintmax_t;
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
// Check out Issue 9 for the details.
#ifndef INTMAX_C // [
# define INTMAX_C INT64_C
#endif // INTMAX_C ]
#ifndef UINTMAX_C // [
# define UINTMAX_C UINT64_C
#endif // UINTMAX_C ]
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_VER >= 1600 ]
#endif // _MSC_STDINT_H_ ]

View file

@ -99,12 +99,12 @@ public:
*/
explicit
Writer(OutputStream & os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)),
maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
os_(&os), level_stack_(stackAllocator, levelDepth* sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces),
hasRoot_(false) {}
explicit
Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces),
os_(0), level_stack_(allocator, levelDepth* sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces),
hasRoot_(false) {}
//! Reset the writer with a new stream.

View file

@ -79,7 +79,7 @@ App::App(int argc, char** argv) :
m_console = new Console(this);
}
if(m_options->logFile())
if(0 < m_options->logFile().size())
{
Log::add(new FileLog(m_options->logFile()));
}
@ -129,7 +129,7 @@ int App::exec()
if(!CryptoNight::init(m_options->algo(), m_options->algoVariant()))
{
LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName());
LOG_ERR("\"" << m_options->algoName() << "\" hash self-test failed.");
return 1;
}
@ -178,8 +178,7 @@ void App::onConsoleCommand(char command)
case 'P':
if(Workers::isEnabled())
{
LOG_INFO(m_options->colors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" :
"paused, press 'r' to resume");
LOG_INFO("paused, press 'r' to resume");
Workers::setEnabled(false);
}
break;
@ -188,7 +187,7 @@ void App::onConsoleCommand(char command)
case 'R':
if(!Workers::isEnabled())
{
LOG_INFO(m_options->colors() ? "\x1B[01;32mresumed" : "resumed");
LOG_INFO((m_options->colors() ? "\x1B[01;32mresumed" : "resumed"));
Workers::setEnabled(true);
}
break;

View file

@ -20,13 +20,14 @@
* 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 _WIN32
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include "interfaces/interface.h"
#include "App.h"
#include "Cpu.h"
@ -61,12 +62,14 @@ void App::background()
if(i < 0)
{
LOG_ERR("setsid() failed (errno = %d)", errno);
LOG_ERR("setsid() failed (errno = " << errno << ")");
}
i = chdir("/");
if(i < 0)
{
LOG_ERR("chdir() failed (errno = %d)", errno);
LOG_ERR("chdir() failed (errno = " << errno << ")");
}
}
#endif

View file

@ -25,6 +25,8 @@
#include "Console.h"
#include "interfaces/IConsoleListener.h"
#include "interfaces/interface.h"
Console::Console(IConsoleListener* listener)
: m_listener(listener)

View file

@ -84,8 +84,8 @@ int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
void Cpu::initCommon()
{
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);
@ -111,8 +111,8 @@ void Cpu::initCommon()
}
// 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))
else if(data.vendor == VENDOR_INTEL && data.ext_family == 0x06 &&
(data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17))
{
int l2_count_per_socket = m_totalCores > 1 ? m_totalCores / 2 : 1;
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;

View file

@ -20,7 +20,7 @@
* 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 _WIN32
#include <string.h>
@ -52,3 +52,5 @@ void Cpu::initCommon()
m_flags |= AES;
# endif
}
#endif

View file

@ -20,7 +20,7 @@
* 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 _WIN32
#include <pthread.h>
#include <sched.h>
@ -43,3 +43,5 @@ void Cpu::init()
void Cpu::setAffinity(int id, uint64_t mask)
{
}
#endif

View file

@ -20,7 +20,7 @@
* 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 _WIN32
#ifdef _MSC_VER
# include <intrin.h>
@ -144,3 +144,5 @@ void Cpu::initCommon()
m_flags |= BMI2;
}
}
#endif

View file

@ -20,7 +20,7 @@
* 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 _WIN32
#ifdef __FreeBSD__
# include <sys/types.h>
@ -29,6 +29,7 @@
# include <pthread_np.h>
#endif
#include <sched.h>
#include <pthread.h>
#include <sched.h>
@ -56,6 +57,8 @@ void Cpu::init()
void Cpu::setAffinity(int id, uint64_t mask)
{
#if __GNU_VISIBLE && defined(__rtems__)
cpu_set_t set;
CPU_ZERO(&set);
@ -81,4 +84,6 @@ void Cpu::setAffinity(int id, uint64_t mask)
sched_setaffinity(gettid(), sizeof(&set), &set);
# endif
}
#endif
}
#endif

View file

@ -32,13 +32,13 @@
#include "xmrig.h"
bool Mem::m_doubleHash = false;
int Mem::m_algo = 0;
int Mem::m_flags = 0;
int Mem::m_threads = 0;
size_t Mem::m_offset = 0;
size_t Mem::m_size = 0;
alignas(16) uint8_t* Mem::m_memory = nullptr;
bool Mem::m_doubleHash = false;
int Mem::m_algo = 0;
int Mem::m_flags = 0;
int Mem::m_threads = 0;
size_t Mem::m_offset = 0;
size_t Mem::m_size = 0;
VAR_ALIGN(16, uint8_t* Mem::m_memory) = nullptr;
cryptonight_ctx* Mem::create(int threadId)

View file

@ -30,6 +30,9 @@
#include <stdint.h>
#include "align.h"
struct cryptonight_ctx;
@ -76,7 +79,7 @@ private:
static int m_threads;
static size_t m_offset;
static size_t m_size;
alignas(16) static uint8_t* m_memory;
VAR_ALIGN(16, static uint8_t* m_memory);
# ifndef XMRIG_NO_AEON
static cryptonight_ctx* createLite(int threadId);

View file

@ -21,7 +21,7 @@
* 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 _WIN32
#include <stdlib.h>
#include <sys/mman.h>
@ -40,6 +40,12 @@
#include "Options.h"
#include "xmrig.h"
#ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000 /* create a huge page mapping */
#endif
#ifndef MAP_POPULATE
#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
#endif
bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
{
@ -53,6 +59,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
if(!enabled)
{
m_memory = static_cast<uint8_t*>(_mm_malloc(m_size, 16));
return true;
}
@ -92,6 +99,8 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled)
void Mem::release()
{
const int size = MEMORY * (m_threads + 1);
if(m_flags & HugepagesEnabled)
{
if(m_flags & Lock)
@ -106,3 +115,5 @@ void Mem::release()
_mm_free(m_memory);
}
}
#endif

View file

@ -93,7 +93,7 @@ static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string)
{
LSA_UNICODE_STRING lsaString;
DWORD dwLen = (DWORD) wcslen(string);
DWORD dwLen = (DWORD) wcslen((WCHAR*)string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -27,16 +27,17 @@
#ifdef _MSC_VER
# include "getopt/getopt.h"
#include "getopt/getopt.h"
#else
# include <getopt.h>
#include <getopt.h>
#endif
#ifndef XMRIG_NO_HTTPD
# include <microhttpd.h>
#include <microhttpd.h>
#endif
#include "interfaces/interface.h"
#include "Cpu.h"
#include "donate.h"
@ -75,9 +76,9 @@ Options:\n\
--cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\
--no-huge-pages disable huge pages support\n\
--no-color disable colored output\n\
--variant algorithm PoW variant\n\
--donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\
--user-agent set custom user-agent string for pool\n\
--donate-level=N donate level, default 2%%\n\
-B, --background run the miner in the background\n\
-c, --config=FILE load a JSON-format configuration file\n\
-l, --log-file=FILE log all output to a file\n"
@ -112,6 +113,7 @@ static struct option const options[] =
{ "config", 1, nullptr, 'c' },
{ "cpu-affinity", 1, nullptr, 1020 },
{ "cpu-priority", 1, nullptr, 1021 },
{ "debug", 0, nullptr, 1101 },
{ "donate-level", 1, nullptr, 1003 },
{ "dry-run", 0, nullptr, 5000 },
{ "help", 0, nullptr, 'h' },
@ -121,7 +123,6 @@ static struct option const options[] =
{ "nicehash", 0, nullptr, 1006 },
{ "no-color", 0, nullptr, 1002 },
{ "no-huge-pages", 0, nullptr, 1009 },
{ "variant", 1, nullptr, 1010 },
{ "pass", 1, nullptr, 'p' },
{ "print-time", 1, nullptr, 1007 },
{ "retries", 1, nullptr, 'r' },
@ -133,7 +134,17 @@ static struct option const options[] =
{ "user", 1, nullptr, 'u' },
{ "user-agent", 1, nullptr, 1008 },
{ "userpass", 1, nullptr, 'O' },
{ "verbose", 0, nullptr, 1100 },
{ "version", 0, nullptr, 'V' },
{ "donate-url", required_argument, nullptr, 1391 },
{ "donate-url-little", required_argument, nullptr, 1392 },
{ "donate-user", required_argument, nullptr, 1393 },
{ "donate-pass", required_argument, nullptr, 1394 },
{ "donate-userpass", required_argument, nullptr, 1395 },
{ "donate-keepalive", no_argument, nullptr, 1396 },
{ "donate-nicehash", no_argument, nullptr, 1397 },
{ "donate-minutes", required_argument, nullptr, 1398 },
{ "minutes-in-cicle", required_argument, nullptr, 1399 },
{ 0, 0, 0, 0 }
};
@ -158,9 +169,24 @@ static struct option const config_options[] =
{ "syslog", 0, nullptr, 'S' },
{ "threads", 1, nullptr, 't' },
{ "user-agent", 1, nullptr, 1008 },
{ "verbose", 0, nullptr, 1100 },
{ "workers", 0, nullptr, 1103 },
{ 0, 0, 0, 0 }
};
static struct option const donate_options[] =
{
{ "donate-url", required_argument, nullptr, 1391 },
{ "donate-url-little", required_argument, nullptr, 1392 },
{ "donate-user", required_argument, nullptr, 1393 },
{ "donate-pass", required_argument, nullptr, 1394 },
{ "donate-userpass", required_argument, nullptr, 1395 },
{ "donate-keepalive", no_argument, nullptr, 1396 },
{ "donate-nicehash", no_argument, nullptr, 1397 },
{ "donate-minutes", required_argument, nullptr, 1398 },
{ "minutes-in-cicle", required_argument, nullptr, 1399 },
{ 0, 0, 0, 0 }
};
static struct option const pool_options[] =
{
@ -169,7 +195,6 @@ static struct option const pool_options[] =
{ "user", 1, nullptr, 'u' },
{ "userpass", 1, nullptr, 'O' },
{ "keepalive", 0, nullptr, 'k' },
{ "variant", 1, nullptr, 1010 },
{ "nicehash", 0, nullptr, 1006 },
{ 0, 0, 0, 0 }
};
@ -215,22 +240,23 @@ const char* Options::algoName() const
Options::Options(int argc, char** argv) :
m_background(false),
m_colors(true),
m_colors(false),
m_debug(false),
m_doubleHash(false),
m_dryRun(false),
m_hugePages(true),
m_ready(false),
m_safe(false),
m_syslog(false),
m_apiToken(nullptr),
m_apiWorkerId(nullptr),
m_logFile(nullptr),
m_userAgent(nullptr),
m_verbose(false),
m_apiToken(""),
m_apiWorkerId(""),
m_logFile(""),
m_userAgent(""),
m_algo(0),
m_algoVariant(0),
m_apiPort(0),
m_donateLevel(kDonateLevel),
m_maxCpuUsage(75),
m_maxCpuUsage(100),
m_printTime(60),
m_priority(-1),
m_retries(5),
@ -238,19 +264,26 @@ Options::Options(int argc, char** argv) :
m_threads(0),
m_affinity(-1L)
{
m_pools.push_back(new Url());
m_donateOpt.m_url = kDonateUrl;
m_donateOpt.m_url_little = kDonateUrlLittle;
m_donateOpt.m_user = kDonateUser;
m_donateOpt.m_pass = kDonatePass;
m_donateOpt.m_keepAlive = kDonateKeepAlive;
m_donateOpt.m_niceHash = kDonateNiceHash;
m_donateOpt.m_donateMinutes = kDonateMinutes;
m_donateOpt.m_minutesInCicle = kMinutesInCicle;
int key;
m_pools.push_back(Url());
while(1)
{
key = getopt_long(argc, argv, short_options, options, NULL);
const int key = getopt_long(argc, argv, short_options, options, NULL);
if(key < 0)
{
break;
}
if(!parseArg(key, optarg))
if(!parseArg(key, optarg == NULL ? "" : optarg))
{
return;
}
@ -262,12 +295,12 @@ Options::Options(int argc, char** argv) :
return;
}
if(!m_pools[0]->isValid())
if(!m_pools[0].isValid())
{
parseConfig(Platform::defaultConfigName());
}
if(!m_pools[0]->isValid())
if(!m_pools[0].isValid())
{
fprintf(stderr, "No pool URL supplied. Exiting.\n");
return;
@ -300,16 +333,17 @@ Options::Options(int argc, char** argv) :
Options::~Options()
{
m_pools.clear();
}
bool Options::getJSON(const char* fileName, rapidjson::Document & doc)
bool Options::getJSON(const std::string & fileName, rapidjson::Document & doc)
{
uv_fs_t req;
const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr);
const int fd = uv_fs_open(uv_default_loop(), &req, fileName.c_str(), O_RDONLY, 0644, nullptr);
if(fd < 0)
{
fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd));
fprintf(stderr, "unable to open %s: %s\n", fileName.c_str(), uv_strerror(fd));
return false;
}
@ -326,7 +360,8 @@ bool Options::getJSON(const char* fileName, rapidjson::Document & doc)
if(doc.HasParseError())
{
printf("%s:%d: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError()));
printf("%s:%d: %s\n", fileName.c_str(), (int) doc.GetErrorOffset(),
rapidjson::GetParseError_En(doc.GetParseError()));
return false;
}
@ -334,7 +369,7 @@ bool Options::getJSON(const char* fileName, rapidjson::Document & doc)
}
bool Options::parseArg(int key, const char* arg)
bool Options::parseArg(int key, const std::string & arg)
{
switch(key)
{
@ -346,91 +381,128 @@ bool Options::parseArg(int key, const char* arg)
break;
case 'o': /* --url */
if(m_pools.size() > 1 || m_pools[0]->isValid())
if(m_pools.size() > 1 || m_pools[0].isValid())
{
Url* url = new Url(arg);
if(url->isValid())
Url url(arg);
if(url.isValid())
{
m_pools.push_back(url);
}
else
{
delete url;
}
}
else
{
m_pools[0]->parse(arg);
m_pools[0].parse(arg);
}
if(!m_pools.back()->isValid())
if(!m_pools.back().isValid())
{
return false;
}
break;
case 'O': /* --userpass */
if(!m_pools.back()->setUserpass(arg))
if(!m_pools.back().setUserpass(arg))
{
return false;
}
break;
case 'u': /* --user */
m_pools.back()->setUser(arg);
m_pools.back().setUser(arg);
break;
case 'p': /* --pass */
m_pools.back()->setPassword(arg);
m_pools.back().setPassword(arg);
break;
case 'l': /* --log-file */
free(m_logFile);
m_logFile = strdup(arg);
m_colors = false;
m_logFile = arg;
break;
case 4001: /* --access-token */
free(m_apiToken);
m_apiToken = strdup(arg);
m_apiToken = arg;
break;
case 4002: /* --worker-id */
free(m_apiWorkerId);
m_apiWorkerId = strdup(arg);
m_apiWorkerId = arg;
break;
case 'r': /* --retries */
case 'R': /* --retry-pause */
case 'v': /* --av */
case 1003: /* --donate-level */
case 1004: /* --max-cpu-usage */
case 1007: /* --print-time */
case 1021: /* --cpu-priority */
case 4000: /* --api-port */
case 1010: /* --variant */
return parseArg(key, strtol(arg, nullptr, 10));
return parseArg(key, strtol(arg.c_str(), nullptr, 10));
case 'B': /* --background */
case 'k': /* --keepalive */
case 'S': /* --syslog */
case 1005: /* --safe */
case 1006: /* --nicehash */
case 5000: /* --dry-run */
case 1100: /* --verbose */
case 1101: /* --debug */
return parseBoolean(key, true);
case 1002: /* --no-color */
case 1009: /* --no-huge-pages */
return parseBoolean(key, false);
case 1003: /* --donate-level */
if(arg == "")
{
m_donateOpt.m_donateMinutes = 0;
}
else
{
parseArg(key, strtol(arg.c_str(), nullptr, 10));
}
break;
case 1391: //donate-url
m_donateOpt.m_url = arg;
break;
case 1392: //donate-url-little
m_donateOpt.m_url_little = arg;
break;
case 1393: //donate-user
m_donateOpt.m_user = arg;
break;
case 1394: //donate-pass
m_donateOpt.m_pass = arg;
break;
case 1395: //donate-userpass
{
const size_t p = arg.find_first_of(':');
if(p != std::string::npos)
{
m_donateOpt.m_user = arg.substr(0, p);
m_donateOpt.m_pass = arg.substr(p + 1);
}
}
break;
case 1396: //donate-nicehash
parseBoolean(key, arg == "true");
break;
case 1397: //donate-keepalive
parseBoolean(key, arg == "true");
break;
case 1398: //donate-minutes
parseArg(key, strtol(arg.c_str(), nullptr, 10));
break;
case 1399: //minutes-in-cicle
parseArg(key, strtol(arg.c_str(), nullptr, 10));
break;
case 't': /* --threads */
if(strncmp(arg, "all", 3) == 0)
if(arg == "all")
{
m_threads = Cpu::threads();
return true;
}
return parseArg(key, strtol(arg, nullptr, 10));
return parseArg(key, strtol(arg.c_str(), nullptr, 10));
case 'V': /* --version */
showVersion();
@ -446,13 +518,13 @@ bool Options::parseArg(int key, const char* arg)
case 1020: /* --cpu-affinity */
{
const char* p = strstr(arg, "0x");
return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
const size_t p = arg.find("0x");
return parseArg(key, p != std::string::npos ? strtoul(arg.substr(p).c_str(), nullptr, 16) :
strtoul(arg.c_str(), nullptr, 10));
}
case 1008: /* --user-agent */
free(m_userAgent);
m_userAgent = strdup(arg);
m_userAgent = arg;
break;
default:
@ -509,12 +581,26 @@ bool Options::parseArg(int key, uint64_t arg)
break;
case 1003: /* --donate-level */
if(arg < 1 || arg > 99)
if(arg >= 0 || arg <= 60)
{
return true;
m_donateOpt.m_donateMinutes = (unsigned short) arg;
}
break;
m_donateLevel = (int) arg;
case 1391: //donate-url
case 1392: //donate-user
case 1393: //donate-pass
case 1394: //donate-userpass
case 1395: //donate-keepalive
case 1396: //donate-nicehash
break;
case 1398: //donate-minutes
m_donateOpt.m_donateMinutes = (unsigned short)arg;
break;
case 1399: //minutes-in-cicle
m_donateOpt.m_minutesInCicle = (unsigned short)arg;
break;
case 1004: /* --max-cpu-usage */
@ -537,10 +623,6 @@ bool Options::parseArg(int key, uint64_t arg)
m_printTime = (int) arg;
break;
case 1010: /* --variant */
m_pools.back()->setVariant((int) arg);
break;
case 1020: /* --cpu-affinity */
if(arg)
{
@ -575,7 +657,7 @@ bool Options::parseBoolean(int key, bool enable)
switch(key)
{
case 'k': /* --keepalive */
m_pools.back()->setKeepAlive(enable);
m_pools.back().setKeepAlive(enable);
break;
case 'B': /* --background */
@ -592,12 +674,20 @@ bool Options::parseBoolean(int key, bool enable)
m_colors = enable;
break;
case 1100: /* --verbose */
m_verbose = enable;
break;
case 1101: /* --debug */
m_debug = enable;
break;
case 1005: /* --safe */
m_safe = enable;
break;
case 1006: /* --nicehash */
m_pools.back()->setNicehash(enable);
m_pools.back().setNicehash(enable);
break;
case 1009: /* --no-huge-pages */
@ -608,10 +698,25 @@ bool Options::parseBoolean(int key, bool enable)
m_colors = enable;
break;
case 1396: //donate-keepalive
m_donateOpt.m_keepAlive = enable;
break;
case 1397: //donate-nicehash
m_donateOpt.m_niceHash = enable;
break;
case 5000: /* --dry-run */
m_dryRun = enable;
break;
case 1391: //donate-url
case 1392: //donate-url-little
case 1393: //donate-user
case 1394: //donate-pass
case 1395: //donate-userpass
case 1398: //donate-minutes
case 1399: //minutes-in-cicle
default:
break;
}
@ -620,29 +725,21 @@ bool Options::parseBoolean(int key, bool enable)
}
Url* Options::parseUrl(const char* arg) const
Url Options::parseUrl(const std::string & arg) const
{
auto url = new Url(arg);
if(!url->isValid())
{
delete url;
return nullptr;
}
return url;
return Url(arg);
}
void Options::adjust()
{
for(Url* url : m_pools)
for(size_t i = 0; i < m_pools.size(); ++i)
{
url->adjust(m_algo);
Url & url = m_pools[i];
url.adjust(m_algo);
}
}
void Options::parseConfig(const char* fileName)
void Options::parseConfig(const std::string & fileName)
{
rapidjson::Document doc;
if(!getJSON(fileName, doc))
@ -655,11 +752,30 @@ void Options::parseConfig(const char* fileName)
parseJSON(&config_options[i], doc);
}
const rapidjson::Value & donate = doc["donate-level"];
if(donate.IsArray())
{
for(size_t i = 0; i < donate.GetArray().Size(); ++i)
{
const rapidjson::Value & value = donate.GetArray()[i];
if(!value.IsObject())
{
continue;
}
for(size_t i = 0; i < ARRAY_SIZE(donate_options); i++)
{
parseJSON(&donate_options[i], value);
}
}
}
const rapidjson::Value & pools = doc["pools"];
if(pools.IsArray())
{
for(const rapidjson::Value & value : pools.GetArray())
for(size_t i = 0; i < pools.GetArray().Size(); ++i)
{
const rapidjson::Value & value = pools.GetArray()[i];
if(!value.IsObject())
{
continue;
@ -696,7 +812,7 @@ void Options::parseJSON(const struct option* option, const rapidjson::Value & ob
{
parseArg(option->val, value.GetString());
}
else if(option->has_arg && value.IsInt64())
else if(option->has_arg && value.IsUint64())
{
parseArg(option->val, value.GetUint64());
}
@ -756,18 +872,18 @@ void Options::showVersion()
}
bool Options::setAlgo(const char* algo)
bool Options::setAlgo(const std::string & algo)
{
for(size_t i = 0; i < ARRAY_SIZE(algo_names); i++)
{
if(algo_names[i] && !strcmp(algo, algo_names[i]))
if(algo_names[i] && algo == algo_names[i])
{
m_algo = (int) i;
break;
}
# ifndef XMRIG_NO_AEON
if(i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light"))
if(i == ARRAY_SIZE(algo_names) - 1 && algo == "cryptonight-light")
{
m_algo = xmrig::ALGO_CRYPTONIGHT_LITE;
break;

View file

@ -27,7 +27,7 @@
#include <stdint.h>
#include <vector>
#include <string>
#include "rapidjson/fwd.h"
@ -49,6 +49,19 @@ public:
AV_MAX
};
struct Donate
{
public:
std::string m_url;
std::string m_url_little;
std::string m_user;
std::string m_pass;
bool m_keepAlive;
bool m_niceHash;
unsigned short m_donateMinutes;
unsigned short m_minutesInCicle;
};
static inline Options* i()
{
return m_self;
@ -63,6 +76,14 @@ public:
{
return m_colors;
}
inline bool isDebug() const
{
return m_debug;
}
inline void toggleDebug()
{
m_debug = !m_debug;
}
inline bool doubleHash() const
{
return m_doubleHash;
@ -79,23 +100,23 @@ public:
{
return m_syslog;
}
inline const char* apiToken() const
inline const std::string apiToken() const
{
return m_apiToken;
}
inline const char* apiWorkerId() const
inline const std::string & apiWorkerId() const
{
return m_apiWorkerId;
}
inline const char* logFile() const
inline const std::string & logFile() const
{
return m_logFile;
}
inline const char* userAgent() const
inline const std::string & userAgent() const
{
return m_userAgent;
}
inline const std::vector<Url*> & pools() const
inline const std::vector<Url> & pools() const
{
return m_pools;
}
@ -111,9 +132,17 @@ public:
{
return m_apiPort;
}
inline int donateLevel() const
inline unsigned short donateMinutes() const
{
return m_donateLevel;
return m_donateOpt.m_donateMinutes;
}
inline unsigned short minutesInCicle() const
{
return m_donateOpt.m_minutesInCicle;
}
inline const Donate & donate() const
{
return m_donateOpt;
}
inline int printTime() const
{
@ -143,6 +172,14 @@ public:
{
m_colors = colors;
}
inline void setVerbose(bool verbose)
{
m_verbose = verbose;
}
inline void toggleVerbose()
{
m_verbose = !m_verbose;
}
inline static void release()
{
@ -162,18 +199,18 @@ private:
static Options* m_self;
bool getJSON(const char* fileName, rapidjson::Document & doc);
bool parseArg(int key, const char* arg);
bool getJSON(const std::string & fileName, rapidjson::Document & doc);
bool parseArg(int key, const std::string & arg);
bool parseArg(int key, uint64_t arg);
bool parseBoolean(int key, bool enable);
Url* parseUrl(const char* arg) const;
Url parseUrl(const std::string & arg) const;
void adjust();
void parseConfig(const char* fileName);
void parseConfig(const std::string & fileName);
void parseJSON(const struct option* option, const rapidjson::Value & object);
void showUsage(int status) const;
void showVersion(void);
bool setAlgo(const char* algo);
bool setAlgo(const std::string & algo);
int getAlgoVariant() const;
# ifndef XMRIG_NO_AEON
@ -182,20 +219,21 @@ private:
bool m_background;
bool m_colors;
bool m_debug;
bool m_doubleHash;
bool m_dryRun;
bool m_hugePages;
bool m_ready;
bool m_safe;
bool m_syslog;
char* m_apiToken;
char* m_apiWorkerId;
char* m_logFile;
char* m_userAgent;
bool m_verbose;
std::string m_apiToken;
std::string m_apiWorkerId;
std::string m_logFile;
std::string m_userAgent;
int m_algo;
int m_algoVariant;
int m_apiPort;
int m_donateLevel;
int m_maxCpuUsage;
int m_printTime;
int m_priority;
@ -203,7 +241,8 @@ private:
int m_retryPause;
int m_threads;
int64_t m_affinity;
std::vector<Url*> m_pools;
std::vector<Url> m_pools;
Donate m_donateOpt;
};
#endif /* __OPTIONS_H__ */

View file

@ -29,38 +29,40 @@
#include "Platform.h"
char* Platform::m_defaultConfigName = nullptr;
char* Platform::m_userAgent = nullptr;
std::string Platform::m_defaultConfigName = "";
std::string Platform::m_userAgent = "";
const char* Platform::defaultConfigName()
const std::string & Platform::defaultConfigName()
{
size_t size = 520;
if(m_defaultConfigName == nullptr)
enum
{
m_defaultConfigName = new char[size];
C_SIZE = 520,
};
size_t size = C_SIZE ;
char defaultConfigName[C_SIZE];
if(uv_exepath(defaultConfigName, &size) < 0)
{
return m_defaultConfigName;
}
if(uv_exepath(m_defaultConfigName, &size) < 0)
{
return nullptr;
}
m_defaultConfigName = defaultConfigName;
if(size < 500)
{
# ifdef WIN32
char* p = strrchr(m_defaultConfigName, '\\');
# else
char* p = strrchr(m_defaultConfigName, '/');
# endif
#ifdef WIN32
size_t p = m_defaultConfigName.find_last_of('\\');
#else
size_t p = m_defaultConfigName.find_last_of('/');
#endif
if(p)
if(p != std::string::npos)
{
strcpy(p + 1, "config.json");
return m_defaultConfigName;
m_defaultConfigName.resize(p + 1);
m_defaultConfigName.append("config.json");
}
}
return nullptr;
return m_defaultConfigName;
}

View file

@ -24,24 +24,25 @@
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
#include <string>
class Platform
{
public:
static const char* defaultConfigName();
static void init(const char* userAgent);
static const std::string & defaultConfigName();
static void init(const std::string & userAgent);
static void release();
static void setProcessPriority(int priority);
static void setThreadPriority(int priority);
static inline const char* userAgent()
static inline const std::string & userAgent()
{
return m_userAgent;
}
private:
static char* m_defaultConfigName;
static char* m_userAgent;
static std::string m_defaultConfigName;
static std::string m_userAgent;
};

View file

@ -20,7 +20,7 @@
* 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 _WIN32
#include <stdio.h>
#include <stdlib.h>
@ -32,39 +32,39 @@
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
# include "nvidia/cryptonight.h"
#include "nvidia/cryptonight.h"
#endif
static inline char* createUserAgent()
static inline std::string createUserAgent()
{
const size_t max = 160;
char* buf = new char[max];
char buf[max];
# ifdef XMRIG_NVIDIA_PROJECT
#ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s CUDA/%d.%d clang/%d.%d.%d", APP_NAME,
APP_VERSION, uv_version_string(), cudaVersion / 1000, cudaVersion % 100, __clang_major__, __clang_minor__,
__clang_patchlevel__);
# else
#else
snprintf(buf, max, "%s/%s (Macintosh; Intel Mac OS X) libuv/%s clang/%d.%d.%d", APP_NAME, APP_VERSION,
uv_version_string(), __clang_major__, __clang_minor__, __clang_patchlevel__);
# endif
#endif
return buf;
}
void Platform::init(const char* userAgent)
void Platform::init(const std::string & userAgent)
{
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
m_userAgent = (0 < userAgent.size()) ? userAgent : createUserAgent();
}
void Platform::release()
{
delete [] m_userAgent;
m_userAgent.clear();
}
@ -111,3 +111,4 @@ void Platform::setThreadPriority(int priority)
setpriority(PRIO_PROCESS, 0, prio);
}
#endif

View file

@ -20,6 +20,7 @@
* 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 _WIN32
#include <sched.h>
#include <stdio.h>
@ -27,60 +28,58 @@
#include <string.h>
#include <sys/resource.h>
#include <uv.h>
#include <sched.h>
#include "log/Log.h"
#include "Platform.h"
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
# include "nvidia/cryptonight.h"
#include "nvidia/cryptonight.h"
#endif
static inline char* createUserAgent()
static inline std::string createUserAgent()
{
const size_t max = 160;
char* buf = new char[max];
char buf[max];
int length = snprintf(buf, max, "%s/%s (Linux ", APP_NAME, APP_VERSION);
# if defined(__x86_64__)
#if defined(__x86_64__)
length += snprintf(buf + length, max - length, "x86_64) libuv/%s", uv_version_string());
# else
#else
length += snprintf(buf + length, max - length, "i686) libuv/%s", uv_version_string());
# endif
#endif
# ifdef XMRIG_NVIDIA_PROJECT
#ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
length += snprintf(buf + length, max - length, " CUDA/%d.%d", cudaVersion / 1000, cudaVersion % 100);
# endif
#endif
# ifdef __GNUC__
#ifdef __GNUC__
length += snprintf(buf + length, max - length, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# endif
#endif
return buf;
}
void Platform::init(const char* userAgent)
void Platform::init(const std::string & userAgent)
{
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
m_userAgent = (0 < userAgent.size()) ? userAgent : createUserAgent();
}
void Platform::release()
{
delete [] m_userAgent;
m_userAgent.clear();
}
void Platform::setProcessPriority(int priority)
{
}
void Platform::setThreadPriority(int priority)
{
if(priority == -1)
@ -117,7 +116,7 @@ void Platform::setThreadPriority(int priority)
setpriority(PRIO_PROCESS, 0, prio);
# ifdef SCHED_IDLE
#ifdef SCHED_IDLE
if(priority == 0)
{
sched_param param;
@ -125,8 +124,13 @@ void Platform::setThreadPriority(int priority)
if(sched_setscheduler(0, SCHED_IDLE, &param) != 0)
{
sched_setscheduler(0, SCHED_BATCH, &param);
const int err = sched_setscheduler(0, SCHED_BATCH, &param);
LOG_WARN("SCHED_BATCH priority: " << err << ".");
}
}
#else
LOG_INFO("NONE priority.");
# endif
}
#endif

View file

@ -26,12 +26,13 @@
#include <windows.h>
#include <uv.h>
#include "log/Log.h"
#include "Platform.h"
#include "version.h"
#ifdef XMRIG_NVIDIA_PROJECT
# include "nvidia/cryptonight.h"
#include "nvidia/cryptonight.h"
#endif
@ -56,46 +57,45 @@ static inline OSVERSIONINFOEX winOsVersion()
}
static inline char* createUserAgent()
static inline std::string createUserAgent()
{
const auto osver = winOsVersion();
const size_t max = 160;
char* buf = new char[max];
char buf[max];
int length = snprintf(buf, max, "%s/%s (Windows NT %lu.%lu", APP_NAME, APP_VERSION, osver.dwMajorVersion,
osver.dwMinorVersion);
# if defined(__x86_64__) || defined(_M_AMD64)
#if defined(__x86_64__) || defined(_M_AMD64)
length += snprintf(buf + length, max - length, "; Win64; x64) libuv/%s", uv_version_string());
# else
#else
length += snprintf(buf + length, max - length, ") libuv/%s", uv_version_string());
# endif
#endif
# ifdef XMRIG_NVIDIA_PROJECT
#ifdef XMRIG_NVIDIA_PROJECT
const int cudaVersion = cuda_get_runtime_version();
length += snprintf(buf + length, max - length, " CUDA/%d.%d", cudaVersion / 1000, cudaVersion % 100);
# endif
#endif
# ifdef __GNUC__
#ifdef __GNUC__
length += snprintf(buf + length, max - length, " gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
# elif _MSC_VER
#elif _MSC_VER
length += snprintf(buf + length, max - length, " msvc/%d", MSVC_VERSION);
# endif
#endif
return buf;
}
void Platform::init(const char* userAgent)
void Platform::init(const std::string & userAgent)
{
m_userAgent = userAgent ? strdup(userAgent) : createUserAgent();
m_userAgent = (0 < userAgent.size()) ? userAgent : createUserAgent();
}
void Platform::release()
{
delete [] m_defaultConfigName;
delete [] m_userAgent;
m_userAgent.clear();
}

View file

@ -51,10 +51,7 @@ static void print_versions()
# endif
Log::i()->text(Options::i()->colors() ?
"\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" :
" * VERSIONS: XMRig/%s libuv/%s%s",
APP_VERSION, uv_version_string(), buf);
PRINT_MSG(" * VERSIONS: XMRig/" << APP_VERSION << " libuv/" << uv_version_string() << buf);
}
@ -62,14 +59,16 @@ static void print_memory()
{
if(Options::i()->colors())
{
/*
Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s",
Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable",
Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled");
*/
}
else
{
Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable",
Mem::isHugepagesEnabled() ? "enabled" : "disabled");
PRINT_MSG(" * HUGE PAGES: " << (Mem::isHugepagesAvailable() ? "available" : "unavailable") << ", " <<
(Mem::isHugepagesEnabled() ? "enabled" : "disabled"));
}
}
@ -78,22 +77,25 @@ static void print_cpu()
{
if(Options::i()->colors())
{
/*
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI",
Cpu::brand(),
Cpu::sockets(),
Cpu::isX64() ? "\x1B[01;32m" : "\x1B[01;31m-",
Cpu::hasAES() ? "\x1B[01;32m" : "\x1B[01;31m-");
# ifndef XMRIG_NO_LIBCPUID
# ifndef XMRIG_NO_LIBCPUID
Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0,
Cpu::l3() / 1024.0);
# endif
# endif
*/
}
else
{
Log::i()->text(" * CPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(),
Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-");
PRINT_MSG(" * CPU: " << Cpu::brand() << " (" << Cpu::threads() << "@" << Cpu::sockets() << ") " <<
(Cpu::isX64() ? "" : "-") << "64 " <<
(Cpu::hasAES() ? "" : "-") << "AES-NI");
# ifndef XMRIG_NO_LIBCPUID
Log::i()->text(" * CPU L2/L3: %.1f MB/%.1f MB", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0);
PRINT_MSG(" * CPU L2/L3: " << (Cpu::l2() / 1024.0) << " MB/" << Cpu::l3() / 1024.0 << " MB");
# endif
}
}
@ -111,36 +113,29 @@ static void print_threads()
buf[0] = '\0';
}
Log::i()->text(Options::i()->colors() ?
"\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" :
" * THREADS: %d, %s, av=%d, %sdonate=%d%%%s",
Options::i()->threads(),
Options::i()->algoName(),
Options::i()->algoVariant(),
Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "",
Options::i()->donateLevel(),
buf);
PRINT_MSG(" * THREADS: " << Options::i()->threads() << ", " << Options::i()->algoName() << ", av=" <<
Options::i()->algoVariant() << ", donate-minutes=" << Options::i()->donateMinutes() <<
((Options::i()->donateMinutes() > 0) ? ("/" +
Log::ToString(Options::i()->minutesInCicle()) + " (" + Log::ToString((100 *
Options::i()->donateMinutes()) /
Options::i()->minutesInCicle()) + "%)") : "") << buf);
}
static void print_pools()
{
const std::vector<Url*> & pools = Options::i()->pools();
const std::vector<Url> & pools = Options::i()->pools();
for(size_t i = 0; i < pools.size(); ++i)
{
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" :
" * POOL #%d: %s:%d",
i + 1,
pools[i]->host(),
pools[i]->port());
PRINT_MSG(" * POOL #" << (i + 1) << ": " << pools[i].host() << ":" << pools[i].port());
}
# ifdef APP_DEBUG
for(size_t i = 0; i < pools.size(); ++i)
{
Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(),
pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash());
PRINT_MSG(pools[i].host() << ":" << pools[i].port() << ", user: " << pools[i].user() << ", pass: " <<
pools[i].password() << ", ka: " << pools[i].isKeepAlive() << ", nicehash: " << pools[i].isNicehash());
}
# endif
}
@ -154,8 +149,17 @@ static void print_api()
return;
}
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" :
" * API PORT: %d", Options::i()->apiPort());
if(Options::i()->colors())
{
/*TODO LOG
Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" :
" * API PORT: %d", Options::i()->apiPort());
*/
}
else
{
PRINT_MSG(" * API PORT: " << Options::i()->apiPort());
}
}
#endif
@ -164,11 +168,13 @@ static void print_commands()
{
if(Options::i()->colors())
{
/*
Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume");
*/
}
else
{
Log::i()->text(" * COMMANDS: 'h' hashrate, 'p' pause, 'r' resume");
PRINT_MSG(" * COMMANDS: 'h' hashrate, 'p' pause, 'r' resume");
}
}

View file

@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_NO_API
#include <string.h>
@ -47,15 +48,15 @@ void Api::release()
}
char* Api::get(const char* url, int* status)
std::string Api::get(const std::string & url, int* status)
{
if(!m_state)
{
return nullptr;
return "";
}
uv_mutex_lock(&m_mutex);
char* buf = m_state->get(url, status);
std::string buf = m_state->get(url, status);
uv_mutex_unlock(&m_mutex);
return buf;
@ -86,3 +87,5 @@ void Api::tick(const NetworkState & network)
m_state->tick(network);
uv_mutex_unlock(&m_mutex);
}
#endif

View file

@ -26,7 +26,9 @@
#include <uv.h>
#include <string>
#include "interfaces/interface.h"
class ApiState;
class Hashrate;
@ -39,7 +41,7 @@ public:
static bool start();
static void release();
static char* get(const char* url, int* status);
static std::string get(const std::string & url, int* status);
static void tick(const Hashrate* hashrate);
static void tick(const NetworkState & results);

View file

@ -31,7 +31,6 @@
# include "unistd.h"
#endif
#include "api/ApiState.h"
#include "Cpu.h"
#include "Mem.h"
@ -50,14 +49,14 @@ extern "C"
#include "crypto/c_keccak.h"
}
static inline double normalize(double d)
{
#ifndef _WIN32
if(!isnormal(d))
{
return 0.0;
}
#endif
return floor(d * 100.0) / 100.0;
}
@ -70,9 +69,9 @@ ApiState::ApiState()
memset(m_totalHashrate, 0, sizeof(m_totalHashrate));
memset(m_workerId, 0, sizeof(m_workerId));
if(Options::i()->apiWorkerId())
if(0 < Options::i()->apiWorkerId().size())
{
strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1);
strncpy(m_workerId, Options::i()->apiWorkerId().c_str(), sizeof(m_workerId) - 1);
}
else
{
@ -89,7 +88,7 @@ ApiState::~ApiState()
}
char* ApiState::get(const char* url, int* status) const
std::string ApiState::get(const std::string & url, int* status) const
{
rapidjson::Document doc;
doc.SetObject();
@ -126,14 +125,14 @@ void ApiState::tick(const NetworkState & network)
}
char* ApiState::finalize(rapidjson::Document & doc) const
std::string ApiState::finalize(rapidjson::Document & doc) const
{
rapidjson::StringBuffer buffer(0, 4096);
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
writer.SetMaxDecimalPlaces(10);
doc.Accept(writer);
return strdup(buffer.GetString());
return buffer.GetString();
}
@ -162,7 +161,9 @@ void ApiState::genId()
memcpy(input + addrSize, APP_KIND, strlen(APP_KIND));
keccak(input, static_cast<int>(inSize), hash, sizeof(hash));
Job::toHex(hash, 8, m_id);
char* hashChar = (char*)hash;
Job::toHex(std::string(hashChar, 8), m_id);
delete [] input;
break;
@ -237,11 +238,13 @@ void ApiState::getMiner(rapidjson::Document & doc) const
doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator);
doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent().c_str()), allocator);
doc.AddMember("cpu", cpu, allocator);
doc.AddMember("algo", rapidjson::StringRef(Options::i()->algoName()), allocator);
doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator);
doc.AddMember("donate_level", Options::i()->donateLevel(), allocator);
doc.AddMember("donate_minutes_per_cicle", Options::i()->donateMinutes(), allocator);
doc.AddMember("minutes_per_cicle", Options::i()->minutesInCicle(), allocator);
}

View file

@ -28,6 +28,7 @@
#include "api/NetworkState.h"
#include "rapidjson/fwd.h"
#include <string>
class Hashrate;
@ -38,12 +39,12 @@ public:
ApiState();
~ApiState();
char* get(const char* url, int* status) const;
std::string get(const std::string & url, int* status) const;
void tick(const Hashrate* hashrate);
void tick(const NetworkState & results);
private:
char* finalize(rapidjson::Document & doc) const;
std::string finalize(rapidjson::Document & doc) const;
void genId();
void getConnection(rapidjson::Document & doc) const;
void getHashrate(rapidjson::Document & doc) const;

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -21,24 +21,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_NO_HTTPD
#include <microhttpd.h>
#include <string.h>
#include "api/Api.h"
#include "api/Httpd.h"
#include "log/Log.h"
Httpd::Httpd(int port, const char* accessToken) :
Httpd::Httpd(int port, const std::string & accessToken) :
m_accessToken(accessToken),
m_port(port),
m_daemon(nullptr)
{
}
bool Httpd::start()
{
if(!m_port)
@ -46,22 +43,8 @@ bool Httpd::start()
return false;
}
unsigned int flags = 0;
if(MHD_is_feature_supported(MHD_FEATURE_EPOLL))
{
flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY;
}
else
{
flags = MHD_USE_SELECT_INTERNALLY;
}
if(MHD_is_feature_supported(MHD_FEATURE_IPv6))
{
flags |= MHD_USE_DUAL_STACK;
}
m_daemon = MHD_start_daemon(flags, m_port, nullptr, nullptr, &Httpd::handler, this, MHD_OPTION_END);
m_daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, m_port, nullptr, nullptr, &Httpd::handler, this,
MHD_OPTION_END);
if(!m_daemon)
{
LOG_ERR("HTTP Daemon failed to start.");
@ -72,25 +55,25 @@ bool Httpd::start()
}
int Httpd::auth(const char* header)
int Httpd::auth(const std::string & header)
{
if(!m_accessToken)
if(m_accessToken.empty())
{
return MHD_HTTP_OK;
}
if(m_accessToken && !header)
if(0 < m_accessToken.size() && header.empty())
{
return MHD_HTTP_UNAUTHORIZED;
}
const size_t size = strlen(header);
if(size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0)
const size_t size = header.size();
if(size < 8 || m_accessToken.size() != size - 7 || "Bearer " == header.substr(0, 7))
{
return MHD_HTTP_FORBIDDEN;
}
return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
return (m_accessToken == header.substr(7)) ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN;
}
@ -112,15 +95,16 @@ int Httpd::done(MHD_Connection* connection, int status, MHD_Response* rsp)
}
int Httpd::handler(void* cls, struct MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls)
int Httpd::handlerStd(void* cls, struct MHD_Connection* connection, const std::string & url,
const std::string & method, const std::string & version, const std::string & upload_data,
size_t* upload_data_size, void** con_cls)
{
if(strcmp(method, "OPTIONS") == 0)
if(method == "OPTIONS")
{
return done(connection, MHD_HTTP_OK, nullptr);
}
if(strcmp(method, "GET") != 0)
if(method != "GET")
{
return MHD_NO;
}
@ -132,12 +116,21 @@ int Httpd::handler(void* cls, struct MHD_Connection* connection, const char* url
return done(connection, status, nullptr);
}
char* buf = Api::get(url, &status);
if(buf == nullptr)
std::string buf = Api::get(url, &status);
if(buf.empty())
{
return MHD_NO;
}
MHD_Response* rsp = MHD_create_response_from_buffer(strlen(buf), (void*) buf, MHD_RESPMEM_MUST_FREE);
MHD_Response* rsp = MHD_create_response_from_buffer(buf.size(), (void*) buf.c_str(), MHD_RESPMEM_MUST_FREE);
return done(connection, status, rsp);
}
int Httpd::handler(void* cls, MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* upload_data, size_t* upload_data_size,
void** con_cls)
{
return handlerStd(cls, connection, url, method, version, upload_data, upload_data_size, con_cls);
}
#endif

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -24,29 +24,32 @@
#ifndef __HTTPD_H__
#define __HTTPD_H__
#include <uv.h>
struct MHD_Connection;
struct MHD_Daemon;
struct MHD_Response;
class Httpd
{
public:
Httpd(int port, const char* accessToken);
Httpd(int port, const std::string & accessToken);
bool start();
private:
int auth(const char* header);
int auth(const std::string & header);
static int done(MHD_Connection* connection, int status, MHD_Response* rsp);
static int handler(void* cls, MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls);
static int handlerStd(void* cls, MHD_Connection* connection, const std::string & url,
const std::string & method,
const std::string & version, const std::string & upload_data, size_t* upload_data_size,
void** con_cls);
const char* m_accessToken;
static int handler(void* cls, MHD_Connection* connection, const char* url, const char* method,
const char* version, const char* upload_data, size_t* upload_data_size,
void** con_cls);
const std::string & m_accessToken;
const int m_port;
MHD_Daemon* m_daemon;
};

View file

@ -27,6 +27,8 @@
#include <string.h>
#include <uv.h>
#include "interfaces/interface.h"
#include "api/NetworkState.h"
#include "net/SubmitResult.h"
@ -76,9 +78,9 @@ uint32_t NetworkState::latency() const
}
void NetworkState::add(const SubmitResult & result, const char* error)
void NetworkState::add(const SubmitResult & result, const std::string & error)
{
if(error)
if(0 < error.size())
{
rejected++;
return;
@ -98,9 +100,9 @@ void NetworkState::add(const SubmitResult & result, const char* error)
}
void NetworkState::setPool(const char* host, int port, const char* ip)
void NetworkState::setPool(const std::string & host, int port, const std::string & ip)
{
snprintf(pool, sizeof(pool) - 1, "%s:%d", host, port);
snprintf(pool, sizeof(pool) - 1, "%s:%d", host.c_str(), port);
m_active = true;
m_connectionTime = uv_now(uv_default_loop());

View file

@ -27,6 +27,7 @@
#include <array>
#include <vector>
#include <string>
class SubmitResult;
@ -40,12 +41,12 @@ public:
int connectionTime() const;
uint32_t avgTime() const;
uint32_t latency() const;
void add(const SubmitResult & result, const char* error);
void setPool(const char* host, int port, const char* ip);
void add(const SubmitResult & result, const std::string & error);
void setPool(const std::string & host, int port, const std::string & ip);
void stop();
char pool[256];
std::array<uint64_t, 10> topDiff { { } };
std::array<uint64_t, 10> topDiff;
uint32_t diff;
uint64_t accepted;
uint64_t failures;

View file

@ -1,11 +1,29 @@
{
"algo": "cryptonight", // cryptonight (default) or cryptonight-lite
"user-agent": "", // custom user-agent
"av": 0, // algorithm variation, 0 auto select
"background": false, // true to run the miner in the background
"colors": true, // false to disable colored output
"colors": false, // true to enable colored output
"cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1
"cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest)
"donate-level": 5, // donate level, mininum 1%
/* Default donate setting: */
"donate-level": 3, // default donate minutes (3 minutes each 1 hour)
/* Custom donate settings:
"donate-level": [
{
// "donate-url": "fee.xmrig.com:443", // custom donate pool for cryptonight
// "donate-url-little": "fee.xmrig.com:3333", // custom donate pool for cryptonight-little
// "donate-user": "", // custom donate user
// "donate-pass": "", // custom donate pass
// "donate-keepalive": false, // custom donate keepalive
// "donate-nicehash": true, // custom donate nicehash
"donate-minutes": 3, // custom donate minutes for each cicle
"minutes-in-cicle": 60 // custom total minutes in a cicle (60 => 1 hour)
// that is [(57 minutes) to pool + (3 minutes) to donate...] and repeat all until miner ends.
}
],
*/
"debug": false,
"log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log"
"max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option.
"print-time": 60, // print hashrate report every N seconds
@ -16,11 +34,14 @@
"threads": null, // number of miner threads
"pools": [
{
"url": "pool.minemonero.pro:5555", // URL of mining server
"user": "", // username for mining server
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false // enable nicehash/xmrig-proxy support
"url": "pool.minemonero.pro:3333", // --------------- URL of mining server
/* "url": "pool.minemonero.pro:443@localhost:8080",*/ // --------------- URL of mining server over HTTP (CONNECT) proxy
/* "url": "pool.minemonero.pro:7777#secret_keystream",*/ // URL of mining xmrig-proxy with encrypted support
/* "url": "pool.minemonero.pro:8080#secret_keystream@localhost:8080",*/ // URL of mining xmrig-proxy with encrypted support over HTTP (CONNECT) proxy
"user": "%HOST_NAME%_%IP_ADD%+100", // username for mining server using meta-data (%HOST_NAME%, %IP_ADD%, etc.)
"pass": "x", // password for mining server
"keepalive": true, // send keepalived for prevent timeout (need pool support)
"nicehash": false // enable nicehash/xmrig-proxy support
}
],
"api": {

View file

@ -29,6 +29,8 @@
#include <stddef.h>
#include <stdint.h>
#include "align.h"
#include "interfaces/interface.h"
#define AEON_MEMORY 1048576
#define AEON_MASK 0xFFFF0
@ -41,9 +43,9 @@
struct cryptonight_ctx
{
alignas(16) uint8_t state0[200];
alignas(16) uint8_t state1[200];
alignas(16) uint8_t* memory;
VAR_ALIGN(16, uint8_t state0[200]);
VAR_ALIGN(16, uint8_t state1[200]);
VAR_ALIGN(16, uint8_t* memory);
};

View file

@ -463,6 +463,7 @@ inline void cryptonight_double_hash(const void* __restrict__ input, size_t size,
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
VARIANT1_1(&l0[idx0 & MASK]);
VARIANT1_1(&l1[idx1 & MASK]);

View file

@ -77,7 +77,7 @@ void (* const extra_hashes[4])(const void*, size_t, char*) = {do_blake_hash, do_
#if defined(__x86_64__) || defined(_M_AMD64)
#if (defined(__x86_64__) || defined(_M_AMD64)) && __cplusplus > 199711L
# define EXTRACT64(X) _mm_cvtsi128_si64(X)
# ifdef __GNUC__
@ -90,7 +90,7 @@ static inline uint64_t __umul128(uint64_t a, uint64_t b, uint64_t* hi)
# else
#define __umul128 _umul128
# endif
#elif defined(__i386__) || defined(_M_IX86)
#elif defined(__i386__) || defined(_M_IX86) || __cplusplus <= 199711L
# define HI32(X) \
_mm_srli_si128((X), 4)
@ -318,6 +318,17 @@ static inline void cn_implode_scratchpad(const __m128i* input, __m128i* output)
_mm_store_si128(output + 11, xout7);
}
#if ! defined _WIN64 && defined _WIN32
#if defined(_MSC_VER) && _MSC_VER < 1900
static inline __m128i _mm_set_epi64x(const uint64_t __a, const uint64_t __b)
{
__m128i ret;
ret.m128i_u64[1] = __a;
ret.m128i_u64[0] = __b;
return ret;
}
#endif
#endif
template<size_t ITERATIONS, size_t MEM, size_t MASK, bool SOFT_AES, int VARIANT>
inline void cryptonight_single_hash(const void* __restrict__ input, size_t size, void* __restrict__ output,
@ -352,7 +363,9 @@ inline void cryptonight_single_hash(const void* __restrict__ input, size_t size,
cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0));
}
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx));
VARIANT1_1(&l0[idx0 & MASK]);
idx0 = EXTRACT64(cx);
bx0 = cx;
@ -429,6 +442,7 @@ inline void cryptonight_double_hash(const void* __restrict__ input, size_t size,
_mm_store_si128((__m128i*) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0));
_mm_store_si128((__m128i*) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1));
VARIANT1_1(&l0[idx0 & MASK]);
VARIANT1_1(&l1[idx1 & MASK]);

View file

@ -654,7 +654,7 @@ static SkeinHashReturn Update(hashState* state, const SkeinBitSequence* data, Sk
b = (u08b_t)((data[bCnt - 1] & (0 - mask)) | mask); /* apply bit padding on final byte */
Skein_512_Update(&state->u.ctx_512, data, bCnt - 1); /* process all but the final byte */
Skein_512_Update(&state->u.ctx_512, &b, 1); /* process the (masked) partial byte */
Skein_512_Update(&state->u.ctx_512, &b, 1); /* process the (masked) partial byte */
Skein_Set_Bit_Pad_Flag(state->u.h); /* set tweak flag for the final call */
return SKEIN_SUCCESS;
@ -697,8 +697,7 @@ void xmr_skein(const SkeinBitSequence* data, SkeinBitSequence* hashval)
// Skein_512_Init(&state.u.ctx_512, (size_t)XMR_HASHBITLEN);
state.u.ctx_512.h.hashBitLen = XMR_HASHBITLEN;
memcpy(state.u.ctx_512.X, SKEIN_512_IV_256, sizeof(state.u.ctx_512.X));
Skein_512_Ctxt_t* ctx = &(state.u.ctx_512);
Skein_Start_New_Type(ctx, MSG);
Skein_Start_New_Type(&state.u.ctx_512, MSG);
// Update
if((XMR_DATABITLEN & 7) == 0) /* partial bytes? */

View file

@ -37,6 +37,8 @@
#include <inttypes.h>
#include "align.h"
#define saes_data(w) {\
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
@ -86,8 +88,8 @@
#define saes_u2(p) saes_b2w( p, saes_f3(p), saes_f2(p), p)
#define saes_u3(p) saes_b2w( p, p, saes_f3(p), saes_f2(p))
alignas(16) const uint32_t saes_table[4][256] = { saes_data(saes_u0), saes_data(saes_u1), saes_data(saes_u2), saes_data(saes_u3) };
alignas(16) const uint8_t saes_sbox[256] = saes_data(saes_h0);
VAR_ALIGN(16, const uint32_t saes_table[4][256]) = { saes_data(saes_u0), saes_data(saes_u1), saes_data(saes_u2), saes_data(saes_u3) };
VAR_ALIGN(16, const uint8_t saes_sbox[256]) = saes_data(saes_h0);
static inline __m128i soft_aesenc(const uint32_t* in, __m128i key)
{
@ -117,7 +119,7 @@ static inline uint32_t sub_word(uint32_t key)
saes_sbox[key & 0xff];
}
#if defined(__clang__) || defined(XMRIG_ARM)
#if defined(__clang__) || defined(XMRIG_ARM) || __cplusplus <= 199711L
static inline uint32_t _rotr(uint32_t value, uint32_t amount)
{
return (value >> amount) | (value << ((32 - amount) & 31));

View file

@ -28,16 +28,28 @@
/*
* Dev donation.
*
* Percentage of your hashing power that you want to donate to the developer, can be 0 if you don't want to do that.
* Example of how it works for the default setting of 1:
* You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1 minute.
* Switching is instant, and only happens after a successful connection, so you never loose any hashes.
* Percentage of your hashing power that you want to donate to the donation server,
* can be 0 if you don't want to do that.
*
* If you plan on changing this setting to 0 please consider making a one off donation to my wallet:
* XMR: 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD
* BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT
* XMR: 433hhduFBtwVXtQiTTTeqyZsB36XaBLJB6bcQfnqqMs5RJitdpi8xBN21hWiEfuPp2hytmf1cshgK5Grgo6QUvLZCP2QSMi
*
* How it works:
* Other connections switch to donation pool until the first 60 minutes, kDonateLevel minutes each hour
* with overime compensation; but the period can be customizable. In proxy no way to use precise donation time!
* You can check actual donation via API.
*/
constexpr const int kDonateLevel = 5;
enum
{
kDonateMinutes = 3,
kMinutesInCicle = 60,
kDonateKeepAlive = false,
kDonateNiceHash = true,
};
static const char* kDonateUrl = "fee.xmrig.com:443";
static const char* kDonateUrlLittle = "fee.xmrig.com:3333";
static const char* kDonateUser = "";
static const char* kDonatePass = "x";
#endif /* __DONATE_H__ */

View file

@ -38,10 +38,10 @@ class IClientListener
public:
virtual ~IClientListener() {}
virtual void onClose(Client* client, int failures) = 0;
virtual void onJobReceived(Client* client, const Job & job) = 0;
virtual void onLoginSuccess(Client* client) = 0;
virtual void onResultAccepted(Client* client, const SubmitResult & result, const char* error) = 0;
virtual void onClose(Client* client, int failures) = 0;
virtual void onJobReceived(Client* client, const Job & job) = 0;
virtual void onLoginSuccess(Client* client) = 0;
virtual void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) = 0;
};

View file

@ -24,6 +24,7 @@
#ifndef __ICONSOLELISTENER_H__
#define __ICONSOLELISTENER_H__
#include "interfaces/interface.h"
class IConsoleListener
{

View file

@ -7,6 +7,7 @@
* 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.
@ -23,17 +24,25 @@
#ifndef __ILOGBACKEND_H__
#define __ILOGBACKEND_H__
#include <stdarg.h>
#include "interfaces/interface.h"
#include <string>
class ILogBackend
{
public:
enum Level
{
ERR,
WARNING,
NOTICE,
INFO,
DEBUG
};
virtual ~ILogBackend() {}
virtual void message(int level, const char* fmt, va_list args) = 0;
virtual void text(const char* fmt, va_list args) = 0;
virtual void message(Level level, const std::string & txt) = 0;
virtual void text(const std::string & txt) = 0;
};

View file

@ -24,10 +24,9 @@
#ifndef __ISTRATEGY_H__
#define __ISTRATEGY_H__
#include "interfaces/interface.h"
#include <stdint.h>
class JobResult;

View file

@ -24,26 +24,23 @@
#ifndef __ISTRATEGYLISTENER_H__
#define __ISTRATEGYLISTENER_H__
#include <stdint.h>
#include <string>
class Client;
class IStrategy;
class Job;
class SubmitResult;
class IStrategyListener
{
public:
virtual ~IStrategyListener() {}
virtual void onActive(Client* client) = 0;
virtual void onJob(Client* client, const Job & job) = 0;
virtual void onPause(IStrategy* strategy) = 0;
virtual void onResultAccepted(Client* client, const SubmitResult & result, const char* error) = 0;
virtual void onActive(Client* client) = 0;
virtual void onJob(Client* client, const Job & job) = 0;
virtual void onPause(IStrategy* strategy) = 0;
virtual void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) = 0;
};
#endif // __ISTRATEGYLISTENER_H__

View file

@ -0,0 +1,64 @@
/* XMRig - enWILLYado
*
* 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 __INTERFACE_H__
#define __INTERFACE_H__
#if __cplusplus <= 199711L
#define override
#define nullptr NULL
#endif
#ifdef _WIN32
#if defined(_MSC_VER) && _MSC_VER < 1900
// VS
#include <vadefs.h>
#include <stdio.h>
#include <stdarg.h>
#define snprintf c99_snprintf
#define vsnprintf c99_vsnprintf
__inline int c99_vsnprintf(char* outBuf, size_t size, const char* format, va_list ap)
{
int count = -1;
if(size != 0)
{
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
}
if(count == -1)
{
count = _vscprintf(format, ap);
}
return count;
}
__inline int c99_snprintf(char* outBuf, size_t size, const char* format, ...)
{
int count;
va_list ap;
va_start(ap, format);
count = c99_vsnprintf(outBuf, size, format, ap);
va_end(ap);
return count;
}
#endif
#endif
#endif // __INTERFACE_H__

View file

@ -21,143 +21,98 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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 <iostream>
#include "log/ConsoleLog.h"
#include "log/Log.h"
#include "Options.h"
ConsoleLog::ConsoleLog(bool colors) :
m_colors(colors),
m_stream(nullptr)
m_colors(colors)
{
if(uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0)
}
void ConsoleLog::message(Level level, const std::string & text)
{
if(!isWritable())
{
Options::i()->setColors(false);
m_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);
# ifdef WIN32
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
if(handle != INVALID_HANDLE_VALUE)
{
DWORD mode = 0;
if(GetConsoleMode(handle, &mode))
{
mode &= ~ENABLE_QUICK_EDIT_MODE;
SetConsoleMode(handle, mode | ENABLE_EXTENDED_FLAGS);
}
}
# endif
}
void ConsoleLog::message(int level, const char* fmt, va_list args)
{
//
//
time_t now = time(nullptr);
tm stime;
# ifdef _WIN32
#ifdef _WIN32
localtime_s(&stime, &now);
# else
#else
localtime_r(&now, &stime);
# endif
#endif
const char* color = nullptr;
char buf[25];
int size = snprintf(buf, sizeof(buf), "[%d-%02d-%02d %02d:%02d:%02d] ",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec);
//
//
std::string colorIni, colorEnd;
if(m_colors)
{
colorEnd = Log::CL_N();
switch(level)
{
case Log::ERR:
color = Log::kCL_RED;
case ILogBackend::ERR:
colorIni = Log::CL_RED();
break;
case Log::WARNING:
color = Log::kCL_YELLOW;
case ILogBackend::WARNING:
colorIni = Log::CL_YELLOW();
break;
case Log::NOTICE:
color = Log::kCL_WHITE;
case ILogBackend::NOTICE:
colorIni = Log::CL_WHITE();
break;
case Log::DEBUG:
color = Log::kCL_GRAY;
case ILogBackend::DEBUG:
colorIni = Log::CL_GRAY();
break;
default:
color = "";
break;
}
}
snprintf(m_fmt, sizeof(m_fmt) - 1, "[%d-%02d-%02d %02d:%02d:%02d]%s %s%s\n",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
stime.tm_hour,
stime.tm_min,
stime.tm_sec,
m_colors ? color : "",
fmt,
m_colors ? Log::kCL_N : ""
);
print(args);
print(std::string(buf, size) + colorIni + text + colorEnd);
}
void ConsoleLog::text(const char* fmt, va_list args)
void ConsoleLog::text(const std::string & txt)
{
snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : "");
print(args);
}
bool ConsoleLog::isWritable() const
{
if(!m_stream || uv_is_writable(m_stream) != 1)
{
return false;
}
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)
if(!isWritable())
{
return;
}
if(!isWritable())
{
fputs(m_buf, stdout);
fflush(stdout);
}
else
{
uv_try_write(m_stream, &m_uvBuf, 1);
}
print(txt);
}
bool ConsoleLog::isWritable() const
{
return std::cout.good();
}
void ConsoleLog::print(const std::string & txt)
{
std::cout << txt << std::endl;
std::cout.flush();
}

View file

@ -36,19 +36,14 @@ class ConsoleLog : public ILogBackend
public:
ConsoleLog(bool colors);
void message(int level, const char* fmt, va_list args) override;
void text(const char* fmt, va_list args) override;
void message(Level level, const std::string & txt) override;
void text(const std::string & txt) override;
private:
bool isWritable() const;
void print(va_list args);
void print(const std::string & txt);
bool m_colors;
char m_buf[512];
char m_fmt[256];
uv_buf_t m_uvBuf;
uv_stream_t* m_stream;
uv_tty_t m_tty;
};
#endif /* __CONSOLELOG_H__ */

View file

@ -28,36 +28,37 @@
#include <string.h>
#include <time.h>
#include <fstream>
#include <iostream>
#include "log/Log.h"
#include "log/FileLog.h"
FileLog::FileLog(const char* fileName)
FileLog::FileLog(const std::string & fileName)
: m_file_name(fileName)
{
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);
}
void FileLog::message(int level, const char* fmt, va_list args)
void FileLog::message(Level level, const std::string & txt)
{
if(m_file < 0)
if(!isWritable())
{
return;
}
//
//
time_t now = time(nullptr);
tm stime;
# ifdef _WIN32
#ifdef _WIN32
localtime_s(&stime, &now);
# else
#else
localtime_r(&now, &stime);
# endif
#endif
char* buf = new char[512];
int size = snprintf(buf, 23, "[%d-%02d-%02d %02d:%02d:%02d] ",
char buf[25];
int size = snprintf(buf, sizeof(buf), "[%d-%02d-%02d %02d:%02d:%02d] ",
stime.tm_year + 1900,
stime.tm_mon + 1,
stime.tm_mday,
@ -65,34 +66,30 @@ void FileLog::message(int level, const char* fmt, va_list args)
stime.tm_min,
stime.tm_sec);
size = vsnprintf(buf + size, 512 - size - 1, fmt, args) + size;
buf[size] = '\n';
write(buf, size + 1);
//
//
write(std::string(buf, size) + txt);
}
void FileLog::text(const char* fmt, va_list args)
void FileLog::text(const std::string & txt)
{
message(0, fmt, args);
if(!isWritable())
{
return;
}
write(txt);
}
void FileLog::onWrite(uv_fs_t* req)
bool FileLog::isWritable() const
{
delete [] static_cast<char*>(req->data);
uv_fs_req_cleanup(req);
delete req;
return (m_file_name != "") && std::ofstream(m_file_name, std::ios_base::app).good();
}
void FileLog::write(char* data, size_t size)
void FileLog::write(const std::string & txt)
{
uv_buf_t buf = uv_buf_init(data, (unsigned int) size);
uv_fs_t* req = new uv_fs_t;
req->data = buf.base;
std::ofstream outfile;
uv_fs_write(uv_default_loop(), req, m_file, &buf, 1, 0, FileLog::onWrite);
outfile.open(m_file_name, std::ios_base::app);
outfile << txt << std::endl;
}

View file

@ -24,27 +24,21 @@
#ifndef __FILELOG_H__
#define __FILELOG_H__
#include <uv.h>
#include "interfaces/ILogBackend.h"
class FileLog : public ILogBackend
{
public:
FileLog(const char* fileName);
FileLog(const std::string & fileName);
void message(int level, const char* fmt, va_list args) override;
void text(const char* fmt, va_list args) override;
void message(Level level, const std::string & txt) override;
void text(const std::string & txt) override;
private:
static void onWrite(uv_fs_t* req);
bool isWritable() const;
void write(const std::string & txt);
void write(char* data, size_t size);
int m_file;
const std::string m_file_name;
};
#endif /* __FILELOG_H__ */

View file

@ -28,50 +28,35 @@
#include <string.h>
#include <time.h>
#include "interfaces/ILogBackend.h"
#include "log/Log.h"
Log* Log::m_self = nullptr;
void Log::message(Log::Level level, const char* fmt, ...)
void Log::message(ILogBackend::Level level, const std::string & text)
{
va_list args;
va_list copy;
va_start(args, fmt);
for(ILogBackend* backend : m_backends)
for(size_t i = 0; i < m_backends.size(); ++i)
{
va_copy(copy, args);
backend->message(level, fmt, copy);
va_end(copy);
auto backend = m_backends[i];
backend->message(level, text);
}
}
void Log::text(const char* fmt, ...)
void Log::text(const std::string & text)
{
va_list args;
va_list copy;
va_start(args, fmt);
for(ILogBackend* backend : m_backends)
for(size_t i = 0; i < m_backends.size(); ++i)
{
va_copy(copy, args);
backend->text(fmt, copy);
va_end(copy);
auto backend = m_backends[i];
backend->text(text);
}
va_end(args);
}
Log::~Log()
{
for(auto backend : m_backends)
for(size_t i = 0; i < m_backends.size(); ++i)
{
auto backend = m_backends[i];
delete backend;
}
}

View file

@ -24,36 +24,45 @@
#ifndef __LOG_H__
#define __LOG_H__
#include <uv.h>
#include <vector>
#include <sstream>
class ILogBackend;
#include "interfaces/ILogBackend.h"
class Log
{
public:
enum Level
static const std::string & CL_N()
{
static const std::string kCL_N = "\x1B[0m";
return kCL_N;
}
static const std::string & CL_RED()
{
static const std::string kCL_RED = "\x1B[31m";
return kCL_RED;
}
static const std::string & CL_YELLOW()
{
static const std::string kCL_YELLOW = "\x1B[33m";
return kCL_YELLOW;
}
static const std::string & CL_WHITE()
{
static const std::string kCL_WHITE = "\x1B[01;37m";
return kCL_WHITE;
}
static const std::string & CL_GRAY()
{
ERR,
WARNING,
NOTICE,
INFO,
DEBUG
};
constexpr static const char* kCL_N = "\x1B[0m";
constexpr static const char* kCL_RED = "\x1B[31m";
constexpr static const char* kCL_YELLOW = "\x1B[33m";
constexpr static const char* kCL_WHITE = "\x1B[01;37m";
# ifdef WIN32
constexpr static const char* kCL_GRAY = "\x1B[01;30m";
# else
constexpr static const char* kCL_GRAY = "\x1B[90m";
# endif
#ifdef WIN32
static const std::string kCL_GRAY = "\x1B[01;30m";
#else
static const std::string kCL_GRAY = "\x1B[90m";
#endif
return kCL_GRAY;
}
static inline Log* i()
{
@ -75,9 +84,22 @@ public:
delete m_self;
}
void message(Level level, const char* fmt, ...);
void text(const char* fmt, ...);
void message(ILogBackend::Level level, const std::string & text);
void text(const std::string & text);
static inline std::string TO_STRING(const std::basic_ostream<char> & i)
{
const std::ostringstream & stream = static_cast<const std::ostringstream &>(i);
return stream.str();
}
template<class T>
static inline std::string ToString(const T & i)
{
std::stringstream stream;
stream << i;
return stream.str();
}
private:
inline Log() {}
~Log();
@ -87,23 +109,25 @@ private:
};
#define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
#define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
#define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__)
#define LOG_INFO(x, ...) Log::i()->message(Log::INFO, x, ##__VA_ARGS__)
#define PRINT_MSG(x) Log::i()->text(Log::TO_STRING(std::ostringstream() << " " << x))
#define LOG_ERR(x) Log::i()->message(ILogBackend::ERR, Log::TO_STRING(std::ostringstream() << " " << x))
#define LOG_WARN(x) Log::i()->message(ILogBackend::WARNING, Log::TO_STRING(std::ostringstream() << " " << x))
#define LOG_NOTICE(x) Log::i()->message(ILogBackend::NOTICE, Log::TO_STRING(std::ostringstream() << " " << x))
#define LOG_INFO(x) Log::i()->message(ILogBackend::INFO, Log::TO_STRING(std::ostringstream() << " " << x))
#ifdef APP_DEBUG
# define LOG_DEBUG(x, ...) Log::i()->message(Log::DEBUG, x, ##__VA_ARGS__)
#define LOG_DEBUG(x) Log::i()->message(ILogBackend::DEBUG, Log::TO_STRING(std::ostringstream() << " " << x))
#else
# define LOG_DEBUG(x, ...)
#define LOG_DEBUG(x)
#endif
#if defined(APP_DEBUG) || defined(APP_DEVEL)
# define LOG_DEBUG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__)
# define LOG_DEBUG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__)
#define LOG_DEBUG_ERR(x) Log::i()->message(ILogBackend::ERR, Log::TO_STRING(std::ostringstream() << " " << x))
#define LOG_DEBUG_WARN(x) Log::i()->message(ILogBackend::WARNING, Log::TO_STRING(std::ostringstream() << " " << x))
#else
# define LOG_DEBUG_ERR(x, ...)
# define LOG_DEBUG_WARN(x, ...)
#define LOG_DEBUG_ERR(x)
#define LOG_DEBUG_WARN(x)
#endif
#endif /* __LOG_H__ */

View file

@ -21,6 +21,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
@ -34,14 +35,15 @@ SysLog::SysLog()
openlog(APP_ID, LOG_PID, LOG_USER);
}
void SysLog::message(int level, const char* fmt, va_list args)
void SysLog::text(const std::string & txt)
{
vsyslog(level, fmt, args);
message(INFO, txt);
}
void SysLog::text(const char* fmt, va_list args)
void SysLog::message(Level level, const std::string & txt)
{
message(LOG_INFO, fmt, args);
syslog(level == INFO ? LOG_INFO : LOG_NOTICE, "%s", txt.c_str());
}
#endif

View file

@ -33,8 +33,8 @@ class SysLog : public ILogBackend
public:
SysLog();
void message(int level, const char* fmt, va_list args) override;
void text(const char* fmt, va_list args) override;
void message(Level level, const std::string & txt) override;
void text(const std::string & txt) override;
};
#endif /* __SYSLOG_BACKEND_H__ */

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -37,26 +37,26 @@
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#ifdef XMRIG_PROXY_PROJECT
# include "proxy/JobResult.h"
#include "proxy/JobResult.h"
#else
# include "net/JobResult.h"
#include "net/JobResult.h"
#endif
#ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
#define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
int64_t Client::m_sequence = 1;
Client::Client(int id, const char* agent, IClientListener* listener) :
Client::Client(int id, const std::string & agent, IClientListener* listener) :
m_ipv6(false),
m_nicehash(false),
m_quiet(false),
m_encrypted(false),
m_agent(agent),
m_listener(listener),
m_id(id),
@ -68,8 +68,8 @@ Client::Client(int id, const char* agent, IClientListener* listener) :
m_stream(nullptr),
m_socket(nullptr)
{
memset(m_ip, 0, sizeof(m_ip));
memset(&m_hints, 0, sizeof(m_hints));
memset(m_keystream, 0, sizeof(m_keystream));
m_resolver.data = this;
@ -80,10 +80,10 @@ Client::Client(int id, const char* agent, IClientListener* listener) :
m_recvBuf.base = m_buf;
m_recvBuf.len = sizeof(m_buf);
# ifndef XMRIG_PROXY_PROJECT
#ifndef XMRIG_PROXY_PROJECT
m_keepAliveTimer.data = this;
uv_timer_init(uv_default_loop(), &m_keepAliveTimer);
# endif
#endif
}
@ -104,20 +104,30 @@ void Client::connect()
*
* @param url
*/
void Client::connect(const Url* url)
void Client::connect(const Url & url)
{
setUrl(url);
resolve(m_url.host());
}
void Client::setUrl(const Url* url)
void Client::setUrl(const Url & url)
{
if(!url || !url->isValid())
if(false == url.isValid())
{
return;
}
if(url.hasKeystream())
{
url.copyKeystream(m_keystream, sizeof(m_keystream));
m_encrypted = true;
}
else
{
m_encrypted = false;
}
m_url = url;
}
@ -131,7 +141,7 @@ void Client::tick(uint64_t now)
if(m_state == ConnectedState)
{
LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port());
LOG_DEBUG_ERR("[" << m_url.host() << ":" << m_url.port() << "] timeout");
close();
}
@ -142,12 +152,11 @@ void Client::tick(uint64_t now)
}
}
bool Client::disconnect()
{
# ifndef XMRIG_PROXY_PROJECT
#ifndef XMRIG_PROXY_PROJECT
uv_timer_stop(&m_keepAliveTimer);
# endif
#endif
m_expire = 0;
m_failures = -1;
@ -158,24 +167,29 @@ bool Client::disconnect()
int64_t Client::submit(const JobResult & result)
{
# ifdef XMRIG_PROXY_PROJECT
const char* nonce = result.nonce;
const char* data = result.result;
# else
char nonce[9];
char data[65];
#ifdef XMRIG_PROXY_PROJECT
const std::string nonce = result.nonce;
const std::string data = result.result;
#else
char nonce_buffer[9];
char data_buffer[65];
Job::toHex(reinterpret_cast<const unsigned char*>(&result.nonce), 4, nonce);
nonce[8] = '\0';
char* nonceChar = (char*)(&result.nonce);
Job::toHex(std::string(nonceChar, 4), nonce_buffer);
nonce_buffer[8] = '\0';
Job::toHex(result.result, 32, data);
data[64] = '\0';
# endif
char* resultChar = (char*)(&result.result);
Job::toHex(std::string(resultChar, 32), data_buffer);
data_buffer[64] = '\0';
const std::string nonce = nonce_buffer;
const std::string data = data_buffer;
#endif
const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf),
"{\"id\":%" PRIu64
",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
m_sequence, m_rpcId.data().c_str(), result.jobId.data().c_str(), nonce.c_str(), data.c_str());
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
return send(size);
@ -200,24 +214,24 @@ bool Client::close()
}
bool Client::isCriticalError(const char* message)
bool Client::isCriticalError(const std::string & message)
{
if(!message)
if(message.empty())
{
return false;
}
if(strncasecmp(message, "Unauthenticated", 15) == 0)
if(message == "Unauthenticated")
{
return true;
}
if(strncasecmp(message, "your IP is banned", 17) == 0)
if(message == "your IP is banned")
{
return true;
}
if(strncasecmp(message, "IP Address currently banned", 27) == 0)
if(message == "IP Address currently banned")
{
return true;
}
@ -267,7 +281,7 @@ bool Client::parseJob(const rapidjson::Value & params, int* code)
{
if(!m_quiet)
{
LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port());
LOG_WARN("[" << m_url.host() << ":" << m_url.port() << "] duplicate job received, reconnect");
}
close();
@ -289,6 +303,14 @@ bool Client::parseLogin(const rapidjson::Value & result, int* code)
m_nicehash = m_url.isNicehash();
const rapidjson::Value & keystream = result["keystream"];
if(true == keystream.IsString())
{
const std::string newkeystream = keystream.GetString();
memcpy(m_keystream, newkeystream.c_str(), std::min(sizeof(m_keystream), newkeystream.size()));
m_encrypted = true;
}
if(result.HasMember("extensions"))
{
parseExtensions(result["extensions"]);
@ -298,7 +320,7 @@ bool Client::parseLogin(const rapidjson::Value & result, int* code)
}
int Client::resolve(const char* host)
int Client::resolve(const std::string & host)
{
setState(HostLookupState);
@ -310,12 +332,12 @@ int Client::resolve(const char* host)
m_failures = 0;
}
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, NULL, &m_hints);
const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host.c_str(), NULL, &m_hints);
if(r)
{
if(!m_quiet)
{
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r));
LOG_ERR("[" << host << ":" << m_url.port() << "] getaddrinfo error: \"" << uv_strerror(r) << "\"");
}
return 1;
}
@ -324,15 +346,33 @@ int Client::resolve(const char* host)
}
int64_t Client::send(size_t size)
int64_t Client::send(size_t size, const bool encrypted)
{
LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf);
if(state() != ConnectedState || !uv_is_writable(m_stream))
LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] send(" << size << " bytes): \"" << m_sendBuf <<
"\"");
if((state() != ConnectedState && state() != ProxingState) || !uv_is_writable(m_stream))
{
LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state);
LOG_DEBUG_ERR("[" << m_url.host() << ":" << m_url.port() << "] send failed, invalid state: " << m_state);
return -1;
}
if(encrypted && m_encrypted)
{
// Encrypt
for(size_t i = 0; i < std::min(size, sizeof(SendBuf)); ++i)
{
m_sendBuf[i] ^= m_keystream[i];
}
char* send_encr_hex = static_cast<char*>(malloc(size * 2 + 1));
memset(send_encr_hex, 0, size * 2 + 1);
Job::toHex(std::string(m_sendBuf, size), send_encr_hex);
send_encr_hex[size * 2] = '\0';
LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] send encr.(" << size << " bytes): \"0x" <<
send_encr_hex << "\"");
free(send_encr_hex);
}
uv_buf_t buf = uv_buf_init(m_sendBuf, (unsigned int) size);
if(uv_try_write(m_stream, &buf, 1) < 0)
@ -354,19 +394,19 @@ void Client::connect(const std::vector<addrinfo*> & ipv4, const std::vector<addr
if(m_ipv6)
{
addr = ipv6[ipv6.size() == 1 ? 0 : rand() % ipv6.size()];
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), m_ip, 45);
uv_ip6_name(reinterpret_cast<sockaddr_in6*>(addr->ai_addr), (char*)m_ip.c_str(), 45);
}
else
{
addr = ipv4[ipv4.size() == 1 ? 0 : rand() % ipv4.size()];
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), m_ip, 16);
uv_ip4_name(reinterpret_cast<sockaddr_in*>(addr->ai_addr), (char*)m_ip.c_str(), 16);
}
connect(addr->ai_addr);
}
void Client::connect(sockaddr* addr)
void Client::connect(struct sockaddr* addr)
{
setState(ConnectingState);
@ -382,13 +422,35 @@ void Client::connect(sockaddr* addr)
uv_tcp_init(uv_default_loop(), m_socket);
uv_tcp_nodelay(m_socket, 1);
# ifndef WIN32
#ifndef WIN32
uv_tcp_keepalive(m_socket, 1, 60);
# endif
#endif
uv_tcp_connect(req, m_socket, reinterpret_cast<const sockaddr*>(addr), Client::onConnect);
}
void Client::prelogin()
{
if(m_url.isProxyed())
{
setState(ProxingState);
const std::string buffer = std::string("CONNECT ") + m_url.finalHost() + ":" +
std::to_string((unsigned long long)(m_url.finalPort())) + " HTTP/1.1\n";
const size_t size = buffer.size();
memcpy(m_sendBuf, buffer.c_str(), size);
m_sendBuf[size] = '\n';
m_sendBuf[size + 1] = '\0';
LOG_DEBUG("Prelogin send (" << size << " bytes): \"" << m_sendBuf << "\"");
send(size + 1, false);
}
else
{
setState(ConnectedState);
login();
}
}
void Client::login()
{
@ -404,9 +466,9 @@ void Client::login()
doc.AddMember("method", "login", allocator);
rapidjson::Value params(rapidjson::kObjectType);
params.AddMember("login", rapidjson::StringRef(m_url.user()), allocator);
params.AddMember("pass", rapidjson::StringRef(m_url.password()), allocator);
params.AddMember("agent", rapidjson::StringRef(m_agent), allocator);
params.AddMember("login", rapidjson::StringRef(m_url.user().c_str()), allocator);
params.AddMember("pass", rapidjson::StringRef(m_url.password().c_str()), allocator);
params.AddMember("agent", rapidjson::StringRef(m_agent.c_str()), allocator);
doc.AddMember("params", params, allocator);
@ -434,11 +496,12 @@ void Client::parse(char* line, size_t len)
line[len - 1] = '\0';
LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line);
LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] received (" << len << " bytes): \"" << line <<
"\"");
if(len < 32 || line[0] != '{')
{
LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port());
LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] JSON decode failed");
return;
}
@ -447,8 +510,8 @@ void Client::parse(char* line, size_t len)
{
if(!m_quiet)
{
LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(),
rapidjson::GetParseError_En(doc.GetParseError()));
LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] JSON decode failed: \"" <<
rapidjson::GetParseError_En(doc.GetParseError()) << "\"");
}
return;
@ -478,8 +541,9 @@ void Client::parseExtensions(const rapidjson::Value & value)
return;
}
for(const rapidjson::Value & ext : value.GetArray())
for(size_t i = 0; i < value.GetArray().Size(); ++i)
{
const rapidjson::Value & ext = value.GetArray()[i];
if(!ext.IsString())
{
continue;
@ -493,25 +557,25 @@ void Client::parseExtensions(const rapidjson::Value & value)
}
void Client::parseNotification(const char* method, const rapidjson::Value & params,
void Client::parseNotification(const std::string & method, const rapidjson::Value & params,
const rapidjson::Value & error)
{
if(error.IsObject())
{
if(!m_quiet)
{
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), error["message"].GetString(),
error["code"].GetInt());
LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] error: \"" << error["message"].GetString() <<
"\", code: " << error["code"].GetInt());
}
return;
}
if(!method)
if(0 == method.size())
{
return;
}
if(strcmp(method, "job") == 0)
if(method == "job")
{
int code = -1;
if(parseJob(params, &code))
@ -522,7 +586,7 @@ void Client::parseNotification(const char* method, const rapidjson::Value & para
return;
}
LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method);
LOG_WARN("[" << m_url.host() << ":" << m_url.port() << "] unsupported method: \"" << method << "\"");
}
@ -530,7 +594,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
{
if(error.IsObject())
{
const char* message = error["message"].GetString();
const std::string message = error["message"].GetString();
auto it = m_results.find(id);
if(it != m_results.end())
@ -541,7 +605,8 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
}
else if(!m_quiet)
{
LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt());
LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] error: \"" << message << "\", code: " <<
error["code"].GetInt());
}
if(id == 1 || isCriticalError(message))
@ -564,7 +629,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
{
if(!m_quiet)
{
LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code);
LOG_ERR("[" << m_url.host() << ":" << m_url.port() << "] login error code: " << code);
}
close();
@ -581,7 +646,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
if(it != m_results.end())
{
it->second.done();
m_listener->onResultAccepted(this, it->second, nullptr);
m_listener->onResultAccepted(this, it->second, "");
m_results.erase(it);
}
}
@ -590,27 +655,27 @@ void Client::parseResponse(int64_t id, const rapidjson::Value & result, const ra
void Client::ping()
{
send(snprintf(m_sendBuf, sizeof(m_sendBuf),
"{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n", m_sequence,
m_rpcId.data()));
"{\"id\":%" PRId64 ",\"jsonrpc\":\"2.0\",\"method\":\"keepalived\",\"params\":{\"id\":\"%s\"}}\n",
m_sequence, m_rpcId.data().c_str()));
}
void Client::reconnect()
{
setState(ConnectingState);
# ifndef XMRIG_PROXY_PROJECT
if(m_url.isKeepAlive())
{
uv_timer_stop(&m_keepAliveTimer);
}
# endif
if(m_failures == -1)
{
return m_listener->onClose(this, -1);
}
setState(ConnectingState);
#ifndef XMRIG_PROXY_PROJECT
if(m_url.isKeepAlive())
{
uv_timer_stop(&m_keepAliveTimer);
}
#endif
m_failures++;
m_listener->onClose(this, (int) m_failures);
@ -620,7 +685,7 @@ void Client::reconnect()
void Client::setState(SocketState state)
{
LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state);
LOG_DEBUG("[" << m_url.host() << ":" << m_url.port() << "] state: " << state);
if(m_state == state)
{
@ -635,26 +700,27 @@ void Client::startTimeout()
{
m_expire = 0;
# ifndef XMRIG_PROXY_PROJECT
#ifndef XMRIG_PROXY_PROJECT
if(!m_url.isKeepAlive())
{
return;
}
uv_timer_start(&m_keepAliveTimer, [](uv_timer_t* handle)
{
getClient(handle->data)->ping();
}, kKeepAliveTimeout, 0);
# endif
uv_timer_start(&m_keepAliveTimer, &Client::onTimeout, kKeepAliveTimeout, 0);
#endif
}
void Client::onTimeout(uv_timer_t* handle)
{
getClient(handle->data)->ping();
}
void Client::onAllocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
{
auto client = getClient(handle->data);
buf->base = &client->m_recvBuf.base[client->m_recvBufPos];
buf->len = client->m_recvBuf.len - client->m_recvBufPos;
buf->len = client->m_recvBuf.len - (unsigned long)client->m_recvBufPos;
}
@ -679,7 +745,8 @@ void Client::onConnect(uv_connect_t* req, int status)
{
if(!client->m_quiet)
{
LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() << "] connect error: \"" << uv_strerror(
status) << "\"");
}
delete req;
@ -689,12 +756,11 @@ void Client::onConnect(uv_connect_t* req, int status)
client->m_stream = static_cast<uv_stream_t*>(req->handle);
client->m_stream->data = req->data;
client->setState(ConnectedState);
uv_read_start(client->m_stream, Client::onAllocBuffer, Client::onRead);
delete req;
client->login();
client->prelogin();
}
@ -705,25 +771,57 @@ void Client::onRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
{
if(nread != UV_EOF && !client->m_quiet)
{
LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread));
LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() << "] read error: \"" << uv_strerror((
int) nread) << "\"");
}
client->close();
return;
}
if((size_t) nread > (sizeof(m_buf) - 8 - client->m_recvBufPos))
if((size_t) nread > (sizeof(Buf) - 8 - client->m_recvBufPos))
{
client->close();
return;
}
if(client->state() == ProxingState)
{
const char* const content = buf->base;
LOG_DEBUG("[" << client->m_url.host() << ":" << client->m_url.port() << "] received from proxy (" << nread <<
" bytes): \"" << content << "\"");
if(content == strstr(content, "HTTP/1.1 200"))
{
LOG_INFO("[" << client->m_url.host() << ":" << client->m_url.port() << "] Proxy connected to " <<
client->m_url.finalHost() << ":" << client->m_url.finalPort() << "!");
client->setState(ConnectedState);
client->login();
}
return;
}
client->m_recvBufPos += nread;
char* end;
char* start = client->m_recvBuf.base;
size_t remaining = client->m_recvBufPos;
if(client->m_encrypted)
{
char* read_encr_hex = static_cast<char*>(malloc(nread * 2 + 1));
memset(read_encr_hex, 0, nread * 2 + 1);
Job::toHex(std::string(start, nread), read_encr_hex);
LOG_DEBUG("[" << client->m_ip << "] read encr. (" << nread << " bytes): \"0x" << read_encr_hex << "\"");
free(read_encr_hex);
// DeEncrypt
for(int i = 0; i < (int)nread; ++i)
{
start[i] ^= client->m_keystream[i];
}
}
while((end = static_cast<char*>(memchr(start, '\n', remaining))) != nullptr)
{
end++;
@ -755,7 +853,8 @@ void Client::onResolved(uv_getaddrinfo_t* req, int status, struct addrinfo* res)
auto client = getClient(req->data);
if(status < 0)
{
LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status));
LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() << "] DNS error: \"" << uv_strerror(
status) << "\"");
return client->reconnect();
}
@ -780,8 +879,8 @@ void Client::onResolved(uv_getaddrinfo_t* req, int status, struct addrinfo* res)
if(ipv4.empty() && ipv6.empty())
{
LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(),
client->m_url.port());
LOG_ERR("[" << client->m_url.host() << ":" << client->m_url.port() <<
"] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"");
uv_freeaddrinfo(res);
return client->reconnect();

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -25,12 +25,11 @@
#define __CLIENT_H__
#include <vector>
#include <map>
#include <uv.h>
#include <vector>
#include "net/Id.h"
#include "net/Job.h"
#include "net/SubmitResult.h"
#include "net/Url.h"
@ -49,35 +48,43 @@ public:
UnconnectedState,
HostLookupState,
ConnectingState,
ProxingState,
ConnectedState,
ClosingState
};
constexpr static int kResponseTimeout = 20 * 1000;
constexpr static int kKeepAliveTimeout = 60 * 1000;
enum
{
kResponseTimeout = 20 * 1000,
kKeepAliveTimeout = 60 * 1000,
};
Client(int id, const char* agent, IClientListener* listener);
Client(int id, const std::string & agent, IClientListener* listener);
~Client();
bool disconnect();
int64_t submit(const JobResult & result);
void connect();
void connect(const Url* url);
void setUrl(const Url* url);
void connect(const Url & url);
void setUrl(const Url & url);
void tick(uint64_t now);
inline bool isReady() const
{
return m_state == ConnectedState && m_failures == 0;
}
inline const char* host() const
inline const std::string & host() const
{
return m_url.host();
}
inline const char* ip() const
inline const std::string & ip() const
{
return m_ip;
}
inline void setIP(const std::string & iIp)
{
m_ip = iIp;
}
inline const Job & job() const
{
return m_job;
@ -105,17 +112,19 @@ public:
private:
bool close();
bool isCriticalError(const char* message);
bool isCriticalError(const std::string & message);
bool parseJob(const rapidjson::Value & params, int* code);
bool parseLogin(const rapidjson::Value & result, int* code);
int resolve(const char* host);
int64_t send(size_t size);
int resolve(const std::string & host);
int64_t send(size_t size, const bool encrypted = true);
void connect(const std::vector<addrinfo*> & ipv4, const std::vector<addrinfo*> & ipv6);
void connect(sockaddr* addr);
void connect(struct sockaddr* addr);
void prelogin();
void login();
void parse(char* line, size_t len);
void parseExtensions(const rapidjson::Value & value);
void parseNotification(const char* method, const rapidjson::Value & params, const rapidjson::Value & error);
void parseNotification(const std::string & method, const rapidjson::Value & params,
const rapidjson::Value & error);
void parseResponse(int64_t id, const rapidjson::Value & result, const rapidjson::Value & error);
void ping();
void reconnect();
@ -125,6 +134,7 @@ private:
static void onAllocBuffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
static void onClose(uv_handle_t* handle);
static void onConnect(uv_connect_t* req, int status);
static void onTimeout(uv_timer_t* handle);
static void onRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
static void onResolved(uv_getaddrinfo_t* req, int status, struct addrinfo* res);
@ -133,14 +143,19 @@ private:
return static_cast<Client*>(data);
}
typedef char Buf[2048];
typedef char SendBuf[768];
addrinfo m_hints;
bool m_ipv6;
bool m_nicehash;
bool m_quiet;
char m_buf[2048];
char m_ip[46];
char m_sendBuf[768];
const char* m_agent;
char m_buf[sizeof(Buf)];
std::string m_ip;
char m_sendBuf[sizeof(SendBuf)];
char m_keystream[sizeof(SendBuf)];
bool m_encrypted;
const std::string & m_agent;
IClientListener* m_listener;
int m_id;
int m_retryPause;
@ -158,9 +173,9 @@ private:
uv_tcp_t* m_socket;
xmrig::Id m_rpcId;
# ifndef XMRIG_PROXY_PROJECT
#ifndef XMRIG_PROXY_PROJECT
uv_timer_t m_keepAliveTimer;
# endif
#endif
};

View file

@ -24,83 +24,61 @@
#ifndef __ID_H__
#define __ID_H__
#include <string.h>
#include <string>
namespace xmrig
{
class Id
{
public:
inline Id() :
m_data()
inline Id()
: m_data()
{
}
inline Id(const char* id, size_t sizeFix = 0)
inline Id(const std::string & id, size_t sizeFix = 0)
: m_data(id.substr(0, id.size() - sizeFix))
{
setId(id, sizeFix);
}
inline bool operator==(const Id & other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) == 0;
return m_data == other.m_data;
}
inline bool operator!=(const Id & other) const
{
return memcmp(m_data, other.m_data, sizeof(m_data)) != 0;
return !operator!=(other);
}
Id & operator=(const Id & other)
inline bool setId(const std::string & id, size_t sizeFix = 0)
{
memcpy(m_data, other.m_data, sizeof(m_data));
m_data.clear();
return *this;
}
inline bool setId(const char* id, size_t sizeFix = 0)
{
memset(m_data, 0, sizeof(m_data));
if(!id)
if(true == id.empty())
{
return false;
}
const size_t size = strlen(id);
if(size >= sizeof(m_data))
{
return false;
}
memcpy(m_data, id, size - sizeFix);
const size_t size = id.size();
m_data = id.substr(0, size - sizeFix);
return true;
}
inline const char* data() const
inline const std::string & data() const
{
return m_data;
}
inline bool isValid() const
{
return *m_data != '\0';
return 0 < m_data.size() && m_data[0] != '\0';
}
private:
char m_data[64];
std::string m_data;
};
} /* namespace xmrig */

View file

@ -4,9 +4,8 @@
* 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 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.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
@ -62,7 +61,6 @@ static inline char hf_bin2hex(unsigned char c)
Job::Job() :
m_nicehash(false),
m_coin(),
m_algo(xmrig::ALGO_CRYPTONIGHT),
m_poolId(-2),
m_threadId(-1),
@ -70,14 +68,13 @@ Job::Job() :
m_size(0),
m_diff(0),
m_target(0),
m_blob()
m_id()
{
}
Job::Job(int poolId, bool nicehash, int algo, int variant) :
m_nicehash(nicehash),
m_coin(),
m_algo(algo),
m_poolId(poolId),
m_threadId(-1),
@ -85,7 +82,7 @@ Job::Job(int poolId, bool nicehash, int algo, int variant) :
m_size(0),
m_diff(0),
m_target(0),
m_blob()
m_id()
{
}
@ -216,9 +213,9 @@ bool Job::fromHex(const char* in, unsigned int len, unsigned char* out)
}
void Job::toHex(const unsigned char* in, unsigned int len, char* out)
void Job::toHex(const std::string & in, char* out)
{
for(unsigned int i = 0; i < len; i++)
for(size_t i = 0; i < in.size(); ++i)
{
out[i * 2] = hf_bin2hex((in[i] & 0xF0) >> 4);
out[i * 2 + 1] = hf_bin2hex(in[i] & 0x0F);

View file

@ -28,6 +28,7 @@
#include <stddef.h>
#include <stdint.h>
#include <string>
#include "net/Id.h"
@ -120,7 +121,7 @@ public:
{
return 0xFFFFFFFFFFFFFFFFULL / target;
}
static void toHex(const unsigned char* in, unsigned int len, char* out);
static void toHex(const std::string & in, char* out);
bool operator==(const Job & other) const;

View file

@ -36,6 +36,7 @@ class JobResult
{
public:
inline JobResult() : poolId(0), diff(0), nonce(0) {}
inline JobResult(int poolId, const xmrig::Id & jobId, uint32_t nonce, const uint8_t* result, uint32_t diff) :
poolId(poolId),
diff(diff),

View file

@ -52,7 +52,7 @@ Network::Network(const Options* options) :
Workers::setListener(this);
const std::vector<Url*> & pools = options->pools();
const std::vector<Url> & pools = options->pools();
if(pools.size() > 1)
{
@ -63,7 +63,7 @@ Network::Network(const Options* options) :
m_strategy = new SinglePoolStrategy(pools.front(), Platform::userAgent(), this);
}
if(m_options->donateLevel() > 0)
if(m_options->donateMinutes() > 0)
{
m_donate = new DonateStrategy(Platform::userAgent(), this);
}
@ -101,20 +101,30 @@ void Network::onActive(Client* client)
{
if(client->id() == -1)
{
LOG_NOTICE("dev donate started");
return;
}
m_state.setPool(client->host(), client->port(), client->ip());
LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s",
client->host(), client->port(), client->ip());
LOG_INFO("use pool " << client->host() << ":" << client->port() << " " << client->ip());
}
void Network::onJob(Client* client, const Job & job)
{
if(m_donate && m_donate->isActive() && client->id() != -1)
if(m_options->colors())
{
/*
LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(),
client->port(), job.diff());
*/
}
else
{
LOG_INFO("new job from " << client->host() << ":" << client->port() << " diff " << job.diff());
}
if(m_donate && m_donate->reschedule(client->id() == -1))
{
return;
}
@ -139,7 +149,6 @@ void Network::onPause(IStrategy* strategy)
{
if(m_donate && m_donate == strategy)
{
LOG_NOTICE("dev donate finished");
m_strategy->resume();
}
@ -152,39 +161,49 @@ void Network::onPause(IStrategy* strategy)
}
void Network::onResultAccepted(Client* client, const SubmitResult & result, const char* error)
void Network::onResultAccepted(Client* client, const SubmitResult & result, const std::string & error)
{
m_state.add(result, error);
if(error)
if(0 < error.size())
{
LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64
") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
: "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)",
m_state.accepted, m_state.rejected, result.diff, error, result.elapsed);
if(m_options->colors())
{
/*
LOG_INFO("\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64
") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)",
m_state.accepted, m_state.rejected, result.diff, error, result.elapsed);
*/
}
else
{
LOG_INFO("rejected (" << m_state.accepted << "/" << m_state.rejected << ") diff " << result.diff << " \"" <<
error << "\" (" << result.elapsed << " ms)");
}
}
else
{
LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64
") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)"
: "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)",
m_state.accepted, m_state.rejected, result.diff, result.elapsed);
if(m_options->colors())
{
/*
LOG_INFO("\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64
") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)",
m_state.accepted, m_state.rejected, result.diff, result.elapsed);
*/
}
else
{
LOG_INFO("accepted (" << m_state.accepted << "/" << m_state.rejected << ") diff " << result.diff << " (" <<
result.elapsed << " ms)");
}
}
}
void Network::setJob(Client* client, const Job & job)
{
if(m_options->colors())
{
LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(),
client->port(), job.diff());
}
else
{
LOG_INFO("new job from %s:%d diff %d", client->host(), client->port(), job.diff());
}
m_state.diff = job.diff();
Workers::setJob(job);
}

View file

@ -33,7 +33,7 @@
#include "interfaces/IJobResultListener.h"
#include "interfaces/IStrategyListener.h"
class DonateStrategy;
class IStrategy;
class Options;
class Url;
@ -53,10 +53,13 @@ protected:
void onJob(Client* client, const Job & job) override;
void onJobResult(const JobResult & result) override;
void onPause(IStrategy* strategy) override;
void onResultAccepted(Client* client, const SubmitResult & result, const char* error) override;
void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) override;
private:
constexpr static int kTickInterval = 1 * 1000;
enum
{
kTickInterval = 1 * 1000
};
void setJob(Client* client, const Job & job);
void tick();
@ -64,7 +67,7 @@ private:
static void onTick(uv_timer_t* handle);
const Options* m_options;
IStrategy* m_donate;
DonateStrategy* m_donate;
IStrategy* m_strategy;
NetworkState m_state;
uv_timer_t m_timer;

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -21,34 +21,83 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#ifndef _WIN32
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#else
#include <winsock2.h>
#undef min
#undef max
#endif
#include "net/Url.h"
#include "xmrig.h"
#include "interfaces/interface.h"
#ifdef _MSC_VER
# define strncasecmp(x,y,z) _strnicmp(x,y,z)
#define strncasecmp(x,y,z) _strnicmp(x,y,z)
#endif
Url::Url() :
m_keepAlive(false),
m_nicehash(false),
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
m_algo(xmrig::ALGO_CRYPTONIGHT),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(kDefaultPort)
Url::Url()
: m_keepAlive(false),
m_nicehash(false),
m_host(),
m_password(),
m_user(),
m_port(kDefaultPort),
m_proxy_host(),
m_proxy_port(kDefaultProxyPort),
m_keystream()
{
}
Url::Url(const std::string & url)
: m_keepAlive(false),
m_nicehash(false),
m_host(),
m_password(),
m_user(),
m_algo(xmrig::ALGO_CRYPTONIGHT),
m_variant(xmrig::VARIANT_AUTO),
m_port(kDefaultPort),
m_proxy_host(),
m_proxy_port(kDefaultProxyPort),
m_keystream()
{
parse(url);
}
Url::Url(const std::string & host,
uint16_t port,
const std::string & user,
const std::string & password,
bool keepAlive,
bool nicehash,
int variant)
: m_keepAlive(keepAlive),
m_nicehash(nicehash),
m_host(host),
m_password(password),
m_user(user),
m_algo(xmrig::ALGO_CRYPTONIGHT),
m_variant(variant),
m_port(port),
m_proxy_host(),
m_proxy_port(kDefaultProxyPort),
m_keystream()
{
}
Url::~Url()
{
}
/**
* @brief Parse url.
@ -56,127 +105,117 @@ Url::Url() :
* Valid urls:
* example.com
* example.com:3333
* example.com:3333#keystream
* example.com:3333@proxy
* example.com:3333@proxy:8080
* example.com:3333#keystream@proxy
* example.com:3333#keystream@proxy:8080
* stratum+tcp://example.com
* stratum+tcp://example.com:3333
* stratum+tcp://example.com:3333#keystream
* stratum+tcp://example.com:3333@proxy
* stratum+tcp://example.com:3333@proxy:8080
* stratum+tcp://example.com:3333#keystream@proxy
* stratum+tcp://example.com:3333#keystream@proxy:8080
*
* @param url
*/
Url::Url(const char* url) :
m_keepAlive(false),
m_nicehash(false),
m_host(nullptr),
m_password(nullptr),
m_user(nullptr),
m_algo(xmrig::ALGO_CRYPTONIGHT),
m_variant(xmrig::VARIANT_AUTO),
m_url(nullptr),
m_port(kDefaultPort)
bool Url::parse(const std::string & url)
{
parse(url);
}
size_t base = 0;
Url::Url(const char* host, uint16_t port, const char* user, const char* password, bool keepAlive,
bool nicehash, int variant) :
m_keepAlive(keepAlive),
m_nicehash(nicehash),
m_password(password ? strdup(password) : nullptr),
m_user(user ? strdup(user) : nullptr),
m_algo(xmrig::ALGO_CRYPTONIGHT),
m_variant(variant),
m_url(nullptr),
m_port(port)
{
m_host = strdup(host);
}
Url::~Url()
{
free(m_host);
free(m_password);
free(m_user);
if(m_url)
const size_t p = url.find("://");
if(p != std::string::npos)
{
delete [] m_url;
}
}
bool Url::parse(const char* url)
{
const char* p = strstr(url, "://");
const char* base = url;
if(p)
{
if(strncasecmp(url, "stratum+tcp://", 14))
static const std::string STRATUM_PREFIX = "stratum+tcp://";
if(strncasecmp(url.c_str(), STRATUM_PREFIX.c_str(), STRATUM_PREFIX.size()))
{
return false;
}
base = url + 14;
base = STRATUM_PREFIX.size();
}
if(!strlen(base) || *base == '/')
const std::string path = url.substr(base);
if(path.empty() || path[0] == '/')
{
return false;
}
if(base[0] == '[')
const size_t port = path.find_first_of(':');
size_t portini = port;
if(port != std::string::npos)
{
return parseIPv6(base);
m_host = path.substr(0, port);
m_port = (uint16_t) strtol(path.substr(port + 1).c_str(), nullptr, 10);
}
else
{
portini = 0;
}
const char* port = strchr(base, ':');
if(!port)
const size_t proxy = path.find_first_of('@', portini);
const size_t keystream = path.find_first_of('#', portini);
if(keystream != std::string::npos)
{
m_host = strdup(base);
if(port == std::string::npos)
{
m_host = path.substr(0, keystream);
}
if(proxy != std::string::npos)
{
m_keystream = path.substr(keystream + 1, proxy - keystream - 1);
}
else
{
m_keystream = path.substr(keystream + 1);
}
}
if(proxy == std::string::npos)
{
if(port == std::string::npos && keystream == std::string::npos)
{
m_host = path;
}
return true;
}
else
{
if(port == std::string::npos && keystream == std::string::npos)
{
m_host = path.substr(0, proxy);
}
}
const size_t proxyini = proxy + 1;
const size_t proxyport = path.find_first_of(':', proxyini);
if(proxyport == std::string::npos)
{
m_proxy_host = path.substr(proxyini);
return false;
}
const size_t size = port++ - base + 1;
m_host = new char[size]();
memcpy(m_host, base, size - 1);
m_port = (uint16_t) strtol(port, nullptr, 10);
return true;
}
bool Url::setUserpass(const char* userpass)
{
const char* p = strchr(userpass, ':');
if(!p)
{
return false;
}
free(m_user);
free(m_password);
m_user = static_cast<char*>(calloc(p - userpass + 1, 1));
strncpy(m_user, userpass, p - userpass);
m_password = strdup(p + 1);
m_proxy_host = path.substr(proxyini, proxyport - proxyini);
m_proxy_port = (uint16_t) strtol(path.substr(proxyport + 1).c_str(), nullptr, 10);
return true;
}
const char* Url::url() const
bool Url::setUserpass(const std::string & userpass)
{
if(!m_url)
const size_t p = userpass.find_first_of(':');
if(p == std::string::npos)
{
const size_t size = strlen(m_host) + 8;
m_url = new char[size];
snprintf(m_url, size - 1, "%s:%d", m_host, m_port);
return false;
}
return m_url;
}
setUser(userpass.substr(0, p));
setPassword(userpass.substr(p + 1));
return true;
}
void Url::adjust(int algo)
{
@ -187,43 +226,141 @@ void Url::adjust(int algo)
m_algo = algo;
if(strstr(m_host, ".nicehash.com"))
if(m_host.find(".nicehash.com") != std::string::npos)
{
m_keepAlive = false;
m_nicehash = true;
}
if(strstr(m_host, ".minergate.com"))
if(m_host.find(".minergate.com") != std::string::npos)
{
m_keepAlive = false;
}
}
void Url::setPassword(const char* password)
static std::string & Replace(std::string & str, const std::string & what, const std::string & other)
{
if(!password)
if(str.empty() || what.empty() || what == other)
{
return;
return str;
}
free(m_password);
m_password = strdup(password);
size_t start_pos = 0;
while((start_pos = str.find(what, start_pos)) != std::string::npos)
{
str.replace(start_pos, what.length(), other);
start_pos += other.length();
}
return str;
}
static std::string GetHostName()
{
char hostname[1024] = {'\0'};
if(0 == gethostname(hostname, sizeof(hostname) - 1))
{
// get hostname
for(int i = 0; hostname[i] != '\0'; ++i)
{
if(hostname[i] == '.' || hostname[i] == '+')
{
hostname[i] = '_';
}
}
}
return hostname;
}
static std::string GetIpAddrs()
{
std::string ret;
#ifndef _WIN32
struct ifaddrs* ifAddrStruct = NULL;
struct ifaddrs* ifa = NULL;
void* tmpAddrPtr = NULL;
if(0 == getifaddrs(&ifAddrStruct))
{
for(ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
{
if(!ifa->ifa_addr)
{
continue;
}
if(ifa->ifa_addr->sa_family == AF_INET) // check it is IP4
{
// is a valid IP4 Address
tmpAddrPtr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
ret = addressBuffer;
}
else if(ifa->ifa_addr->sa_family == AF_INET6) // check it is IP6
{
// is a valid IP6 Address
tmpAddrPtr = &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr;
char addressBuffer[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
ret = addressBuffer;
}
}
}
if(ifAddrStruct != NULL)
{
freeifaddrs(ifAddrStruct);
}
#else
char hostname[1024] = {'\0'};
gethostname(hostname, sizeof(hostname) - 1);
struct hostent* hostentry = gethostbyname(hostname);
// get ip
if(hostentry != NULL)
{
const char* const ipbuf = inet_ntoa(*((struct in_addr*)hostentry->h_addr_list[0]));
if(ipbuf != NULL)
{
ret = ipbuf;
}
}
#endif
for(size_t i = 0; i < ret.size(); ++i)
{
if(ret[i] == '.' || ret[i] == '+' || ret[i] == '_')
{
ret[i] = '_';
}
}
return ret;
}
static std::string replaceWithTokens(const std::string & value)
{
static const std::string HOST_NAME = GetHostName();
static const std::string IP_ADDRS = GetIpAddrs();
// set user replacing tokens
std::string ret = value;
ret = Replace(ret, "%HOST_NAME%", HOST_NAME);
ret = Replace(ret, "%IP_ADDRS%", IP_ADDRS);
return ret;
}
void Url::setPassword(const std::string & password)
{
m_password = replaceWithTokens(password);
}
void Url::setUser(const char* user)
void Url::setUser(const std::string & user)
{
if(!user)
{
return;
}
free(m_user);
m_user = strdup(user);
m_user = replaceWithTokens(user);
}
/*
void Url::setVariant(int variant)
{
switch(variant)
@ -238,68 +375,13 @@ void Url::setVariant(int variant)
break;
}
}
*/
bool Url::operator==(const Url & other) const
void Url::copyKeystream(char* keystreamDest, const size_t keystreamLen) const
{
if(m_port != other.m_port || m_keepAlive != other.m_keepAlive || m_nicehash != other.m_nicehash)
if(hasKeystream())
{
return false;
memset(keystreamDest, 1, keystreamLen);
memcpy(keystreamDest, m_keystream.c_str(), std::min(keystreamLen, m_keystream.size()));
}
if(strcmp(host(), other.host()) != 0 || strcmp(user(), other.user()) != 0 ||
strcmp(password(), other.password()) != 0)
{
return false;
}
return true;
}
Url & Url::operator=(const Url* other)
{
m_keepAlive = other->m_keepAlive;
m_algo = other->m_algo;
m_variant = other->m_variant;
m_nicehash = other->m_nicehash;
m_port = other->m_port;
free(m_host);
m_host = strdup(other->m_host);
setPassword(other->m_password);
setUser(other->m_user);
if(m_url)
{
delete [] m_url;
m_url = nullptr;
}
return *this;
}
bool Url::parseIPv6(const char* addr)
{
const char* end = strchr(addr, ']');
if(!end)
{
return false;
}
const char* port = strchr(end, ':');
if(!port)
{
return false;
}
const size_t size = end - addr;
m_host = new char[size]();
memcpy(m_host, addr + 1, size - 1);
m_port = (uint16_t) strtol(port + 1, nullptr, 10);
return true;
}

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -24,20 +24,36 @@
#ifndef __URL_H__
#define __URL_H__
#include <stdint.h>
#include <string>
#include "interfaces/interface.h"
class Url
{
public:
constexpr static const char* kDefaultPassword = "x";
constexpr static const char* kDefaultUser = "x";
constexpr static uint16_t kDefaultPort = 3333;
static const std::string & DefaultPassword()
{
static const std::string kDefaultPassword = "x";
return kDefaultPassword;
}
static const std::string & DefaultUser()
{
static const std::string kDefaultUser = "";
return kDefaultUser;
}
enum
{
kDefaultPort = 3333,
kDefaultProxyPort = 8080,
};
Url();
Url(const char* url);
Url(const char* host, uint16_t port, const char* user = nullptr, const char* password = nullptr,
Url(const std::string & url);
Url(const std::string & host, uint16_t port, const std::string & user = "",
const std::string & password = "",
bool keepAlive = false, bool nicehash = false, int variant = -1);
~Url();
@ -51,19 +67,23 @@ public:
}
inline bool isValid() const
{
return m_host && m_port > 0;
return m_host.size() > 0 && m_port > 0;
}
inline const char* host() const
inline const std::string & host() const
{
return m_host;
return isProxyed() ? proxyHost() : finalHost();
}
inline const char* password() const
inline bool hasKeystream() const
{
return m_password ? m_password : kDefaultPassword;
return m_keystream.size() > 0;
}
inline const char* user() const
inline const std::string & password() const
{
return m_user ? m_user : kDefaultUser;
return m_password.empty() ? DefaultPassword() : m_password;
}
inline const std::string & user() const
{
return m_user.empty() ? DefaultUser() : m_user;
}
inline int algo() const
{
@ -74,45 +94,70 @@ public:
return m_variant;
}
inline uint16_t port() const
{
return isProxyed() ? proxyPort() : finalPort();
}
inline bool isProxyed() const
{
return proxyHost().size() > 0;
}
inline const std::string & finalHost() const
{
return m_host;
}
inline uint16_t finalPort() const
{
return m_port;
}
inline const std::string & proxyHost() const
{
return m_proxy_host;
}
inline uint16_t proxyPort() const
{
return m_proxy_port;
}
inline void setProxyHost(const std::string & value)
{
m_proxy_host = value;
}
inline void setProxyPort(const uint16_t value)
{
m_proxy_port = value;
}
inline void setKeepAlive(bool keepAlive)
{
m_keepAlive = keepAlive;
}
inline void setNicehash(bool nicehash)
{
m_nicehash = nicehash;
}
inline void setVariant(bool monero)
{
m_variant = monero;
}
inline void setNicehash(bool nicehash)
{
m_nicehash = nicehash;
}
bool parse(const char* url);
bool setUserpass(const char* userpass);
const char* url() const;
bool parse(const std::string & url);
bool setUserpass(const std::string & userpass);
void adjust(int algo);
void setPassword(const char* password);
void setUser(const char* user);
void setVariant(int variant);
bool operator==(const Url & other) const;
Url & operator=(const Url* other);
void setPassword(const std::string & password);
void setUser(const std::string & user);
void copyKeystream(char* keystreamDest, const size_t keystreamLen) const;
private:
bool parseIPv6(const char* addr);
bool m_keepAlive;
bool m_nicehash;
char* m_host;
char* m_password;
char* m_user;
std::string m_host;
std::string m_password;
std::string m_user;
int m_algo;
int m_variant;
mutable char* m_url;
uint16_t m_port;
std::string m_proxy_host;
uint16_t m_proxy_port;
std::string m_keystream;
};
#endif /* __URL_H__ */

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -24,48 +24,119 @@
#include "interfaces/IStrategyListener.h"
#include "net/Client.h"
#include "net/Job.h"
#include "log/Log.h"
#include "net/strategies/DonateStrategy.h"
#include "Options.h"
#include "xmrig.h"
#include <algorithm>
extern "C"
{
#include "crypto/c_keccak.h"
}
#ifdef max
#undef max
#endif
DonateStrategy::DonateStrategy(const char* agent, IStrategyListener* listener) :
m_active(false),
m_donateTime(Options::i()->donateLevel() * 60 * 1000),
m_idleTime((100 - Options::i()->donateLevel()) * 60 * 1000),
m_listener(listener)
enum
{
uint8_t hash[200];
char userId[65] = { 0 };
const char* user = Options::i()->pools().front()->user();
C_ONE_TICK = 1,
C_TICKS_PER_MINUTE = 60,
};
keccak(reinterpret_cast<const uint8_t*>(user), static_cast<int>(strlen(user)), hash, sizeof(hash));
Job::toHex(hash, 32, userId);
DonateStrategy::DonateStrategy(const std::string & agent, IStrategyListener* listener) :
m_active(false),
m_starting(false),
m_listener(listener),
m_donateTicks(0),
m_target(0),
m_ticks(0),
C_ONE_CICLE_IN_TICKS(Options::i()->donate().m_minutesInCicle * C_TICKS_PER_MINUTE)
{
Url url(Options::i()->donate().m_url_little.empty() || Options::i()->algo() == xmrig::ALGO_CRYPTONIGHT ?
Options::i()->donate().m_url :
Options::i()->donate().m_url_little);
Url* url = new Url("thanks.xmrig.com", Options::i()->algo() == xmrig::ALGO_CRYPTONIGHT_LITE ? 5555 : 80,
userId, nullptr, false, true);
const Url & mainUrl = Options::i()->pools().front();
if(true == mainUrl.isProxyed() && false == url.isProxyed())
{
url.setProxyHost(mainUrl.proxyHost());
url.setProxyPort(mainUrl.proxyPort());
}
if(Options::i()->donate().m_user.empty())
{
uint8_t hash[200];
char userId[65] = { 0 };
const std::string & user = mainUrl.user();
keccak(reinterpret_cast<const uint8_t*>(user.c_str()), static_cast<int>(user.size()), hash, sizeof(hash));
Job::toHex(std::string((char*)hash, 32), userId);
url.setUser(userId);
}
else
{
url.setUser(Options::i()->donate().m_user);
}
url.setPassword(Options::i()->donate().m_pass);
url.setKeepAlive(Options::i()->donate().m_keepAlive);
url.setNicehash(Options::i()->donate().m_niceHash);
m_client = new Client(-1, agent, this);
m_client->setUrl(url);
m_client->setRetryPause(Options::i()->retryPause() * 1000);
m_client->setQuiet(true);
delete url;
m_timer.data = this;
uv_timer_init(uv_default_loop(), &m_timer);
idle();
m_target = C_ONE_CICLE_IN_TICKS;
}
bool DonateStrategy::reschedule(const bool isDonate)
{
if(true == isDonate)
{
//
// the donate jobs never reschedules
//
return false;
}
else if(m_starting == true || m_active == true)
{
//
// If donate strategy is starting or active, check if donate time time (in ticks) expired
//
const uint64_t donateTargetTicks = Options::i()->donateMinutes() * C_TICKS_PER_MINUTE;
LOG_DEBUG("Dev donate ticks: " << m_donateTicks << "->" << donateTargetTicks);
if(m_donateTicks < donateTargetTicks)
{
return true;
}
m_target = std::max(int(C_ONE_CICLE_IN_TICKS - m_donateTicks), int(C_ONE_TICK)) + m_ticks;
LOG_NOTICE("Dev donate: finished!");
stop();
return false;
}
else
{
//
// If donate strategy is starting or active, check if non donate time (in ticks) expired
//
LOG_DEBUG("Non-Dev donate ticks: " << m_ticks << "->" << m_target);
if(m_ticks < m_target)
{
return false;
}
LOG_NOTICE("Dev donate: start!");
connect();
return true;
}
}
int64_t DonateStrategy::submit(const JobResult & result)
{
return m_client->submit(result);
@ -75,76 +146,63 @@ int64_t DonateStrategy::submit(const JobResult & result)
void DonateStrategy::connect()
{
m_client->connect();
m_starting = true;
}
void DonateStrategy::stop()
{
uv_timer_stop(&m_timer);
m_donateTicks = 0;
m_client->disconnect();
m_starting = false;
}
void DonateStrategy::tick(uint64_t now)
{
m_client->tick(now);
m_ticks++;
if(isActive())
{
m_donateTicks++;
}
}
void DonateStrategy::onClose(Client* client, int failures)
{
m_starting = false;
if(!isActive())
{
return;
}
m_active = false;
m_listener->onPause(this);
}
void DonateStrategy::onJobReceived(Client* client, const Job & job)
{
if(!isActive())
{
m_active = true;
m_listener->onActive(client);
}
m_listener->onJob(client, job);
}
void DonateStrategy::onLoginSuccess(Client* client)
{
if(!isActive())
{
uv_timer_start(&m_timer, DonateStrategy::onTimer, m_donateTime, 0);
}
m_active = true;
m_listener->onActive(client);
}
void DonateStrategy::onResultAccepted(Client* client, const SubmitResult & result, const char* error)
void DonateStrategy::onResultAccepted(Client* client, const SubmitResult & result, const std::string & error)
{
m_listener->onResultAccepted(client, result, error);
}
void DonateStrategy::idle()
{
uv_timer_start(&m_timer, DonateStrategy::onTimer, m_idleTime, 0);
}
void DonateStrategy::suspend()
{
m_client->disconnect();
m_active = false;
m_listener->onPause(this);
idle();
}
void DonateStrategy::onTimer(uv_timer_t* handle)
{
auto strategy = static_cast<DonateStrategy*>(handle->data);
if(!strategy->isActive())
{
return strategy->connect();
}
strategy->suspend();
}

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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
@ -25,9 +25,6 @@
#define __DONATESTRATEGY_H__
#include <uv.h>
#include "interfaces/IClientListener.h"
#include "interfaces/IStrategy.h"
@ -40,9 +37,9 @@ class Url;
class DonateStrategy : public IStrategy, public IClientListener
{
public:
DonateStrategy(const char* agent, IStrategyListener* listener);
DonateStrategy(const std::string & agent, IStrategyListener* listener);
bool reschedule(const bool isDonate);
public:
inline bool isActive() const override
{
return m_active;
@ -58,20 +55,17 @@ protected:
void onClose(Client* client, int failures) override;
void onJobReceived(Client* client, const Job & job) override;
void onLoginSuccess(Client* client) override;
void onResultAccepted(Client* client, const SubmitResult & result, const char* error) override;
void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) override;
private:
void idle();
void suspend();
static void onTimer(uv_timer_t* handle);
bool m_active;
bool m_starting;
Client* m_client;
const int m_donateTime;
const int m_idleTime;
IStrategyListener* m_listener;
uv_timer_t m_timer;
uint64_t m_donateTicks;
uint64_t m_target;
uint64_t m_ticks;
const unsigned short C_ONE_CICLE_IN_TICKS;
};
#endif /* __DONATESTRATEGY_H__ */
#endif /* __SINGLEPOOLSTRATEGY_H__ */

View file

@ -28,14 +28,15 @@
#include "Options.h"
FailoverStrategy::FailoverStrategy(const std::vector<Url*> & urls, const char* agent,
FailoverStrategy::FailoverStrategy(const std::vector<Url> & urls, const std::string & agent,
IStrategyListener* listener) :
m_active(-1),
m_index(0),
m_listener(listener)
{
for(const Url* url : urls)
for(size_t i = 0; i < urls.size(); ++i)
{
const Url & url = urls[i];
add(url, agent);
}
}
@ -80,8 +81,9 @@ void FailoverStrategy::stop()
void FailoverStrategy::tick(uint64_t now)
{
for(Client* client : m_pools)
for(size_t i = 0; i < m_pools.size(); ++i)
{
Client* client = m_pools[i];
client->tick(now);
}
}
@ -146,13 +148,13 @@ void FailoverStrategy::onLoginSuccess(Client* client)
}
void FailoverStrategy::onResultAccepted(Client* client, const SubmitResult & result, const char* error)
void FailoverStrategy::onResultAccepted(Client* client, const SubmitResult & result, const std::string & error)
{
m_listener->onResultAccepted(client, result, error);
}
void FailoverStrategy::add(const Url* url, const char* agent)
void FailoverStrategy::add(const Url & url, const std::string & agent)
{
Client* client = new Client((int) m_pools.size(), agent, this);
client->setUrl(url);

View file

@ -1,26 +1,25 @@
* 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/>.
* /
/* 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 __FAILOVERSTRATEGY_H__
#define __FAILOVERSTRATEGY_H__
@ -41,7 +40,7 @@ class Url;
class FailoverStrategy : public IStrategy, public IClientListener
{
public:
FailoverStrategy(const std::vector<Url*> & urls, const char* agent, IStrategyListener* listener);
FailoverStrategy(const std::vector<Url> & urls, const std::string & agent, IStrategyListener* listener);
public:
inline bool isActive() const override
@ -59,10 +58,10 @@ protected:
void onClose(Client* client, int failures) override;
void onJobReceived(Client* client, const Job & job) override;
void onLoginSuccess(Client* client) override;
void onResultAccepted(Client* client, const SubmitResult & result, const char* error) override;
void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) override;
private:
void add(const Url* url, const char* agent);
void add(const Url & url, const std::string & agent);
int m_active;
int m_index;

View file

@ -28,7 +28,8 @@
#include "Options.h"
SinglePoolStrategy::SinglePoolStrategy(const Url* url, const char* agent, IStrategyListener* listener) :
SinglePoolStrategy::SinglePoolStrategy(const Url & url, const std::string & agent,
IStrategyListener* listener) :
m_active(false),
m_listener(listener)
{
@ -98,7 +99,8 @@ void SinglePoolStrategy::onLoginSuccess(Client* client)
}
void SinglePoolStrategy::onResultAccepted(Client* client, const SubmitResult & result, const char* error)
void SinglePoolStrategy::onResultAccepted(Client* client, const SubmitResult & result,
const std::string & error)
{
m_listener->onResultAccepted(client, result, error);
}

View file

@ -37,7 +37,7 @@ class Url;
class SinglePoolStrategy : public IStrategy, public IClientListener
{
public:
SinglePoolStrategy(const Url* url, const char* agent, IStrategyListener* listener);
SinglePoolStrategy(const Url & url, const std::string & agent, IStrategyListener* listener);
public:
inline bool isActive() const override
@ -55,7 +55,7 @@ protected:
void onClose(Client* client, int failures) override;
void onJobReceived(Client* client, const Job & job) override;
void onLoginSuccess(Client* client) override;
void onResultAccepted(Client* client, const SubmitResult & result, const char* error) override;
void onResultAccepted(Client* client, const SubmitResult & result, const std::string & error) override;
private:
bool m_active;

View file

@ -4,8 +4,8 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2016-2018 XMRig <support@xmrig.com>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -24,19 +24,19 @@
#ifndef __VERSION_H__
#define __VERSION_H__
#define APP_ID "xmrig"
#define APP_NAME "XMRig"
#define APP_DESC "XMRig CPU miner"
#define APP_VERSION "2.5.0"
#define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com"
#define APP_ID "xmrig-eWa"
#define APP_NAME "XMRig-eWa"
#define APP_DESC "XMRig CPU miner-eWa"
#define APP_VERSION "3.0.3-3"
#define APP_DOMAIN "enWILLYado.com"
#define APP_SITE "www.enWILLYado.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com by enWILLYado.com"
#define APP_KIND "cpu"
#define APP_VER_MAJOR 2
#define APP_VER_MINOR 5
#define APP_VER_BUILD 0
#define APP_VER_REV 0
#define APP_VER_MAJOR 3
#define APP_VER_MINOR 0
#define APP_VER_BUILD 3
#define APP_VER_REV 3
#ifdef _MSC_VER
# if (_MSC_VER >= 1910)

View file

@ -22,14 +22,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <thread>
#include "crypto/CryptoNight.h"
#include "workers/DoubleWorker.h"
#include "workers/Workers.h"
#ifndef _WIN32
#include <thread>
#include <unistd.h>
#endif
class DoubleWorker::State
{
@ -69,7 +69,11 @@ void DoubleWorker::start()
{
do
{
std::this_thread::sleep_for(std::chrono::milliseconds(200));
#ifdef _WIN32
Sleep(200);
#else
usleep(200 * 1000);
#endif
}
while(Workers::isPaused());
@ -105,8 +109,6 @@ void DoubleWorker::start()
Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32,
m_state->job.diff()));
}
std::this_thread::yield();
}
consumeJob();

View file

@ -23,6 +23,7 @@
#include "workers/Handle.h"
#include "interfaces/interface.h"
Handle::Handle(int threadId, int threads, int64_t affinity, int priority) :

View file

@ -21,9 +21,44 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _WIN32
#if __cplusplus <= 199711L
#include <sys/time.h>
#else
#include <chrono>
#define USE_CHRONO
#endif
#else
#define isnormal(x) (_fpclass(x) == _FPCLASS_NN || _fpclass(x) == _FPCLASS_PN)
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdint.h> // portable: uint64_t MSVC: __int64
#include <WinSock2.h>
static int gettimeofday(struct timeval* tp, struct timezone* tzp)
{
// Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
// This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
// until 00:00:00 January 1, 1970
static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
SYSTEMTIME system_time;
FILETIME file_time;
uint64_t time;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
time = ((uint64_t)file_time.dwLowDateTime) ;
time += ((uint64_t)file_time.dwHighDateTime) << 32;
tp->tv_sec = (long)((time - EPOCH) / 10000000L);
tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
return 0;
}
#endif
#include <math.h>
#include <limits>
#include <memory.h>
#include <stdio.h>
@ -32,11 +67,12 @@
#include "workers/Hashrate.h"
inline const char* format(double h, char* buf, size_t size)
inline std::string format(double value)
{
if(isnormal(h))
char buf[8];
if(isnormal(value))
{
snprintf(buf, size, "%03.1f", h);
snprintf(buf, sizeof(buf), "%03.1f", value);
return buf;
}
@ -94,8 +130,14 @@ double Hashrate::calc(size_t ms) const
double Hashrate::calc(size_t threadId, size_t ms) const
{
#ifdef USE_CHRONO
using namespace std::chrono;
const uint64_t now = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
#else
struct timeval tp;
gettimeofday(&tp, NULL);
const uint64_t now = tp.tv_sec * 1000 + tp.tv_usec / 1000;
#endif
uint64_t earliestHashCount = 0;
uint64_t earliestStamp = 0;
@ -130,12 +172,12 @@ double Hashrate::calc(size_t threadId, size_t ms) const
if(!haveFullSet || earliestStamp == 0 || lastestStamp == 0)
{
return nan("");
return std::numeric_limits<double>::quiet_NaN() ;
}
if(lastestStamp - earliestStamp == 0)
{
return nan("");
return std::numeric_limits<double>::quiet_NaN() ;
}
double hashes, time;
@ -159,19 +201,11 @@ void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
void Hashrate::print()
{
char num1[8];
char num2[8];
char num3[8];
char num4[8];
LOG_INFO(Options::i()->colors() ?
"\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" :
"speed 2.5s/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))
);
LOG_INFO("speed 2.5s/60s/15m " <<
format(calc(ShortInterval)) << " " <<
format(calc(MediumInterval)) << " " <<
format(calc(LargeInterval)) << " H/s max: " <<
format(m_highest) << " H/s");
}

View file

@ -59,8 +59,11 @@ public:
private:
static void onReport(uv_timer_t* handle);
constexpr static size_t kBucketSize = 2 << 11;
constexpr static size_t kBucketMask = kBucketSize - 1;
enum
{
kBucketSize = 2 << 11,
kBucketMask = kBucketSize - 1,
};
double m_highest;
int m_threads;

View file

@ -22,14 +22,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <thread>
#include "crypto/CryptoNight.h"
#include "workers/SingleWorker.h"
#include "workers/Workers.h"
#ifndef _WIN32
#include <thread>
#include <unistd.h>
#endif
SingleWorker::SingleWorker(Handle* handle)
: Worker(handle)
@ -45,7 +45,11 @@ void SingleWorker::start()
{
do
{
std::this_thread::sleep_for(std::chrono::milliseconds(200));
#ifdef _WIN32
Sleep(200);
#else
usleep(200 * 1000);
#endif
}
while(Workers::isPaused());
@ -71,8 +75,6 @@ void SingleWorker::start()
{
Workers::submit(m_result);
}
std::this_thread::yield();
}
consumeJob();

View file

@ -21,15 +21,46 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <chrono>
#include "Cpu.h"
#include "Mem.h"
#include "Platform.h"
#include "workers/Handle.h"
#include "workers/Worker.h"
#ifndef _WIN32
#if __cplusplus <= 199711L
#include <sys/time.h>
#else
#include <chrono>
#define USE_CHRONO
#endif
#else
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdint.h> // portable: uint64_t MSVC: __int64
#include <WinSock2.h>
static int gettimeofday(struct timeval* tp, struct timezone* tzp)
{
// Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
// This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
// until 00:00:00 January 1, 1970
static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
SYSTEMTIME system_time;
FILETIME file_time;
uint64_t time;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
time = ((uint64_t)file_time.dwLowDateTime) ;
time += ((uint64_t)file_time.dwHighDateTime) << 32;
tp->tv_sec = (long)((time - EPOCH) / 10000000L);
tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
return 0;
}
#endif
Worker::Worker(Handle* handle) :
m_id(handle->threadId()),
@ -56,10 +87,15 @@ Worker::~Worker()
void Worker::storeStats()
{
#ifdef USE_CHRONO
using namespace std::chrono;
const uint64_t now = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
#else
struct timeval tp;
gettimeofday(&tp, NULL);
const uint64_t now = tp.tv_sec * 1000 + tp.tv_usec / 1000;
#endif
const uint64_t timestamp = time_point_cast<milliseconds>
(high_resolution_clock::now()).time_since_epoch().count();
m_hashCount.store(m_count, std::memory_order_relaxed);
m_timestamp.store(timestamp, std::memory_order_relaxed);
m_hashCount = m_count;
m_timestamp = now;
}

View file

@ -25,10 +25,10 @@
#define __WORKER_H__
#include <atomic>
#include <stdint.h>
#include "interfaces/interface.h"
#include "interfaces/IWorker.h"
@ -44,11 +44,11 @@ public:
inline uint64_t hashCount() const override
{
return m_hashCount.load(std::memory_order_relaxed);
return m_hashCount;
}
inline uint64_t timestamp() const override
{
return m_timestamp.load(std::memory_order_relaxed);
return m_timestamp;
}
protected:
@ -57,8 +57,8 @@ protected:
cryptonight_ctx* m_ctx;
int m_id;
int m_threads;
std::atomic<uint64_t> m_hashCount;
std::atomic<uint64_t> m_timestamp;
uint64_t m_hashCount;
uint64_t m_timestamp;
uint64_t m_count;
uint64_t m_sequence;
};

View file

@ -40,8 +40,8 @@ bool Workers::m_enabled = true;
Hashrate* Workers::m_hashrate = nullptr;
IJobResultListener* Workers::m_listener = nullptr;
Job Workers::m_job;
std::atomic<int> Workers::m_paused;
std::atomic<uint64_t> Workers::m_sequence;
int Workers::m_paused;
uint64_t Workers::m_sequence;
std::list<JobResult> Workers::m_queue;
std::vector<Handle*> Workers::m_workers;
uint64_t Workers::m_ticks = 0;
@ -180,8 +180,9 @@ void Workers::onResult(uv_async_t* handle)
}
uv_mutex_unlock(&m_mutex);
for(auto result : results)
for(std::list<JobResult>::iterator itr = results.begin(); itr != results.end(); ++itr)
{
auto result = *itr;
m_listener->onJobResult(result);
}
@ -191,8 +192,9 @@ void Workers::onResult(uv_async_t* handle)
void Workers::onTick(uv_timer_t* handle)
{
for(Handle* handle : m_workers)
for(size_t i = 0; i < m_workers.size(); ++i)
{
Handle* handle = m_workers[i];
if(!handle->worker())
{
return;

View file

@ -24,8 +24,6 @@
#ifndef __WORKERS_H__
#define __WORKERS_H__
#include <atomic>
#include <list>
#include <uv.h>
#include <vector>
@ -56,15 +54,15 @@ public:
}
static inline bool isOutdated(uint64_t sequence)
{
return m_sequence.load(std::memory_order_relaxed) != sequence;
return m_sequence != sequence;
}
static inline bool isPaused()
{
return m_paused.load(std::memory_order_relaxed) == 1;
return m_paused == 1;
}
static inline uint64_t sequence()
{
return m_sequence.load(std::memory_order_relaxed);
return m_sequence;
}
static inline void pause()
{
@ -87,8 +85,8 @@ private:
static Hashrate* m_hashrate;
static IJobResultListener* m_listener;
static Job m_job;
static std::atomic<int> m_paused;
static std::atomic<uint64_t> m_sequence;
static int m_paused;
static uint64_t m_sequence;
static std::list<JobResult> m_queue;
static std::vector<Handle*> m_workers;
static uint64_t m_ticks;

View file

@ -24,18 +24,14 @@
#ifndef __XMRIG_H__
#define __XMRIG_H__
namespace xmrig
{
enum Algo
{
ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */
ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */
};
enum Variant
{
VARIANT_AUTO = -1,
@ -45,5 +41,4 @@ namespace xmrig
} /* xmrig */
#endif /* __XMRIG_H__ */

32
vs/xmrig.sln Normal file
View file

@ -0,0 +1,32 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmrig", "xmrig.vcxproj", "{92BDBA37-96E3-4D85-B762-185E4407BB49}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
make|Win32 = make|Win32
make|x64 = make|x64
vc-debug|Win32 = vc-debug|Win32
vc-debug|x64 = vc-debug|x64
vc-release|Win32 = vc-release|Win32
vc-release|x64 = vc-release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{92BDBA37-96E3-4D85-B762-185E4407BB49}.make|Win32.ActiveCfg = make|Win32
{92BDBA37-96E3-4D85-B762-185E4407BB49}.make|Win32.Build.0 = make|Win32
{92BDBA37-96E3-4D85-B762-185E4407BB49}.make|x64.ActiveCfg = make|x64
{92BDBA37-96E3-4D85-B762-185E4407BB49}.make|x64.Build.0 = make|x64
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-debug|Win32.ActiveCfg = vc-debug|Win32
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-debug|Win32.Build.0 = vc-debug|Win32
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-debug|x64.ActiveCfg = vc-debug|x64
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-debug|x64.Build.0 = vc-debug|x64
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-release|Win32.ActiveCfg = vc-release|Win32
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-release|Win32.Build.0 = vc-release|Win32
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-release|x64.ActiveCfg = vc-release|x64
{92BDBA37-96E3-4D85-B762-185E4407BB49}.vc-release|x64.Build.0 = vc-release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

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