Skip to content
This repository has been archived by the owner on May 27, 2020. It is now read-only.

API refactoring and updating #172

Closed
wants to merge 8 commits into from
276 changes: 116 additions & 160 deletions api.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ static const char *SICK = "Sick";
static const char *NOSTART = "NoStart";
static const char *DISABLED = "Disabled";
static const char *ALIVE = "Alive";
static const char *UNKNOWN = "Unknown";
#define _DYNAMIC "D"
static const char *DYNAMIC = _DYNAMIC;

Expand Down Expand Up @@ -770,156 +771,126 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
strcat(io_buffer, buf);
}

static void gpustatus(int gpu, bool isjson)
static const char*
bool2str(bool b)
{
char intensity[20];
char buf[BUFSIZ];
char *enabled;
char *status;
float gt, gv;
int ga, gf, gp, gc, gm, pt;

if (gpu >= 0 && gpu < nDevs) {
struct cgpu_info *cgpu = &gpus[gpu];

cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;

#ifdef HAVE_ADL
if (!gpu_stats(gpu, &gt, &gc, &gm, &gv, &ga, &gf, &gp, &pt))
#endif
gt = gv = gm = gc = ga = gf = gp = pt = 0;

if (cgpu->deven != DEV_DISABLED)
enabled = (char *)YES;
else
enabled = (char *)NO;

if (cgpu->status == LIFE_DEAD)
status = (char *)DEAD;
else if (cgpu->status == LIFE_SICK)
status = (char *)SICK;
else if (cgpu->status == LIFE_NOSTART)
status = (char *)NOSTART;
else
status = (char *)ALIVE;

if (cgpu->dynamic)
strcpy(intensity, DYNAMIC);
else
sprintf(intensity, "%d", cgpu->intensity);

if (isjson)
sprintf(buf, "{\"GPU\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"Fan Speed\":%d,\"Fan Percent\":%d,\"GPU Clock\":%d,\"Memory Clock\":%d,\"GPU Voltage\":%.3f,\"GPU Activity\":%d,\"Powertune\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Intensity\":\"%s\",\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}",
gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->utility, intensity,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes);
else
sprintf(buf, "GPU=%d,Enabled=%s,Status=%s,Temperature=%.2f,Fan Speed=%d,Fan Percent=%d,GPU Clock=%d,Memory Clock=%d,GPU Voltage=%.3f,GPU Activity=%d,Powertune=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Intensity=%s,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c",
gpu, enabled, status, gt, gf, gp, gc, gm, gv, ga, pt,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->utility, intensity,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR);
return b ? YES : NO;
}

strcat(io_buffer, buf);
static const char*
status2str(enum alive status)
{
switch (status) {
case LIFE_WELL:
return ALIVE;
case LIFE_SICK:
return SICK;
case LIFE_DEAD:
return DEAD;
case LIFE_NOSTART:
return NOSTART;
default:
return UNKNOWN;
}
}

#if defined(USE_BITFORCE) || defined(USE_ICARUS)
static void pgastatus(int pga, bool isjson)
static void
append_kv(char *buf, json_t*info, bool isjson)
{
char buf[BUFSIZ];
char *enabled;
char *status;
int numpga = numpgas();

if (numpga > 0 && pga >= 0 && pga < numpga) {
int dev = pgadevice(pga);
if (dev < 0) // Should never happen
return;

struct cgpu_info *cgpu = devices[dev];
json_t *value;
const char *key, *tmpl = isjson ? ",\"%s\":%s" : ",%s=%s";
char *vdump;

cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;

if (cgpu->deven != DEV_DISABLED)
enabled = (char *)YES;
else
enabled = (char *)NO;

if (cgpu->status == LIFE_DEAD)
status = (char *)DEAD;
else if (cgpu->status == LIFE_SICK)
status = (char *)SICK;
else if (cgpu->status == LIFE_NOSTART)
status = (char *)NOSTART;
else
status = (char *)ALIVE;

if (isjson)
sprintf(buf, "{\"PGA\":%d,\"Name\":\"%s\",\"ID\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}",
pga, cgpu->api->name, cgpu->device_id,
enabled, status, cgpu->temp,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes);
json_object_foreach(info, key, value) {
if (isjson || !json_is_string(value))
vdump = json_dumps(value, JSON_COMPACT | JSON_ENCODE_ANY);
else
sprintf(buf, "PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c",
pga, cgpu->api->name, cgpu->device_id,
enabled, status, cgpu->temp,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR);

strcat(io_buffer, buf);
vdump = strdup(json_string_value(value));
tailsprintf(buf, tmpl, key, vdump);
free(vdump);
}
}
#endif

#ifdef WANT_CPUMINE
static void cpustatus(int cpu, bool isjson)
static void
devdetail_an(char *buf, struct cgpu_info *cgpu, bool isjson)
{
char buf[BUFSIZ];
tailsprintf(buf, isjson
? "{\"%s\":%d,Driver=%s"
: "%s=%d,Driver=%s",
cgpu->api->name, cgpu->device_id,
cgpu->api->dname
);

if (cgpu->kname)
tailsprintf(buf, isjson ? ",\"Kernel\":\"%s\"" : ",Kernel=%s", cgpu->kname);
if (cgpu->name)
tailsprintf(buf, isjson ? ",\"Model\":\"%s\"" : ",Model=%s", cgpu->name);
if (cgpu->device_path)
tailsprintf(buf, isjson ? ",\"Device Path\":\"%s\"" : ",Device Path=%s", cgpu->device_path);

if (cgpu->api->get_extra_device_detail) {
json_t *info = cgpu->api->get_extra_device_detail(cgpu);
append_kv(buf, info, isjson);
json_decref(info);
}

tailsprintf(buf, "%c", isjson ? '}' : SEPARATOR);
}

if (opt_n_threads > 0 && cpu >= 0 && cpu < num_processors) {
struct cgpu_info *cgpu = &cpus[cpu];
static void devstatus_an(char *buf, struct cgpu_info *cgpu, bool isjson)
{
tailsprintf(buf, isjson
? "{\"%s\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f"
: "%s=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f",
cgpu->api->name, cgpu->device_id,
bool2str(cgpu->deven != DEV_DISABLED),
status2str(cgpu->status),
cgpu->temp,
cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->utility,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes
);

if (cgpu->api->get_extra_device_status) {
json_t *info = cgpu->api->get_extra_device_status(cgpu);
append_kv(buf, info, isjson);
json_decref(info);
}

tailsprintf(buf, "%c", isjson ? '}' : SEPARATOR);
}

cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
static void gpustatus(int gpu, bool isjson)
{
if (gpu < 0 || gpu >= nDevs)
return;
devstatus_an(io_buffer, &gpus[gpu], isjson);
}

if (isjson)
sprintf(buf, "{\"CPU\":%d,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f}",
cpu, cgpu->total_mhashes / total_secs,
opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected,
cgpu->utility,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes);
else
sprintf(buf, "CPU=%d,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c",
cpu, cgpu->total_mhashes / total_secs,
opt_log_interval, cgpu->rolling,
cgpu->accepted, cgpu->rejected,
cgpu->utility,
((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1,
(unsigned long)(cgpu->last_share_pool_time), cgpu->total_mhashes, SEPARATOR);
static void pgastatus(int pga, bool isjson)
{
int dev = pgadevice(pga);
if (dev < 0) // Should never happen
return;
devstatus_an(io_buffer, devices[dev], isjson);
}

strcat(io_buffer, buf);
}
static void cpustatus(int cpu, bool isjson)
{
if (opt_n_threads <= 0 || cpu < 0 || cpu >= num_processors)
return;
devstatus_an(io_buffer, &cpus[cpu], isjson);
}
#endif

static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
static void
devinfo_internal(void (*func)(char*, struct cgpu_info*, bool),
__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson)
{
int devcount = 0;
int i;

if (nDevs == 0 && opt_n_threads == 0) {
if (total_devices == 0) {
strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson));
return;
}
Expand All @@ -931,45 +902,29 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b
strcat(io_buffer, JSON_DEVS);
}

for (i = 0; i < nDevs; i++) {
if (isjson && devcount > 0)
for (i = 0; i < total_devices; ++i) {
if (isjson && i)
strcat(io_buffer, COMMA);

gpustatus(i, isjson);

devcount++;
func(io_buffer, devices[i], isjson);
}

#if defined(USE_BITFORCE) || defined(USE_ICARUS)
int numpga = numpgas();

if (numpga > 0)
for (i = 0; i < numpga; i++) {
if (isjson && devcount > 0)
strcat(io_buffer, COMMA);

pgastatus(i, isjson);

devcount++;
}
#endif

#ifdef WANT_CPUMINE
if (opt_n_threads > 0)
for (i = 0; i < num_processors; i++) {
if (isjson && devcount > 0)
strcat(io_buffer, COMMA);

cpustatus(i, isjson);

devcount++;
}
#endif

if (isjson)
strcat(io_buffer, JSON_CLOSE);
}

static void
devdetail(SOCKETTYPE c, char *param, bool isjson)
{
return devinfo_internal(devdetail_an, c, param, isjson);
}

static void
devstatus(SOCKETTYPE c, char *param, bool isjson)
{
return devinfo_internal(devstatus_an, c, param, isjson);
}

static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
{
int id;
Expand Down Expand Up @@ -1971,6 +1926,7 @@ struct CMDS {
{ "version", apiversion, false },
{ "config", minerconfig, false },
{ "devs", devstatus, false },
{ "devdetail", devdetail, false },
{ "pools", poolstatus, false },
{ "summary", summary, false },
{ "gpuenable", gpuenable, true },
Expand Down
29 changes: 29 additions & 0 deletions driver-opencl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,34 @@ static void get_opencl_statline(char *buf, struct cgpu_info *gpu)
tailsprintf(buf, " I:%2d", gpu->intensity);
}

static json_t*
get_opencl_extra_device_status(struct cgpu_info *gpu)
{
json_t *info = json_object();

float gt, gv;
int ga, gf, gp, gc, gm, pt;
#ifdef HAVE_ADL
if (!gpu_stats(gpu->device_id, &gt, &gc, &gm, &gv, &ga, &gf, &gp, &pt))
#endif
gt = gv = gm = gc = ga = gf = gp = pt = 0;
json_object_set(info, "Fan Speed", json_integer(gf));
json_object_set(info, "Fan Percent", json_integer(gp));
json_object_set(info, "GPU Clock", json_integer(gc));
json_object_set(info, "Memory Clock", json_integer(gm));
json_object_set(info, "GPU Voltage", json_real(gv));
json_object_set(info, "GPU Activity", json_integer(ga));
json_object_set(info, "Powertune", json_integer(pt));

json_object_set(info, "Intensity",
gpu->dynamic
? json_string("D")
: json_integer(gpu->intensity)
);

return info;
}

struct opencl_thread_data {
cl_int (*queue_kernel_parameters)(_clState *, dev_blk_ctx *, cl_uint);
uint32_t *res;
Expand Down Expand Up @@ -1434,6 +1462,7 @@ struct device_api opencl_api = {
.get_statline_before = get_opencl_statline_before,
#endif
.get_statline = get_opencl_statline,
.get_extra_device_status = get_opencl_extra_device_status,
.thread_prepare = opencl_thread_prepare,
.thread_init = opencl_thread_init,
.free_work = opencl_free_work,
Expand Down
2 changes: 2 additions & 0 deletions miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ struct device_api {
void (*reinit_device)(struct cgpu_info*);
void (*get_statline_before)(char*, struct cgpu_info*);
void (*get_statline)(char*, struct cgpu_info*);
json_t* (*get_extra_device_detail)(struct cgpu_info*);
json_t* (*get_extra_device_status)(struct cgpu_info*);

// Thread-specific functions
bool (*thread_prepare)(struct thr_info*);
Expand Down