Browse Source

Merge branch 'master' of https://github.com/ckolivas/cgminer.git

nfactor-troky
Paul Sheppard 13 years ago
parent
commit
df9e76bd73
  1. 5
      adl.c
  2. 12
      api.c
  3. 288
      cgminer.c
  4. 2
      driver-cpu.c
  5. 6
      driver-icarus.c
  6. 37
      driver-opencl.c
  7. 2
      driver-ztex.c
  8. 50
      fpgautils.c
  9. 20
      miner.h
  10. 111
      miner.php
  11. 17
      util.c

5
adl.c

@ -695,6 +695,11 @@ int gpu_fanpercent(int gpu) @@ -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

@ -1636,10 +1636,7 @@ static void addpool(__maybe_unused SOCKETTYPE c, char *param, bool isjson) @@ -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 @@ -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);
}

288
cgminer.c

@ -116,7 +116,7 @@ struct list_head scan_devices; @@ -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; @@ -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) @@ -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) @@ -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) @@ -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: @@ -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: @@ -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) @@ -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) @@ -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) @@ -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,22 +2451,18 @@ static int discard_stale(void) @@ -2417,22 +2451,18 @@ 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);
for (i = 0; i < mining_threads; i++)
@ -2556,7 +2586,7 @@ static bool hash_push(struct work *work) @@ -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) @@ -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) @@ -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;
/* 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) @@ -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) @@ -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) @@ -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) @@ -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: @@ -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: @@ -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();
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 { @@ -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,26 +4171,17 @@ static void convert_to_work(json_t *val, bool rolltime, struct pool *pool) @@ -4058,26 +4171,17 @@ 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
* the pool does not support longpoll, find the first one that does
@ -4121,7 +4225,7 @@ static void *longpoll_thread(void *userdata) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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[]) @@ -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");

2
driver-cpu.c

@ -731,8 +731,6 @@ static void cpu_detect() @@ -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");

6
driver-icarus.c

@ -179,7 +179,7 @@ struct ICARUS_INFO { @@ -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) @@ -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) {
// 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];

37
driver-opencl.c

@ -538,15 +538,11 @@ struct cgpu_info *cpus; @@ -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() @@ -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, @@ -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;
}

2
driver-ztex.c

@ -66,8 +66,6 @@ static void ztex_detect(void) @@ -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

@ -40,9 +40,6 @@ @@ -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) @@ -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 @@ -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) @@ -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) @@ -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 @@ -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 @@ -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

@ -300,6 +300,7 @@ struct cgminer_pool_stats { @@ -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 { @@ -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; @@ -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); @@ -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; @@ -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 { @@ -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

@ -3,6 +3,7 @@ session_start(); @@ -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; @@ -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>'; @@ -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; @@ -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) @@ -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) @@ -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) @@ -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) @@ -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 '&nbsp;&nbsp;&nbsp;&nbsp;';
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%>&nbsp;</td><td>";
echo "<td width=100%>&nbsp;</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 "&nbsp;<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() @@ -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() @@ -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%>&nbsp;</td><td nowrap>";
refreshbuttons();
echo "</td></tr></table></td></tr>";
if ($preprocess != null)

17
util.c

@ -56,7 +56,7 @@ struct upload_buffer { @@ -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) @@ -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) @@ -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, @@ -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, @@ -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…
Cancel
Save