diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 6fe1a838..a1d6e8ab 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -67,3 +67,15 @@ const char *Api::get(const char *url, size_t *size, int *status) return m_buf; } + + +void Api::tick(const Hashrate *hashrate) +{ + if (!m_state) { + return; + } + + uv_mutex_lock(&m_mutex); + m_state->tick(hashrate); + uv_mutex_unlock(&m_mutex); +} diff --git a/src/api/Api.h b/src/api/Api.h index db053139..ba36a992 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -29,6 +29,7 @@ class ApiState; +class Hashrate; class Api @@ -38,6 +39,7 @@ public: static void release(); static const char *get(const char *url, size_t *size, int *status); + static void tick(const Hashrate *hashrate); private: static ApiState *m_state; diff --git a/src/api/ApiState.cpp b/src/api/ApiState.cpp index 32681842..8c745d9b 100644 --- a/src/api/ApiState.cpp +++ b/src/api/ApiState.cpp @@ -21,6 +21,7 @@ * along with this program. If not, see . */ +#include #include #include @@ -38,6 +39,7 @@ #include "Options.h" #include "Platform.h" #include "version.h" +#include "workers/Hashrate.h" extern "C" @@ -46,9 +48,24 @@ extern "C" } +static inline double normalizeHs(double hashrate) +{ + if (!std::isnormal(hashrate)) { + return 0.0; + } + + return std::floor(hashrate * 10.0) / 10.0; +} + + ApiState::ApiState() { + m_threads = Options::i()->threads(); + m_hashrate = new double[m_threads * 3](); + + memset(m_totalHashrate, 0, sizeof(m_totalHashrate)); memset(m_workerId, 0, sizeof(m_workerId)); + if (Options::i()->apiWorkerId()) { strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1); } @@ -62,6 +79,7 @@ ApiState::ApiState() ApiState::~ApiState() { + delete [] m_hashrate; } @@ -71,14 +89,30 @@ const char *ApiState::get(const char *url, size_t *size) const getIdentify(reply); getMiner(reply); + getHashrate(reply); return finalize(reply, size); } +void ApiState::tick(const Hashrate *hashrate) +{ + for (int i = 0; i < m_threads; ++i) { + m_hashrate[i * 3] = normalizeHs(hashrate->calc((size_t) i, Hashrate::ShortInterval)); + m_hashrate[i * 3 + 1] = normalizeHs(hashrate->calc((size_t) i, Hashrate::MediumInterval)); + m_hashrate[i * 3 + 2] = normalizeHs(hashrate->calc((size_t) i, Hashrate::LargeInterval)); + } + + m_totalHashrate[0] = normalizeHs(hashrate->calc(Hashrate::ShortInterval)); + m_totalHashrate[1] = normalizeHs(hashrate->calc(Hashrate::MediumInterval)); + m_totalHashrate[2] = normalizeHs(hashrate->calc(Hashrate::LargeInterval)); + m_highestHashrate = normalizeHs(hashrate->highest()); +} + + const char *ApiState::finalize(json_t *reply, size_t *size) const { - *size = json_dumpb(reply, m_buf, sizeof(m_buf) - 1, JSON_INDENT(4)); + *size = json_dumpb(reply, m_buf, sizeof(m_buf) - 1, JSON_INDENT(4) | JSON_REAL_PRECISION(15)); json_decref(reply); return m_buf; @@ -110,6 +144,32 @@ void ApiState::genId() } +void ApiState::getHashrate(json_t *reply) const +{ + json_t *hashrate = json_object(); + json_t *threads = json_array(); + json_t *total = json_array(); + + json_object_set(reply, "hashrate", hashrate); + json_object_set(hashrate, "total", total); + json_object_set(hashrate, "highest", json_real(m_highestHashrate)); + json_object_set(hashrate, "threads", threads); + + for (int i = 0; i < m_threads * 3; i += 3) { + json_t *thread = json_array(); + json_array_append(thread, json_real(m_hashrate[i])); + json_array_append(thread, json_real(m_hashrate[i + 1])); + json_array_append(thread, json_real(m_hashrate[i + 2])); + + json_array_append(threads, thread); + } + + for (int i = 0; i < 3; ++i) { + json_array_append(total, json_real(m_totalHashrate[i])); + } +} + + void ApiState::getIdentify(json_t *reply) const { json_object_set(reply, "id", json_string(m_id)); diff --git a/src/api/ApiState.h b/src/api/ApiState.h index 3876aa6c..3405d49d 100644 --- a/src/api/ApiState.h +++ b/src/api/ApiState.h @@ -28,6 +28,9 @@ #include "jansson.h" +class Hashrate; + + class ApiState { public: @@ -35,16 +38,21 @@ public: ~ApiState(); const char *get(const char *url, size_t *size) const; + void tick(const Hashrate *hashrate); private: const char *finalize(json_t *reply, size_t *size) const; void genId(); + void getHashrate(json_t *reply) const; void getIdentify(json_t *reply) const; void getMiner(json_t *reply) const; - char m_id[17]; char m_workerId[128]; + double *m_hashrate; + double m_highestHashrate; + double m_totalHashrate[3]; + int m_threads; mutable char m_buf[4096]; }; diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 5bc65698..5c20c247 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -153,10 +153,10 @@ void Hashrate::print() 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(2500), num1, sizeof(num1)), - format(calc(60000), num2, sizeof(num2)), - format(calc(900000), num3, sizeof(num3)), - format(m_highest, num4, sizeof(num4)) + format(calc(ShortInterval), num1, sizeof(num1)), + format(calc(MediumInterval), num2, sizeof(num2)), + format(calc(LargeInterval), num3, sizeof(num3)), + format(m_highest, num4, sizeof(num4)) ); } @@ -169,7 +169,7 @@ void Hashrate::stop() void Hashrate::updateHighest() { - double highest = calc(2500); + double highest = calc(ShortInterval); if (std::isnormal(highest) && highest > m_highest) { m_highest = highest; } diff --git a/src/workers/Hashrate.h b/src/workers/Hashrate.h index ca894dcb..026c0cdf 100644 --- a/src/workers/Hashrate.h +++ b/src/workers/Hashrate.h @@ -32,6 +32,12 @@ class Hashrate { public: + enum Intervals { + ShortInterval = 2500, + MediumInterval = 60000, + LargeInterval = 900000 + }; + Hashrate(int threads); double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; @@ -41,6 +47,7 @@ public: void updateHighest(); inline double highest() const { return m_highest; } + inline int threads() const { return m_threads; } private: static void onReport(uv_timer_t *handle); diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index e51f5d22..4ba28693 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -24,6 +24,7 @@ #include +#include "api/Api.h" #include "interfaces/IJobResultListener.h" #include "Mem.h" #include "Options.h" @@ -192,4 +193,6 @@ void Workers::onTick(uv_timer_t *handle) if ((m_ticks++ & 0xF) == 0) { m_hashrate->updateHighest(); } + + Api::tick(m_hashrate); }