-
Notifications
You must be signed in to change notification settings - Fork 98
/
minethd.h
126 lines (100 loc) · 3.14 KB
/
minethd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#pragma once
#include <thread>
#include <atomic>
#include "nvcc_code/cryptonight.h"
#include "jconf.h"
class telemetry
{
public:
telemetry(size_t iThd);
void push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp);
double calc_telemetry_data(size_t iLastMilisec, size_t iThread);
private:
constexpr static size_t iBucketSize = 2 << 11; //Power of 2 to simplify calculations
constexpr static size_t iBucketMask = iBucketSize - 1;
uint32_t* iBucketTop;
uint64_t** ppHashCounts;
uint64_t** ppTimestamps;
};
class minethd
{
public:
struct miner_work
{
char sJobID[64];
uint8_t bWorkBlob[112];
uint32_t iWorkSize;
uint32_t iResumeCnt;
uint64_t iTarget;
bool bStall;
size_t iPoolId;
miner_work() : iWorkSize(0), bStall(true), iPoolId(0) { }
miner_work(const char* sJobID, const uint8_t* bWork, uint32_t iWorkSize,
uint32_t iResumeCnt, uint64_t iTarget, size_t iPoolId) : iWorkSize(iWorkSize),
iResumeCnt(iResumeCnt), iTarget(iTarget), bStall(false), iPoolId(iPoolId)
{
assert(iWorkSize <= sizeof(bWorkBlob));
memcpy(this->sJobID, sJobID, sizeof(miner_work::sJobID));
memcpy(this->bWorkBlob, bWork, iWorkSize);
}
miner_work(miner_work const&) = delete;
miner_work& operator=(miner_work const& from)
{
assert(this != &from);
iWorkSize = from.iWorkSize;
iResumeCnt = from.iResumeCnt;
iTarget = from.iTarget;
bStall = from.bStall;
iPoolId = from.iPoolId;
assert(iWorkSize <= sizeof(bWorkBlob));
memcpy(sJobID, from.sJobID, sizeof(sJobID));
memcpy(bWorkBlob, from.bWorkBlob, iWorkSize);
return *this;
}
miner_work(miner_work&& from) : iWorkSize(from.iWorkSize), iTarget(from.iTarget),
bStall(from.bStall), iPoolId(from.iPoolId)
{
assert(iWorkSize <= sizeof(bWorkBlob));
memcpy(sJobID, from.sJobID, sizeof(sJobID));
memcpy(bWorkBlob, from.bWorkBlob, iWorkSize);
}
miner_work& operator=(miner_work&& from)
{
assert(this != &from);
iWorkSize = from.iWorkSize;
iResumeCnt = from.iResumeCnt;
iTarget = from.iTarget;
bStall = from.bStall;
iPoolId = from.iPoolId;
assert(iWorkSize <= sizeof(bWorkBlob));
memcpy(sJobID, from.sJobID, sizeof(sJobID));
memcpy(bWorkBlob, from.bWorkBlob, iWorkSize);
return *this;
}
};
static void switch_work(miner_work& pWork);
static std::vector<minethd*>* thread_starter(miner_work& pWork);
static bool self_test();
std::atomic<uint64_t> iHashCount;
std::atomic<uint64_t> iTimestamp;
private:
minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg);
// We use the top 8 bits of the nonce for thread and resume
// This allows us to resume up to 64 threads 4 times before
// we get nonce collisions
// Bottom 24 bits allow for an hour of work at 4000 H/s
inline uint32_t calc_start_nonce(uint32_t resume)
{ return (resume * iThreadCount + iThreadNo) << 24; }
void work_main();
void consume_work();
static std::atomic<uint64_t> iGlobalJobNo;
static std::atomic<uint64_t> iConsumeCnt;
static uint64_t iThreadCount;
uint64_t iJobNo;
static miner_work oGlobalWork;
miner_work oWork;
std::thread oWorkThd;
uint8_t iThreadNo;
nvid_ctx ctx;
bool bQuit;
};