mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-22 20:44:19 +00:00
Merge branch 'master' of https://github.com/ckolivas/cgminer.git
This commit is contained in:
commit
df9e76bd73
5
adl.c
5
adl.c
@ -695,6 +695,11 @@ int gpu_fanpercent(int gpu)
|
||||
applog(LOG_WARNING, "You will need to start cgminer from scratch to correct this");
|
||||
applog(LOG_WARNING, "Disabling fanspeed monitoring on this device");
|
||||
ga->has_fanspeed = false;
|
||||
if (ga->twin) {
|
||||
applog(LOG_WARNING, "Disabling fanspeed linking on GPU twins");
|
||||
ga->twin->twin = NULL;;
|
||||
ga->twin = NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
12
api.c
12
api.c
@ -1636,10 +1636,7 @@ static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
|
||||
return;
|
||||
}
|
||||
|
||||
if (add_pool_details(true, url, user, pass) == ADD_POOL_MAXIMUM) {
|
||||
strcpy(io_buffer, message(MSG_TOOMANYP, MAX_POOLS, NULL, isjson));
|
||||
return;
|
||||
}
|
||||
add_pool_details(true, url, user, pass);
|
||||
|
||||
ptr = escape_string(url, isjson);
|
||||
strcpy(io_buffer, message(MSG_ADDPOOL, 0, ptr, isjson));
|
||||
@ -2113,12 +2110,13 @@ static int itemstats(int i, char *id, struct cgminer_stats *stats, struct cgmine
|
||||
|
||||
if (pool_stats) {
|
||||
sprintf(buf, isjson
|
||||
? ",\"Pool Calls\":%d,\"Pool Attempts\":%d,\"Pool Wait\":%ld.%06ld,\"Pool Max\":%ld.%06ld,\"Pool Min\":%ld.%06ld"
|
||||
: ",Pool Calls=%d,Pool Attempts=%d,Pool Wait=%ld.%06ld,Pool Max=%ld.%06ld,Pool Min=%ld.%06ld",
|
||||
? ",\"Pool Calls\":%d,\"Pool Attempts\":%d,\"Pool Wait\":%ld.%06ld,\"Pool Max\":%ld.%06ld,\"Pool Min\":%ld.%06ld,\"Pool Av\":%f"
|
||||
: ",Pool Calls=%d,Pool Attempts=%d,Pool Wait=%ld.%06ld,Pool Max=%ld.%06ld,Pool Min=%ld.%06ld,Pool Av=%f",
|
||||
pool_stats->getwork_calls, pool_stats->getwork_attempts,
|
||||
pool_stats->getwork_wait.tv_sec, pool_stats->getwork_wait.tv_usec,
|
||||
pool_stats->getwork_wait_max.tv_sec, pool_stats->getwork_wait_max.tv_usec,
|
||||
pool_stats->getwork_wait_min.tv_sec, pool_stats->getwork_wait_min.tv_usec);
|
||||
pool_stats->getwork_wait_min.tv_sec, pool_stats->getwork_wait_min.tv_usec,
|
||||
pool_stats->getwork_wait_rolling);
|
||||
|
||||
strcat(io_buffer, buf);
|
||||
}
|
||||
|
294
cgminer.c
294
cgminer.c
@ -116,7 +116,7 @@ struct list_head scan_devices;
|
||||
static signed int devices_enabled;
|
||||
static bool opt_removedisabled;
|
||||
int total_devices;
|
||||
struct cgpu_info *devices[MAX_DEVICES];
|
||||
struct cgpu_info **devices;
|
||||
bool have_opencl;
|
||||
int opt_n_threads = -1;
|
||||
int mining_threads;
|
||||
@ -190,7 +190,7 @@ unsigned int found_blocks;
|
||||
unsigned int local_work;
|
||||
unsigned int total_go, total_ro;
|
||||
|
||||
struct pool *pools[MAX_POOLS];
|
||||
struct pool **pools;
|
||||
static struct pool *currentpool = NULL;
|
||||
|
||||
int total_pools;
|
||||
@ -395,6 +395,7 @@ static struct pool *add_pool(void)
|
||||
if (!pool)
|
||||
quit(1, "Failed to malloc pool in add_pool");
|
||||
pool->pool_no = pool->prio = total_pools;
|
||||
pools = realloc(pools, sizeof(struct pool *) * (total_pools + 2));
|
||||
pools[total_pools++] = pool;
|
||||
if (unlikely(pthread_mutex_init(&pool->pool_lock, NULL)))
|
||||
quit(1, "Failed to pthread_mutex_init in add_pool");
|
||||
@ -1622,7 +1623,7 @@ static bool submit_upstream_work(const struct work *work, CURL *curl)
|
||||
int thr_id = work->thr_id;
|
||||
struct cgpu_info *cgpu = thr_info[thr_id].cgpu;
|
||||
struct pool *pool = work->pool;
|
||||
bool rolltime;
|
||||
int rolltime;
|
||||
uint32_t *hash32;
|
||||
char hashshow[64+1] = "";
|
||||
|
||||
@ -1837,16 +1838,15 @@ static bool get_upstream_work(struct work *work, CURL *curl)
|
||||
|
||||
url = pool->rpc_url;
|
||||
|
||||
gettimeofday(&tv_start, NULL);
|
||||
retry:
|
||||
/* A single failure response here might be reported as a dead pool and
|
||||
* there may be temporary denied messages etc. falsely reporting
|
||||
* failure so retry a few times before giving up */
|
||||
while (!val && retries++ < 3) {
|
||||
pool_stats->getwork_attempts++;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
val = json_rpc_call(curl, url, pool->rpc_userpass, rpc_req,
|
||||
false, false, &work->rolltime, pool, false);
|
||||
gettimeofday(&tv_end, NULL);
|
||||
}
|
||||
if (unlikely(!val)) {
|
||||
applog(LOG_DEBUG, "Failed json_rpc_call in get_upstream_work");
|
||||
@ -1856,12 +1856,12 @@ retry:
|
||||
rc = work_decode(json_object_get(val, "result"), work);
|
||||
if (!rc && retries < 3)
|
||||
goto retry;
|
||||
work->pool = pool;
|
||||
work->longpoll = false;
|
||||
total_getworks++;
|
||||
pool->getwork_requested++;
|
||||
|
||||
gettimeofday(&tv_end, NULL);
|
||||
timersub(&tv_end, &tv_start, &tv_elapsed);
|
||||
pool_stats->getwork_wait_rolling += ((double)tv_elapsed.tv_sec + ((double)tv_elapsed.tv_usec / 1000000)) * 0.63;
|
||||
pool_stats->getwork_wait_rolling /= 1.63;
|
||||
|
||||
timeradd(&tv_elapsed, &(pool_stats->getwork_wait), &(pool_stats->getwork_wait));
|
||||
if (timercmp(&tv_elapsed, &(pool_stats->getwork_wait_max), >)) {
|
||||
pool_stats->getwork_wait_max.tv_sec = tv_elapsed.tv_sec;
|
||||
@ -1873,6 +1873,11 @@ retry:
|
||||
}
|
||||
pool_stats->getwork_calls++;
|
||||
|
||||
work->pool = pool;
|
||||
work->longpoll = false;
|
||||
total_getworks++;
|
||||
pool->getwork_requested++;
|
||||
|
||||
json_decref(val);
|
||||
out:
|
||||
|
||||
@ -2154,22 +2159,37 @@ static bool workio_get_work(struct workio_cmd *wc)
|
||||
static bool stale_work(struct work *work, bool share)
|
||||
{
|
||||
struct timeval now;
|
||||
time_t work_expiry;
|
||||
struct pool *pool;
|
||||
int getwork_delay;
|
||||
|
||||
if (work->mandatory)
|
||||
return false;
|
||||
|
||||
if (share)
|
||||
work_expiry = opt_expiry;
|
||||
else if (work->rolltime)
|
||||
work_expiry = work->rolltime;
|
||||
else
|
||||
work_expiry = opt_scantime;
|
||||
pool = work->pool;
|
||||
/* Factor in the average getwork delay of this pool, rounding it up to
|
||||
* the nearest second */
|
||||
getwork_delay = pool->cgminer_pool_stats.getwork_wait_rolling * 5 + 1;
|
||||
if (!share) {
|
||||
work_expiry -= getwork_delay;
|
||||
if (unlikely(work_expiry < 5))
|
||||
work_expiry = 5;
|
||||
} else
|
||||
work_expiry += getwork_delay;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
if (share) {
|
||||
if ((now.tv_sec - work->tv_staged.tv_sec) >= opt_expiry)
|
||||
return true;
|
||||
} else if ((now.tv_sec - work->tv_staged.tv_sec) >= opt_scantime)
|
||||
if ((now.tv_sec - work->tv_staged.tv_sec) >= work_expiry)
|
||||
return true;
|
||||
|
||||
if (work->work_block != work_block)
|
||||
return true;
|
||||
|
||||
pool = work->pool;
|
||||
if (opt_fail_only && !share && pool != current_pool() && pool->enabled != POOL_REJECTING)
|
||||
return true;
|
||||
|
||||
@ -2379,8 +2399,11 @@ static void inc_queued(void)
|
||||
mutex_unlock(&qd_lock);
|
||||
}
|
||||
|
||||
static void dec_queued(void)
|
||||
static void dec_queued(struct work *work)
|
||||
{
|
||||
if (work->clone)
|
||||
return;
|
||||
|
||||
mutex_lock(&qd_lock);
|
||||
if (total_queued > 0)
|
||||
total_queued--;
|
||||
@ -2397,17 +2420,28 @@ static int requests_queued(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int discard_stale(void)
|
||||
static void subtract_queued(int work_units)
|
||||
{
|
||||
mutex_lock(&qd_lock);
|
||||
total_queued -= work_units;
|
||||
if (total_queued < 0)
|
||||
total_queued = 0;
|
||||
mutex_unlock(&qd_lock);
|
||||
}
|
||||
|
||||
static void discard_stale(void)
|
||||
{
|
||||
struct work *work, *tmp;
|
||||
int i, stale = 0;
|
||||
int stale = 0, nonclone = 0;
|
||||
|
||||
mutex_lock(stgd_lock);
|
||||
HASH_ITER(hh, staged_work, work, tmp) {
|
||||
if (stale_work(work, false)) {
|
||||
HASH_DEL(staged_work, work);
|
||||
if (work->clone || work->longpoll)
|
||||
if (work->clone)
|
||||
--staged_extras;
|
||||
else
|
||||
nonclone++;
|
||||
discard_work(work);
|
||||
stale++;
|
||||
}
|
||||
@ -2417,23 +2451,19 @@ static int discard_stale(void)
|
||||
applog(LOG_DEBUG, "Discarded %d stales that didn't match current hash", stale);
|
||||
|
||||
/* Dec queued outside the loop to not have recursive locks */
|
||||
for (i = 0; i < stale; i++)
|
||||
dec_queued();
|
||||
|
||||
return stale;
|
||||
subtract_queued(nonclone);
|
||||
}
|
||||
|
||||
static bool queue_request(struct thr_info *thr, bool needed);
|
||||
|
||||
static void restart_threads(void)
|
||||
{
|
||||
int i, stale;
|
||||
int i;
|
||||
|
||||
/* Discard staged work that is now stale */
|
||||
stale = discard_stale();
|
||||
discard_stale();
|
||||
|
||||
for (i = 0; i < stale; i++)
|
||||
queue_request(NULL, true);
|
||||
queue_request(NULL, true);
|
||||
|
||||
for (i = 0; i < mining_threads; i++)
|
||||
work_restart[i].restart = 1;
|
||||
@ -2556,7 +2586,7 @@ static bool hash_push(struct work *work)
|
||||
if (likely(!getq->frozen)) {
|
||||
HASH_ADD_INT(staged_work, id, work);
|
||||
HASH_SORT(staged_work, tv_sort);
|
||||
if (work->clone || work->longpoll)
|
||||
if (work->clone)
|
||||
++staged_extras;
|
||||
} else
|
||||
rc = false;
|
||||
@ -3385,7 +3415,7 @@ static bool pool_active(struct pool *pool, bool pinging)
|
||||
bool ret = false;
|
||||
json_t *val;
|
||||
CURL *curl;
|
||||
bool rolltime;
|
||||
int rolltime;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (unlikely(!curl)) {
|
||||
@ -3493,39 +3523,78 @@ static void pool_resus(struct pool *pool)
|
||||
switch_pools(NULL);
|
||||
}
|
||||
|
||||
static long requested_tv_sec;
|
||||
static time_t requested_tv_sec;
|
||||
|
||||
static bool control_tset(bool *var)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
mutex_lock(&control_lock);
|
||||
ret = *var;
|
||||
*var = true;
|
||||
mutex_unlock(&control_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void control_tclear(bool *var)
|
||||
{
|
||||
mutex_lock(&control_lock);
|
||||
*var = false;
|
||||
mutex_unlock(&control_lock);
|
||||
}
|
||||
|
||||
static bool queueing;
|
||||
|
||||
static bool queue_request(struct thr_info *thr, bool needed)
|
||||
{
|
||||
int rq = requests_queued();
|
||||
struct workio_cmd *wc;
|
||||
struct timeval now;
|
||||
time_t scan_post;
|
||||
int rq, rs;
|
||||
bool ret = true;
|
||||
|
||||
/* Prevent multiple requests being executed at once */
|
||||
if (control_tset(&queueing))
|
||||
return ret;
|
||||
|
||||
rq = requests_queued();
|
||||
rs = requests_staged();
|
||||
|
||||
/* Grab more work every 2/3 of the scan time to avoid all work expiring
|
||||
* at the same time */
|
||||
scan_post = opt_scantime * 2 / 3;
|
||||
if (scan_post < 5)
|
||||
scan_post = 5;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
/* Space out retrieval of extra work according to the number of mining
|
||||
* threads */
|
||||
if (rq >= mining_threads + staged_extras &&
|
||||
(now.tv_sec - requested_tv_sec) < opt_scantime / (mining_threads + 1))
|
||||
return true;
|
||||
/* Test to make sure we have enough work for pools without rolltime
|
||||
* and enough original work for pools with rolltime */
|
||||
if ((rq >= mining_threads || rs >= mining_threads) &&
|
||||
rq > staged_extras + opt_queue &&
|
||||
now.tv_sec - requested_tv_sec < scan_post)
|
||||
goto out;
|
||||
|
||||
requested_tv_sec = now.tv_sec;
|
||||
|
||||
inc_queued();
|
||||
|
||||
/* fill out work request message */
|
||||
wc = calloc(1, sizeof(*wc));
|
||||
if (unlikely(!wc)) {
|
||||
applog(LOG_ERR, "Failed to calloc wc in queue_request");
|
||||
return false;
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wc->cmd = WC_GET_WORK;
|
||||
if (thr)
|
||||
wc->thr = thr;
|
||||
else
|
||||
wc->thr = NULL;
|
||||
wc->thr = thr;
|
||||
|
||||
/* If we're queueing work faster than we can stage it, consider the
|
||||
* system lagging and allow work to be gathered from another pool if
|
||||
* possible */
|
||||
if (rq && needed && !requests_staged() && !opt_fail_only)
|
||||
if (rq && needed && !rs && !opt_fail_only)
|
||||
wc->lagging = true;
|
||||
|
||||
applog(LOG_DEBUG, "Queueing getwork request to work thread");
|
||||
@ -3534,12 +3603,13 @@ static bool queue_request(struct thr_info *thr, bool needed)
|
||||
if (unlikely(!tq_push(thr_info[work_thr_id].q, wc))) {
|
||||
applog(LOG_ERR, "Failed to tq_push in queue_request");
|
||||
workio_cmd_free(wc);
|
||||
return false;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
requested_tv_sec = now.tv_sec;
|
||||
inc_queued();
|
||||
return true;
|
||||
out:
|
||||
control_tclear(&queueing);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct work *hash_pop(const struct timespec *abstime)
|
||||
@ -3554,7 +3624,7 @@ static struct work *hash_pop(const struct timespec *abstime)
|
||||
if (HASH_COUNT(staged_work)) {
|
||||
work = staged_work;
|
||||
HASH_DEL(staged_work, work);
|
||||
if (work->clone || work->longpoll)
|
||||
if (work->clone)
|
||||
--staged_extras;
|
||||
}
|
||||
mutex_unlock(stgd_lock);
|
||||
@ -3571,8 +3641,7 @@ static inline bool should_roll(struct work *work)
|
||||
|
||||
static inline bool can_roll(struct work *work)
|
||||
{
|
||||
return (work->pool && !stale_work(work, false) && work->rolltime &&
|
||||
work->rolls < 11 && !work->clone);
|
||||
return (work->pool && !stale_work(work, false) && work->rolltime && !work->clone);
|
||||
}
|
||||
|
||||
static void roll_work(struct work *work)
|
||||
@ -3603,6 +3672,58 @@ static bool reuse_work(struct work *work)
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct work *make_clone(struct work *work)
|
||||
{
|
||||
struct work *work_clone = make_work();
|
||||
|
||||
memcpy(work_clone, work, sizeof(struct work));
|
||||
work_clone->clone = true;
|
||||
work_clone->longpoll = false;
|
||||
/* Make cloned work appear slightly older to bias towards keeping the
|
||||
* master work item which can be further rolled */
|
||||
work_clone->tv_staged.tv_sec -= 1;
|
||||
|
||||
return work_clone;
|
||||
}
|
||||
|
||||
/* Clones work by rolling it if possible, and returning a clone instead of the
|
||||
* original work item which gets staged again to possibly be rolled again in
|
||||
* the future */
|
||||
static struct work *clone_work(struct work *work)
|
||||
{
|
||||
int mrs = mining_threads - requests_staged();
|
||||
struct work *work_clone;
|
||||
bool cloned;
|
||||
|
||||
if (mrs < 1)
|
||||
return work;
|
||||
|
||||
cloned = false;
|
||||
work_clone = make_clone(work);
|
||||
while (mrs-- > 0 && can_roll(work) && should_roll(work)) {
|
||||
applog(LOG_DEBUG, "Pushing rolled converted work to stage thread");
|
||||
if (unlikely(!stage_work(work_clone))) {
|
||||
cloned = false;
|
||||
break;
|
||||
}
|
||||
roll_work(work);
|
||||
work_clone = make_clone(work);
|
||||
/* Roll it again to prevent duplicates should this be used
|
||||
* directly later on */
|
||||
roll_work(work);
|
||||
cloned = true;
|
||||
}
|
||||
|
||||
if (cloned) {
|
||||
stage_work(work);
|
||||
return work_clone;
|
||||
}
|
||||
|
||||
free_work(work_clone);
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
static bool get_work(struct work *work, bool requested, struct thr_info *thr,
|
||||
const int thr_id)
|
||||
{
|
||||
@ -3674,7 +3795,7 @@ retry:
|
||||
}
|
||||
|
||||
if (stale_work(work_heap, false)) {
|
||||
dec_queued();
|
||||
dec_queued(work_heap);
|
||||
discard_work(work_heap);
|
||||
goto retry;
|
||||
}
|
||||
@ -3687,18 +3808,10 @@ retry:
|
||||
pool_resus(pool);
|
||||
}
|
||||
|
||||
memcpy(work, work_heap, sizeof(*work));
|
||||
|
||||
/* Hand out a clone if we can roll this work item */
|
||||
if (reuse_work(work_heap)) {
|
||||
applog(LOG_DEBUG, "Pushing divided work to get queue head");
|
||||
|
||||
stage_work(work_heap);
|
||||
work->clone = true;
|
||||
} else {
|
||||
dec_queued();
|
||||
free_work(work_heap);
|
||||
}
|
||||
work_heap = clone_work(work_heap);
|
||||
memcpy(work, work_heap, sizeof(struct work));
|
||||
dec_queued(work_heap);
|
||||
free_work(work_heap);
|
||||
|
||||
ret = true;
|
||||
out:
|
||||
@ -4023,9 +4136,9 @@ enum {
|
||||
};
|
||||
|
||||
/* Stage another work item from the work returned in a longpoll */
|
||||
static void convert_to_work(json_t *val, bool rolltime, struct pool *pool)
|
||||
static void convert_to_work(json_t *val, int rolltime, struct pool *pool)
|
||||
{
|
||||
struct work *work, *work_clone;
|
||||
struct work *work;
|
||||
bool rc;
|
||||
|
||||
work = make_work();
|
||||
@ -4058,25 +4171,16 @@ static void convert_to_work(json_t *val, bool rolltime, struct pool *pool)
|
||||
return;
|
||||
}
|
||||
|
||||
work_clone = make_work();
|
||||
memcpy(work_clone, work, sizeof(struct work));
|
||||
while (reuse_work(work)) {
|
||||
work_clone->clone = true;
|
||||
work_clone->longpoll = false;
|
||||
applog(LOG_DEBUG, "Pushing rolled converted work to stage thread");
|
||||
if (unlikely(!stage_work(work_clone)))
|
||||
break;
|
||||
work_clone = make_work();
|
||||
memcpy(work_clone, work, sizeof(struct work));
|
||||
}
|
||||
free_work(work_clone);
|
||||
work = clone_work(work);
|
||||
|
||||
applog(LOG_DEBUG, "Pushing converted work to stage thread");
|
||||
|
||||
if (unlikely(!stage_work(work)))
|
||||
free_work(work);
|
||||
else
|
||||
else {
|
||||
inc_queued();
|
||||
applog(LOG_DEBUG, "Converted longpoll data to work");
|
||||
}
|
||||
}
|
||||
|
||||
/* If we want longpoll, enable it for the chosen default pool, or, if
|
||||
@ -4121,7 +4225,7 @@ static void *longpoll_thread(void *userdata)
|
||||
struct timeval start, end;
|
||||
CURL *curl = NULL;
|
||||
int failures = 0;
|
||||
bool rolltime;
|
||||
int rolltime;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if (unlikely(!curl)) {
|
||||
@ -4272,6 +4376,23 @@ static void *watchpool_thread(void __maybe_unused *userdata)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Work is sorted according to age, so discard the oldest work items, leaving
|
||||
* only 1 staged work item per mining thread */
|
||||
static void age_work(void)
|
||||
{
|
||||
int discarded = 0;
|
||||
|
||||
while (requests_staged() > mining_threads * 4 / 3 + opt_queue) {
|
||||
struct work *work = hash_pop(NULL);
|
||||
|
||||
if (unlikely(!work))
|
||||
break;
|
||||
discard_work(work);
|
||||
discarded++;
|
||||
}
|
||||
if (discarded)
|
||||
applog(LOG_DEBUG, "Aged %d work items", discarded);
|
||||
}
|
||||
|
||||
/* Makes sure the hashmeter keeps going even if mining threads stall, updates
|
||||
* the screen at regular intervals, and restarts threads if they appear to have
|
||||
@ -4294,6 +4415,8 @@ static void *watchdog_thread(void __maybe_unused *userdata)
|
||||
if (requests_queued() < opt_queue)
|
||||
queue_request(NULL, false);
|
||||
|
||||
age_work();
|
||||
|
||||
hashmeter(-1, &zero_tv, 0);
|
||||
|
||||
#ifdef HAVE_CURSES
|
||||
@ -4581,13 +4704,10 @@ char *curses_input(const char *query)
|
||||
}
|
||||
#endif
|
||||
|
||||
int add_pool_details(bool live, char *url, char *user, char *pass)
|
||||
void add_pool_details(bool live, char *url, char *user, char *pass)
|
||||
{
|
||||
struct pool *pool;
|
||||
|
||||
if (total_pools == MAX_POOLS)
|
||||
return ADD_POOL_MAXIMUM;
|
||||
|
||||
pool = add_pool();
|
||||
|
||||
pool->rpc_url = url;
|
||||
@ -4603,8 +4723,6 @@ int add_pool_details(bool live, char *url, char *user, char *pass)
|
||||
pool->enabled = POOL_ENABLED;
|
||||
if (live && !pool_active(pool, false))
|
||||
pool->idle = true;
|
||||
|
||||
return ADD_POOL_OK;
|
||||
}
|
||||
|
||||
#ifdef HAVE_CURSES
|
||||
@ -4614,10 +4732,6 @@ static bool input_pool(bool live)
|
||||
bool ret = false;
|
||||
|
||||
immedok(logwin, true);
|
||||
if (total_pools == MAX_POOLS) {
|
||||
wlogprint("Reached maximum number of pools.\n");
|
||||
goto out;
|
||||
}
|
||||
wlogprint("Input server details.\n");
|
||||
|
||||
url = curses_input("URL");
|
||||
@ -4645,7 +4759,8 @@ static bool input_pool(bool live)
|
||||
if (!pass)
|
||||
goto out;
|
||||
|
||||
ret = (add_pool_details(live, url, user, pass) == ADD_POOL_OK);
|
||||
add_pool_details(live, url, user, pass);
|
||||
ret = true;
|
||||
out:
|
||||
immedok(logwin, false);
|
||||
|
||||
@ -4815,6 +4930,7 @@ bool add_cgpu(struct cgpu_info*cgpu)
|
||||
cgpu->device_id = d->lastid = 0;
|
||||
HASH_ADD_STR(devids, name, d);
|
||||
}
|
||||
devices = realloc(devices, sizeof(struct cgpu_info *) * (total_devices + 2));
|
||||
devices[total_devices++] = cgpu;
|
||||
return true;
|
||||
}
|
||||
@ -4904,8 +5020,6 @@ int main(int argc, char *argv[])
|
||||
gpus[i].dynamic = true;
|
||||
#endif
|
||||
|
||||
memset(devices, 0, sizeof(devices));
|
||||
|
||||
/* parse command line */
|
||||
opt_register_table(opt_config_table,
|
||||
"Options for both config file and command line");
|
||||
|
@ -731,8 +731,6 @@ static void cpu_detect()
|
||||
if (num_processors < 1)
|
||||
return;
|
||||
|
||||
if (total_devices + opt_n_threads > MAX_DEVICES)
|
||||
opt_n_threads = MAX_DEVICES - total_devices;
|
||||
cpus = calloc(opt_n_threads, sizeof(struct cgpu_info));
|
||||
if (unlikely(!cpus))
|
||||
quit(1, "Failed to calloc cpus");
|
||||
|
@ -179,7 +179,7 @@ struct ICARUS_INFO {
|
||||
};
|
||||
|
||||
// One for each possible device
|
||||
static struct ICARUS_INFO *icarus_info[MAX_DEVICES];
|
||||
static struct ICARUS_INFO **icarus_info;
|
||||
|
||||
struct device_api icarus_api;
|
||||
|
||||
@ -421,15 +421,15 @@ static bool icarus_detect_one(const char *devpath)
|
||||
icarus->device_path = strdup(devpath);
|
||||
icarus->threads = 1;
|
||||
add_cgpu(icarus);
|
||||
icarus_info = realloc(icarus_info, sizeof(struct ICARUS_INFO *) * (total_devices + 1));
|
||||
|
||||
applog(LOG_INFO, "Found Icarus at %s, mark as %d",
|
||||
devpath, icarus->device_id);
|
||||
|
||||
if (icarus_info[icarus->device_id] == NULL) {
|
||||
icarus_info[icarus->device_id] = (struct ICARUS_INFO *)malloc(sizeof(struct ICARUS_INFO));
|
||||
if (unlikely(!(icarus_info[icarus->device_id])))
|
||||
quit(1, "Failed to malloc ICARUS_INFO");
|
||||
}
|
||||
// Since we are adding a new device on the end it needs to always be allocated
|
||||
icarus_info[icarus->device_id] = (struct ICARUS_INFO *)malloc(sizeof(struct ICARUS_INFO));
|
||||
if (unlikely(!(icarus_info[icarus->device_id])))
|
||||
quit(1, "Failed to malloc ICARUS_INFO");
|
||||
|
||||
info = icarus_info[icarus->device_id];
|
||||
|
||||
|
@ -538,15 +538,11 @@ struct cgpu_info *cpus;
|
||||
void pause_dynamic_threads(int gpu)
|
||||
{
|
||||
struct cgpu_info *cgpu = &gpus[gpu];
|
||||
int i, thread_no = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mining_threads; i++) {
|
||||
for (i = 1; i < cgpu->threads; i++) {
|
||||
struct thr_info *thr = &thr_info[i];
|
||||
|
||||
if (thr->cgpu != cgpu)
|
||||
continue;
|
||||
if (!thread_no++)
|
||||
continue;
|
||||
if (!thr->pause && cgpu->dynamic) {
|
||||
applog(LOG_WARNING, "Disabling extra threads due to dynamic mode.");
|
||||
applog(LOG_WARNING, "Tune dynamic intensity with --gpu-dyninterval");
|
||||
@ -1130,9 +1126,6 @@ static void opencl_detect()
|
||||
nDevs = 0;
|
||||
}
|
||||
|
||||
if (MAX_DEVICES - total_devices < nDevs)
|
||||
nDevs = MAX_DEVICES - total_devices;
|
||||
|
||||
if (!nDevs)
|
||||
return;
|
||||
|
||||
@ -1354,34 +1347,32 @@ static uint64_t opencl_scanhash(struct thr_info *thr, struct work *work,
|
||||
_clState *clState = clStates[thr_id];
|
||||
const cl_kernel *kernel = &clState->kernel;
|
||||
|
||||
double gpu_ms_average = 7;
|
||||
cl_int status;
|
||||
|
||||
size_t globalThreads[1];
|
||||
size_t localThreads[1] = { clState->wsize };
|
||||
unsigned int threads;
|
||||
unsigned int hashes;
|
||||
|
||||
|
||||
struct timeval tv_gpustart, tv_gpuend, diff;
|
||||
suseconds_t gpu_us;
|
||||
|
||||
gettimeofday(&tv_gpustart, NULL);
|
||||
timeval_subtract(&diff, &tv_gpustart, &tv_gpuend);
|
||||
gettimeofday(&gpu->tv_gpustart, NULL);
|
||||
/* This finish flushes the readbuffer set with CL_FALSE later */
|
||||
clFinish(clState->commandQueue);
|
||||
gettimeofday(&tv_gpuend, NULL);
|
||||
timeval_subtract(&diff, &tv_gpuend, &tv_gpustart);
|
||||
gpu_us = diff.tv_sec * 1000000 + diff.tv_usec;
|
||||
decay_time(&gpu_ms_average, gpu_us / 1000);
|
||||
gettimeofday(&gpu->tv_gpuend, NULL);
|
||||
|
||||
if (gpu->dynamic) {
|
||||
struct timeval diff;
|
||||
suseconds_t gpu_ms;
|
||||
|
||||
timersub(&gpu->tv_gpuend, &gpu->tv_gpustart, &diff);
|
||||
gpu_ms = diff.tv_sec * 1000 + diff.tv_usec / 1000;
|
||||
gpu->gpu_ms_average = (gpu->gpu_ms_average + gpu_ms * 0.63) / 1.63;
|
||||
|
||||
/* Try to not let the GPU be out for longer than 6ms, but
|
||||
* increase intensity when the system is idle, unless
|
||||
* dynamic is disabled. */
|
||||
if (gpu_ms_average > opt_dynamic_interval) {
|
||||
if (gpu->gpu_ms_average > opt_dynamic_interval) {
|
||||
if (gpu->intensity > MIN_INTENSITY)
|
||||
--gpu->intensity;
|
||||
} else if (gpu_ms_average < ((opt_dynamic_interval / 2) ? : 1)) {
|
||||
} else if (gpu->gpu_ms_average < ((opt_dynamic_interval / 2) ? : 1)) {
|
||||
if (gpu->intensity < MAX_INTENSITY)
|
||||
++gpu->intensity;
|
||||
}
|
||||
|
@ -66,8 +66,6 @@ static void ztex_detect(void)
|
||||
applog(LOG_WARNING, "Found %d ztex board(s)", cnt);
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
if (total_devices == MAX_DEVICES)
|
||||
break;
|
||||
ztex = calloc(1, sizeof(struct cgpu_info));
|
||||
ztex->api = &ztex_api;
|
||||
ztex->device_ztex = ztex_devices[i]->dev;
|
||||
|
50
fpgautils.c
50
fpgautils.c
@ -40,9 +40,6 @@
|
||||
char
|
||||
serial_autodetect_udev(detectone_func_t detectone, const char*prodname)
|
||||
{
|
||||
if (total_devices == MAX_DEVICES)
|
||||
return 0;
|
||||
|
||||
struct udev *udev = udev_new();
|
||||
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
|
||||
struct udev_list_entry *list_entry;
|
||||
@ -64,9 +61,6 @@ serial_autodetect_udev(detectone_func_t detectone, const char*prodname)
|
||||
++found;
|
||||
|
||||
udev_device_unref(device);
|
||||
|
||||
if (total_devices == MAX_DEVICES)
|
||||
break;
|
||||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
udev_unref(udev);
|
||||
@ -85,9 +79,6 @@ char
|
||||
serial_autodetect_devserial(detectone_func_t detectone, const char*prodname)
|
||||
{
|
||||
#ifndef WIN32
|
||||
if (total_devices == MAX_DEVICES)
|
||||
return 0;
|
||||
|
||||
DIR *D;
|
||||
struct dirent *de;
|
||||
const char udevdir[] = "/dev/serial/by-id";
|
||||
@ -104,11 +95,8 @@ serial_autodetect_devserial(detectone_func_t detectone, const char*prodname)
|
||||
if (!strstr(de->d_name, prodname))
|
||||
continue;
|
||||
strcpy(devfile, de->d_name);
|
||||
if (detectone(devpath)) {
|
||||
if (detectone(devpath))
|
||||
++found;
|
||||
if (total_devices == MAX_DEVICES)
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir(D);
|
||||
|
||||
@ -121,9 +109,6 @@ serial_autodetect_devserial(detectone_func_t detectone, const char*prodname)
|
||||
char
|
||||
_serial_detect(const char*dname, detectone_func_t detectone, autoscan_func_t autoscan, bool forceauto)
|
||||
{
|
||||
if (total_devices == MAX_DEVICES)
|
||||
return 0;
|
||||
|
||||
struct string_elist *iter, *tmp;
|
||||
const char*s, *p;
|
||||
bool inhibitauto = false;
|
||||
@ -148,12 +133,10 @@ _serial_detect(const char*dname, detectone_func_t detectone, autoscan_func_t aut
|
||||
string_elist_del(iter);
|
||||
inhibitauto = true;
|
||||
++found;
|
||||
if (total_devices == MAX_DEVICES)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((forceauto || !inhibitauto) && autoscan && total_devices < MAX_DEVICES)
|
||||
if ((forceauto || !inhibitauto) && autoscan)
|
||||
found += autoscan();
|
||||
|
||||
return found;
|
||||
@ -198,28 +181,33 @@ serial_open(const char*devpath, unsigned long baud, signed short timeout, bool p
|
||||
if (unlikely(fdDev == -1))
|
||||
return -1;
|
||||
|
||||
struct termios pattr;
|
||||
tcgetattr(fdDev, &pattr);
|
||||
pattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||
pattr.c_oflag &= ~OPOST;
|
||||
pattr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
pattr.c_cflag &= ~(CSIZE | PARENB);
|
||||
pattr.c_cflag |= CS8;
|
||||
struct termios my_termios;
|
||||
|
||||
tcgetattr(fdDev, &my_termios);
|
||||
|
||||
switch (baud) {
|
||||
case 0: break;
|
||||
case 115200: pattr.c_cflag = B115200; break;
|
||||
case 115200: my_termios.c_cflag = B115200; break;
|
||||
default:
|
||||
applog(LOG_WARNING, "Unrecognized baud rate: %lu", baud);
|
||||
}
|
||||
pattr.c_cflag |= CREAD | CLOCAL;
|
||||
|
||||
my_termios.c_cflag |= CS8;
|
||||
my_termios.c_cflag |= CREAD;
|
||||
my_termios.c_cflag |= CLOCAL;
|
||||
my_termios.c_cflag &= ~(CSIZE | PARENB);
|
||||
|
||||
my_termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK |
|
||||
ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||
my_termios.c_oflag &= ~OPOST;
|
||||
my_termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||
|
||||
if (timeout >= 0) {
|
||||
pattr.c_cc[VTIME] = (cc_t)timeout;
|
||||
pattr.c_cc[VMIN] = 0;
|
||||
my_termios.c_cc[VTIME] = (cc_t)timeout;
|
||||
my_termios.c_cc[VMIN] = 0;
|
||||
}
|
||||
|
||||
tcsetattr(fdDev, TCSANOW, &pattr);
|
||||
tcsetattr(fdDev, TCSANOW, &my_termios);
|
||||
if (purge)
|
||||
tcflush(fdDev, TCIOFLUSH);
|
||||
return fdDev;
|
||||
|
20
miner.h
20
miner.h
@ -300,6 +300,7 @@ struct cgminer_pool_stats {
|
||||
struct timeval getwork_wait;
|
||||
struct timeval getwork_wait_max;
|
||||
struct timeval getwork_wait_min;
|
||||
double getwork_wait_rolling;
|
||||
};
|
||||
|
||||
struct cgpu_info {
|
||||
@ -347,6 +348,10 @@ struct cgpu_info {
|
||||
cl_uint vwidth;
|
||||
size_t work_size;
|
||||
enum cl_kernels kernel;
|
||||
|
||||
struct timeval tv_gpustart;;
|
||||
struct timeval tv_gpuend;
|
||||
double gpu_ms_average;
|
||||
#endif
|
||||
|
||||
float temp;
|
||||
@ -537,7 +542,7 @@ extern pthread_rwlock_t netacc_lock;
|
||||
|
||||
extern const uint32_t sha256_init_state[];
|
||||
extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
|
||||
const char *rpc_req, bool, bool, bool *,
|
||||
const char *rpc_req, bool, bool, int *,
|
||||
struct pool *pool, bool);
|
||||
extern char *bin2hex(const unsigned char *p, size_t len);
|
||||
extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len);
|
||||
@ -580,14 +585,9 @@ extern void api(int thr_id);
|
||||
|
||||
extern struct pool *current_pool(void);
|
||||
extern int active_pools(void);
|
||||
extern int add_pool_details(bool live, char *url, char *user, char *pass);
|
||||
|
||||
#define ADD_POOL_MAXIMUM 1
|
||||
#define ADD_POOL_OK 0
|
||||
extern void add_pool_details(bool live, char *url, char *user, char *pass);
|
||||
|
||||
#define MAX_GPUDEVICES 16
|
||||
#define MAX_DEVICES 64
|
||||
#define MAX_POOLS (32)
|
||||
|
||||
#define MIN_INTENSITY -10
|
||||
#define _MIN_INTENSITY_STR "-10"
|
||||
@ -608,9 +608,9 @@ extern double total_secs;
|
||||
extern int mining_threads;
|
||||
extern struct cgpu_info *cpus;
|
||||
extern int total_devices;
|
||||
extern struct cgpu_info *devices[];
|
||||
extern struct cgpu_info **devices;
|
||||
extern int total_pools;
|
||||
extern struct pool *pools[MAX_POOLS];
|
||||
extern struct pool **pools;
|
||||
extern const char *algo_names[];
|
||||
extern enum sha256_algos opt_algo;
|
||||
extern struct strategies strategies[];
|
||||
@ -739,7 +739,7 @@ struct work {
|
||||
bool mined;
|
||||
bool clone;
|
||||
bool cloned;
|
||||
bool rolltime;
|
||||
int rolltime;
|
||||
bool longpoll;
|
||||
bool stale;
|
||||
bool mandatory;
|
||||
|
111
miner.php
111
miner.php
@ -3,6 +3,7 @@ session_start();
|
||||
#
|
||||
global $miner, $port, $readonly, $notify, $rigs, $socktimeoutsec;
|
||||
global $checklastshare, $hidefields;
|
||||
global $ignorerefresh, $changerefresh, $autorefresh;
|
||||
#
|
||||
# Don't touch these 2 - see $rigs below
|
||||
$miner = null;
|
||||
@ -50,6 +51,14 @@ $socktimeoutsec = 10;
|
||||
#$hidefields = array('POOL.URL' => 1, 'POOL.User' => 1);
|
||||
$hidefields = array();
|
||||
#
|
||||
# Auto-refresh of the page (in seconds)
|
||||
# $ignorerefresh = true/false always ignore refresh parameters
|
||||
# $changerefresh = true/false show buttons to change the value
|
||||
# $autorefresh = default value, 0 means dont auto-refresh
|
||||
$ignorerefresh = false;
|
||||
$changerefresh = true;
|
||||
$autorefresh = 0;
|
||||
#
|
||||
$here = $_SERVER['PHP_SELF'];
|
||||
#
|
||||
global $tablebegin, $tableend, $warnfont, $warnoff, $dfmt;
|
||||
@ -60,6 +69,11 @@ $warnfont = '<font color=red><b>';
|
||||
$warnoff = '</b></font>';
|
||||
$dfmt = 'H:i:s j-M-Y \U\T\CP';
|
||||
#
|
||||
global $miner_font_family, $miner_font_size;
|
||||
#
|
||||
$miner_font_family = 'verdana,arial,sans';
|
||||
$miner_font_size = '13pt';
|
||||
#
|
||||
# This below allows you to put your own settings into a seperate file
|
||||
# so you don't need to update miner.php with your preferred settings
|
||||
# every time a new version is released
|
||||
@ -76,9 +90,24 @@ $showndate = false;
|
||||
global $rigerror;
|
||||
$rigerror = array();
|
||||
#
|
||||
function htmlhead($checkapi)
|
||||
function htmlhead($checkapi, $rig)
|
||||
{
|
||||
global $miner_font_family, $miner_font_size;
|
||||
global $error, $readonly, $here;
|
||||
global $ignorerefresh, $autorefresh;
|
||||
|
||||
$paramrig = '';
|
||||
if ($rig != null && $rig != '')
|
||||
$paramrig = "&rig=$rig";
|
||||
|
||||
if ($ignorerefresh == true || $autorefresh == 0)
|
||||
$refreshmeta = '';
|
||||
else
|
||||
{
|
||||
$url = "$here?ref=$autorefresh$paramrig";
|
||||
$refreshmeta = "\n<meta http-equiv='refresh' content='$autorefresh;url=$url'>";
|
||||
}
|
||||
|
||||
if ($readonly === false && $checkapi === true)
|
||||
{
|
||||
$access = api('privileged');
|
||||
@ -87,28 +116,31 @@ function htmlhead($checkapi)
|
||||
|| $access['STATUS']['STATUS'] != 'S')
|
||||
$readonly = true;
|
||||
}
|
||||
?>
|
||||
<html><head><title>Mine</title>
|
||||
$miner_font = "font-family:$miner_font_family; font-size:$miner_font_size;";
|
||||
|
||||
echo "<html><head>$refreshmeta
|
||||
<title>Mine</title>
|
||||
<style type='text/css'>
|
||||
td { color:blue; font-family:verdana,arial,sans; font-size:13pt; }
|
||||
td.h { color:blue; font-family:verdana,arial,sans; font-size:13pt; background:#d0ffff }
|
||||
td.err { color:black; font-family:verdana,arial,sans; font-size:13pt; background:#ff3050 }
|
||||
td.warn { color:black; font-family:verdana,arial,sans; font-size:13pt; background:#ffb050 }
|
||||
td.sta { color:green; font-family:verdana,arial,sans; font-size:13pt; }
|
||||
td.tot { color:blue; font-family:verdana,arial,sans; font-size:13pt; background:#fff8f2 }
|
||||
td.lst { color:blue; font-family:verdana,arial,sans; font-size:13pt; background:#ffffdd }
|
||||
td { color:blue; $miner_font }
|
||||
td.h { color:blue; $miner_font background:#d0ffff }
|
||||
td.err { color:black; $miner_font background:#ff3050 }
|
||||
td.warn { color:black; $miner_font background:#ffb050 }
|
||||
td.sta { color:green; $miner_font }
|
||||
td.tot { color:blue; $miner_font background:#fff8f2 }
|
||||
td.lst { color:blue; $miner_font background:#ffffdd }
|
||||
</style>
|
||||
</head><body bgcolor=#ecffff>
|
||||
<script type='text/javascript'>
|
||||
function pr(a,m){if(m!=null){if(!confirm(m+'?'))return}window.location="<?php echo $here ?>"+a}
|
||||
<?php
|
||||
function pr(a,m){if(m!=null){if(!confirm(m+'?'))return}window.location='$here?ref=$autorefresh'+a}\n";
|
||||
|
||||
if ($ignorerefresh == false)
|
||||
echo "function prr(a){if(a){v=document.getElementById('refval').value}else{v=0}window.location='$here?ref='+v+'$paramrig'}\n";
|
||||
|
||||
if ($readonly === false && $checkapi === true)
|
||||
{
|
||||
?>
|
||||
function prc(a,m){pr('?arg='+a,m)}
|
||||
echo "function prc(a,m){pr('&arg='+a,m)}
|
||||
function prs(a,r){var c=a.substr(3);var z=c.split('|',2);var m=z[0].substr(0,1).toUpperCase()+z[0].substr(1)+' GPU '+z[1];prc(a+'&rig='+r,m)}
|
||||
function prs2(a,n,r){var v=document.getElementById('gi'+n).value;var c=a.substr(3);var z=c.split('|',2);var m='Set GPU '+z[1]+' '+z[0].substr(0,1).toUpperCase()+z[0].substr(1)+' to '+v;prc(a+','+v+'&rig='+r,m)}
|
||||
<?php
|
||||
function prs2(a,n,r){var v=document.getElementById('gi'+n).value;var c=a.substr(3);var z=c.split('|',2);var m='Set GPU '+z[1]+' '+z[0].substr(0,1).toUpperCase()+z[0].substr(1)+' to '+v;prc(a+','+v+'&rig='+r,m)}\n";
|
||||
}
|
||||
?>
|
||||
</script>
|
||||
@ -778,7 +810,7 @@ function doforeach($cmd, $des, $sum, $head, $datetime)
|
||||
foreach ($dthead as $name => $x)
|
||||
{
|
||||
if ($item == 'STATUS' && $name == '')
|
||||
echo "<td align=right><input type=button value='Rig $rig' onclick='pr(\"?rig=$rig\",null)'></td>";
|
||||
echo "<td align=right><input type=button value='Rig $rig' onclick='pr(\"&rig=$rig\",null)'></td>";
|
||||
else
|
||||
{
|
||||
if (isset($row[$name]))
|
||||
@ -861,7 +893,7 @@ function doforeach($cmd, $des, $sum, $head, $datetime)
|
||||
if ($rig === 'total')
|
||||
echo "<td align=right class=tot>Total:</td>";
|
||||
else
|
||||
echo "<td align=right><input type=button value='Rig $rig' onclick='pr(\"?rig=$rig\",null)'></td>";
|
||||
echo "<td align=right><input type=button value='Rig $rig' onclick='pr(\"&rig=$rig\",null)'></td>";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -884,27 +916,42 @@ function doforeach($cmd, $des, $sum, $head, $datetime)
|
||||
}
|
||||
}
|
||||
#
|
||||
function refreshbuttons()
|
||||
{
|
||||
global $readonly;
|
||||
global $ignorerefresh, $changerefresh, $autorefresh;
|
||||
|
||||
if ($ignorerefresh == false && $changerefresh == true)
|
||||
{
|
||||
echo ' ';
|
||||
echo "<input type=button value='Refresh:' onclick='prr(true)'>";
|
||||
echo "<input type=text name='refval' id='refval' size=2 value='$autorefresh'>";
|
||||
echo "<input type=button value='Off' onclick='prr(false)'>";
|
||||
}
|
||||
}
|
||||
#
|
||||
function doOne($rig, $preprocess)
|
||||
{
|
||||
global $error, $readonly, $notify;
|
||||
global $rigs;
|
||||
global $error, $readonly, $notify, $rigs;
|
||||
|
||||
htmlhead(true);
|
||||
htmlhead(true, $rig);
|
||||
|
||||
$error = null;
|
||||
|
||||
echo "<tr><td><table cellpadding=0 cellspacing=0 border=0><tr><td>";
|
||||
echo "<input type=button value='Refresh' onclick='pr(\"?rig=$rig\",null)'></td>";
|
||||
echo "<input type=button value='Refresh' onclick='pr(\"&rig=$rig\",null)'></td>";
|
||||
if (count($rigs) > 1)
|
||||
echo "<td><input type=button value='Summary' onclick='pr(\"\",null)'></td>";
|
||||
echo "<td width=100%> </td><td>";
|
||||
echo "<td width=100%> </td><td nowrap>";
|
||||
if ($readonly === false)
|
||||
{
|
||||
$msg = 'Quit CGMiner';
|
||||
$rg = '';
|
||||
if (count($rigs) > 1)
|
||||
$msg .= " Rig $rig";
|
||||
echo "<input type=button value='Quit' onclick='prc(\"quit&rig=$rig\",\"$msg\")'>";
|
||||
$rg = " Rig $rig";
|
||||
echo "<input type=button value='Restart' onclick='prc(\"restart&rig=$rig\",\"Restart CGMiner$rg\")'>";
|
||||
echo " <input type=button value='Quit' onclick='prc(\"quit&rig=$rig\",\"Quit CGMiner$rg\")'>";
|
||||
}
|
||||
refreshbuttons();
|
||||
echo "</td></tr></table></td></tr>";
|
||||
|
||||
if ($preprocess != null)
|
||||
@ -930,6 +977,14 @@ function display()
|
||||
global $tablebegin, $tableend;
|
||||
global $miner, $port;
|
||||
global $error, $readonly, $notify, $rigs;
|
||||
global $ignorerefresh, $autorefresh;
|
||||
|
||||
if ($ignorerefresh == false)
|
||||
{
|
||||
$ref = trim(getparam('ref', true));
|
||||
if ($ref != null && $ref != '')
|
||||
$autorefresh = intval($ref);
|
||||
}
|
||||
|
||||
$rig = trim(getparam('rig', true));
|
||||
|
||||
@ -998,10 +1053,12 @@ function display()
|
||||
return;
|
||||
}
|
||||
|
||||
htmlhead(false);
|
||||
htmlhead(false, null);
|
||||
|
||||
echo "<tr><td><table cellpadding=0 cellspacing=0 border=0><tr><td>";
|
||||
echo "<input type=button value='Refresh' onclick='pr(\"\",null)'>";
|
||||
echo "<td width=100%> </td><td nowrap>";
|
||||
refreshbuttons();
|
||||
echo "</td></tr></table></td></tr>";
|
||||
|
||||
if ($preprocess != null)
|
||||
|
17
util.c
17
util.c
@ -56,7 +56,7 @@ struct upload_buffer {
|
||||
|
||||
struct header_info {
|
||||
char *lp_path;
|
||||
bool has_rolltime;
|
||||
int rolltime;
|
||||
char *reason;
|
||||
};
|
||||
|
||||
@ -160,8 +160,13 @@ static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
|
||||
if (!strncasecmp("N", val, 1)) {
|
||||
applog(LOG_DEBUG, "X-Roll-Ntime: N found");
|
||||
} else {
|
||||
applog(LOG_DEBUG, "X-Roll-Ntime found");
|
||||
hi->has_rolltime = true;
|
||||
/* Check to see if expire= is supported and if not, set
|
||||
* the rolltime to the default scantime */
|
||||
if (strlen(val) > 7 && !strncasecmp("expire=", val, 7))
|
||||
sscanf(val + 7, "%d", &hi->rolltime);
|
||||
else
|
||||
hi->rolltime = opt_scantime;
|
||||
applog(LOG_DEBUG, "X-Roll-Ntime expiry set to %d", hi->rolltime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,7 +253,7 @@ static void set_nettime(void)
|
||||
|
||||
json_t *json_rpc_call(CURL *curl, const char *url,
|
||||
const char *userpass, const char *rpc_req,
|
||||
bool probe, bool longpoll, bool *rolltime,
|
||||
bool probe, bool longpoll, int *rolltime,
|
||||
struct pool *pool, bool share)
|
||||
{
|
||||
json_t *val, *err_val, *res_val;
|
||||
@ -260,7 +265,7 @@ json_t *json_rpc_call(CURL *curl, const char *url,
|
||||
char len_hdr[64], user_agent_hdr[128];
|
||||
char curl_err_str[CURL_ERROR_SIZE];
|
||||
long timeout = longpoll ? (60 * 60) : 60;
|
||||
struct header_info hi = {NULL, false, NULL};
|
||||
struct header_info hi = {NULL, 0, NULL};
|
||||
bool probing = false;
|
||||
|
||||
memset(&err, 0, sizeof(err));
|
||||
@ -375,7 +380,7 @@ json_t *json_rpc_call(CURL *curl, const char *url,
|
||||
hi.lp_path = NULL;
|
||||
}
|
||||
|
||||
*rolltime = hi.has_rolltime;
|
||||
*rolltime = hi.rolltime;
|
||||
|
||||
val = JSON_LOADS(all_data.buf, &err);
|
||||
if (!val) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user