diff --git a/api.c b/api.c index 03eb75fc..2e070262 100644 --- a/api.c +++ b/api.c @@ -631,6 +631,35 @@ static char *escape_string(char *str, bool isjson) return buf; } +static struct api_data *api_add_extra(struct api_data *root, struct api_data *extra) +{ + struct api_data *tmp; + + if (root) + { + if (extra) { + // extra tail + tmp = extra->prev; + + // extra prev = root tail + extra->prev = root->prev; + + // root tail next = extra + root->prev->next = extra; + + // extra tail next = root + tmp->next = root; + + // root prev = extra tail + root->prev = tmp; + } + } + else + root = extra; + + return root; +} + static struct api_data *api_add_data_full(struct api_data *root, char *name, enum api_data_type type, void *data, bool copy_data) { struct api_data *api_data; @@ -2669,33 +2698,36 @@ void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unuse ptr = NULL; } -static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgminer_pool_stats *pool_stats, char *extra, bool isjson) +static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgminer_pool_stats *pool_stats, struct api_data *extra, bool isjson) { struct api_data *root = NULL; char buf[TMPBUFSIZ]; +/* if (stats->getwork_calls || (extra != NULL && *extra)) { if (extra == NULL) extra = (char *)BLANK; +*/ - root = api_add_int(root, "STATS", &i, false); - root = api_add_string(root, "ID", id, false); - root = api_add_double(root, "Elapsed", &(total_secs), false); - root = api_add_uint32(root, "Calls", &(stats->getwork_calls), false); - root = api_add_timeval(root, "Wait", &(stats->getwork_wait), false); - root = api_add_timeval(root, "Max", &(stats->getwork_wait_max), false); - root = api_add_timeval(root, "Min", &(stats->getwork_wait_min), false); + root = api_add_int(root, "STATS", &i, false); + root = api_add_string(root, "ID", id, false); + root = api_add_double(root, "Elapsed", &(total_secs), false); + root = api_add_uint32(root, "Calls", &(stats->getwork_calls), false); + root = api_add_timeval(root, "Wait", &(stats->getwork_wait), false); + root = api_add_timeval(root, "Max", &(stats->getwork_wait_max), false); + root = api_add_timeval(root, "Min", &(stats->getwork_wait_min), false); - if (pool_stats) { - root = api_add_uint32(root, "Pool Calls", &(pool_stats->getwork_calls), false); - root = api_add_uint32(root, "Pool Attempts", &(pool_stats->getwork_attempts), false); - root = api_add_timeval(root, "Pool Wait", &(pool_stats->getwork_wait), false); - root = api_add_timeval(root, "Pool Max", &(pool_stats->getwork_wait_max), false); - root = api_add_timeval(root, "Pool Min", &(pool_stats->getwork_wait_min), false); - root = api_add_double(root, "Pool Av", &(pool_stats->getwork_wait_rolling), false); - } + if (pool_stats) { + root = api_add_uint32(root, "Pool Calls", &(pool_stats->getwork_calls), false); + root = api_add_uint32(root, "Pool Attempts", &(pool_stats->getwork_attempts), false); + root = api_add_timeval(root, "Pool Wait", &(pool_stats->getwork_wait), false); + root = api_add_timeval(root, "Pool Max", &(pool_stats->getwork_wait_max), false); + root = api_add_timeval(root, "Pool Min", &(pool_stats->getwork_wait_min), false); + root = api_add_double(root, "Pool Av", &(pool_stats->getwork_wait_rolling), false); + } -// TODO: zzzz handle extra <- rewrite the api interface + if (extra) + root = api_add_extra(root, extra); /* sprintf(buf, isjson @@ -2729,21 +2761,21 @@ static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgmine strcat(io_buffer, buf); */ - if (isjson && (i > 0)) - strcat(io_buffer, COMMA); + if (isjson && (i > 0)) + strcat(io_buffer, COMMA); - root = print_data(root, buf, isjson); - strcat(io_buffer, buf); + root = print_data(root, buf, isjson); + strcat(io_buffer, buf); - i++; - } + i++; +// } return i; } static void minerstats(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) { - char extra[TMPBUFSIZ]; + struct api_data *extra; char id[20]; int i, j; @@ -2760,9 +2792,9 @@ static void minerstats(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, if (cgpu && cgpu->api) { if (cgpu->api->get_api_stats) - cgpu->api->get_api_stats(extra, cgpu, isjson); + extra = cgpu->api->get_api_stats(cgpu); else - extra[0] = '\0'; + extra = NULL; sprintf(id, "%s%d", cgpu->api->name, cgpu->device_id); i = itemstats(i, id, &(cgpu->cgminer_stats), NULL, extra, isjson); diff --git a/driver-icarus.c b/driver-icarus.c index 442eb9d1..a543bf8e 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -676,13 +676,30 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, return hash_count; } -static void icarus_api_stats(char *buf, struct cgpu_info *cgpu, bool isjson) +//static void icarus_api_stats(char *buf, struct cgpu_info *cgpu, bool isjson) +static struct api_data *icarus_api_stats(struct cgpu_info *cgpu) { + struct api_data *root = NULL; struct ICARUS_INFO *info = icarus_info[cgpu->device_id]; // Warning, access to these is not locked - but we don't really // care since hashing performance is way more important than // locking access to displaying API debug 'stats' + // If locking becomes an issue for any of them, use copy_data=true also + root = api_add_int(root, "read_count", &(info->read_count), false); + root = api_add_double(root, "fullnonce", &(info->fullnonce), false); + root = api_add_int(root, "count", &(info->count), false); + root = api_add_hs(root, "Hs", &(info->Hs), false); + root = api_add_double(root, "W", &(info->W), false); + root = api_add_uint(root, "total_values", &(info->values), false); + root = api_add_uint64(root, "range", &(info->hash_count_range), false); + root = api_add_uint64(root, "history_count", &(info->history_count), false); + root = api_add_timeval(root, "history_time", &(info->history_time), false); + root = api_add_uint(root, "min_data_count", &(info->min_data_count), false); + root = api_add_uint(root, "timing_values", &(info->history[0].values), false); + root = api_add_const(root, "timing_mode", timing_mode_str(info->timing_mode), false); + root = api_add_bool(root, "is_timing", &(info->do_icarus_timing), false); +/* sprintf(buf, isjson ? "\"read_count\":%d,\"fullnonce\":%f,\"count\":%d,\"Hs\":%.15f,\"W\":%f,\"total_values\":%u,\"range\":%"PRIu64",\"history_count\":%"PRIu64",\"history_time\":%f,\"min_data_count\":%u,\"timing_values\":%u" : "read_count=%d,fullnonce=%f,count=%d,Hs=%.15f,W=%f,total_values=%u,range=%"PRIu64",history_count=%"PRIu64",history_time=%f,min_data_count=%u,timing_values=%u", @@ -693,6 +710,9 @@ static void icarus_api_stats(char *buf, struct cgpu_info *cgpu, bool isjson) (double)(info->history_time.tv_sec) + ((double)(info->history_time.tv_usec))/((double)1000000), info->min_data_count, info->history[0].values); +*/ + + return root; } static void icarus_shutdown(struct thr_info *thr) diff --git a/miner.h b/miner.h index bd13b0e7..316b314a 100644 --- a/miner.h +++ b/miner.h @@ -220,6 +220,7 @@ struct gpu_adl { }; #endif +struct api_data; struct thr_info; struct work; @@ -234,7 +235,7 @@ struct device_api { void (*reinit_device)(struct cgpu_info*); void (*get_statline_before)(char*, struct cgpu_info*); void (*get_statline)(char*, struct cgpu_info*); - void (*get_api_stats)(char*, struct cgpu_info*, bool); + struct api_data *(*get_api_stats)(struct cgpu_info*); // Thread-specific functions bool (*thread_prepare)(struct thr_info*);