mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-31 08:54:19 +00:00
Merge branch 'master' into hashfast
This commit is contained in:
commit
5c9f30369a
@ -105,7 +105,7 @@ ASIC SPECIFIC COMMANDS
|
|||||||
--bitburner-fury-options <arg> Override avalon-options for BitBurner Fury boards baud:miners:asic:timeout:freq
|
--bitburner-fury-options <arg> Override avalon-options for BitBurner Fury boards baud:miners:asic:timeout:freq
|
||||||
--bitburner-fury-voltage <arg> Set BitBurner Fury core voltage, in millivolts
|
--bitburner-fury-voltage <arg> Set BitBurner Fury core voltage, in millivolts
|
||||||
--bitburner-voltage <arg> Set BitBurner (Avalon) core voltage, in millivolts
|
--bitburner-voltage <arg> Set BitBurner (Avalon) core voltage, in millivolts
|
||||||
--klondike-options <arg> Set klondike options clock:temp1:temp2:fan
|
--klondike-options <arg> Set klondike options clock:temptarget
|
||||||
|
|
||||||
|
|
||||||
AVALON AND BITBURNER DEVICES
|
AVALON AND BITBURNER DEVICES
|
||||||
|
1
README
1
README
@ -227,6 +227,7 @@ ASIC only options:
|
|||||||
--bitburner-fury-options <arg> Override avalon-options for BitBurner Fury boards baud:miners:asic:timeout:freq
|
--bitburner-fury-options <arg> Override avalon-options for BitBurner Fury boards baud:miners:asic:timeout:freq
|
||||||
--bitburner-fury-voltage <arg> Set BitBurner Fury core voltage, in millivolts
|
--bitburner-fury-voltage <arg> Set BitBurner Fury core voltage, in millivolts
|
||||||
--bitburner-voltage <arg> Set BitBurner (Avalon) core voltage, in millivolts
|
--bitburner-voltage <arg> Set BitBurner (Avalon) core voltage, in millivolts
|
||||||
|
--klondike-options <arg> Set klondike options clock:temptarget
|
||||||
|
|
||||||
See ASIC-README for more information regarding these.
|
See ASIC-README for more information regarding these.
|
||||||
|
|
||||||
|
90
cgminer.c
90
cgminer.c
@ -1274,7 +1274,7 @@ static struct opt_table opt_config_table[] = {
|
|||||||
#ifdef USE_KLONDIKE
|
#ifdef USE_KLONDIKE
|
||||||
OPT_WITH_ARG("--klondike-options",
|
OPT_WITH_ARG("--klondike-options",
|
||||||
set_klondike_options, NULL, NULL,
|
set_klondike_options, NULL, NULL,
|
||||||
"Set klondike options clock:temp1:temp2:fan"),
|
"Set klondike options clock:temptarget"),
|
||||||
#endif
|
#endif
|
||||||
OPT_WITHOUT_ARG("--load-balance",
|
OPT_WITHOUT_ARG("--load-balance",
|
||||||
set_loadbalance, &pool_strategy,
|
set_loadbalance, &pool_strategy,
|
||||||
@ -4030,52 +4030,21 @@ static int block_sort(struct block *blocka, struct block *blockb)
|
|||||||
return blocka->block_no - blockb->block_no;
|
return blocka->block_no - blockb->block_no;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Decode the current block difficulty which is in packed form */
|
||||||
static void set_blockdiff(const struct work *work)
|
static void set_blockdiff(const struct work *work)
|
||||||
{
|
{
|
||||||
uint64_t *data64, d64, diff64;
|
uint8_t pow = work->data[72];
|
||||||
double previous_diff;
|
int powdiff = (8 * (0x1d - 3)) - (8 * (pow - 3));
|
||||||
uint32_t diffhash[8];
|
uint32_t diff32 = swab32(*((uint32_t *)(work->data + 72))) & 0x00FFFFFF;
|
||||||
uint32_t difficulty;
|
double numerator = 0xFFFFULL << powdiff;
|
||||||
uint32_t diffbytes;
|
double ddiff = numerator / (double)diff32;
|
||||||
uint32_t diffvalue;
|
|
||||||
char rhash[32];
|
|
||||||
int diffshift;
|
|
||||||
|
|
||||||
difficulty = swab32(*((uint32_t *)(work->data + 72)));
|
if (unlikely(current_diff != ddiff)) {
|
||||||
|
suffix_string(ddiff, block_diff, sizeof(block_diff), 0);
|
||||||
diffbytes = ((difficulty >> 24) & 0xff) - 3;
|
current_diff = ddiff;
|
||||||
diffvalue = difficulty & 0x00ffffff;
|
|
||||||
|
|
||||||
diffshift = (diffbytes % 4) * 8;
|
|
||||||
if (diffshift == 0) {
|
|
||||||
diffshift = 32;
|
|
||||||
diffbytes--;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(diffhash, 0, 32);
|
|
||||||
diffbytes >>= 2;
|
|
||||||
if (unlikely(diffbytes > 6))
|
|
||||||
return;
|
|
||||||
diffhash[diffbytes + 1] = diffvalue >> (32 - diffshift);
|
|
||||||
diffhash[diffbytes] = diffvalue << diffshift;
|
|
||||||
|
|
||||||
swab256(rhash, diffhash);
|
|
||||||
|
|
||||||
if (opt_scrypt)
|
|
||||||
data64 = (uint64_t *)(rhash + 2);
|
|
||||||
else
|
|
||||||
data64 = (uint64_t *)(rhash + 4);
|
|
||||||
d64 = bswap_64(*data64);
|
|
||||||
if (unlikely(!d64))
|
|
||||||
d64 = 1;
|
|
||||||
|
|
||||||
previous_diff = current_diff;
|
|
||||||
diff64 = diffone / d64;
|
|
||||||
suffix_string(diff64, block_diff, sizeof(block_diff), 0);
|
|
||||||
current_diff = (double)diffone / (double)d64;
|
|
||||||
if (unlikely(current_diff != previous_diff))
|
|
||||||
applog(LOG_NOTICE, "Network diff set to %s", block_diff);
|
applog(LOG_NOTICE, "Network diff set to %s", block_diff);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool test_work_current(struct work *work)
|
static bool test_work_current(struct work *work)
|
||||||
{
|
{
|
||||||
@ -5929,38 +5898,23 @@ static void gen_hash(unsigned char *data, unsigned char *hash, int len)
|
|||||||
sha256(hash1, 32, hash);
|
sha256(hash1, 32, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Diff 1 is a 256 bit unsigned integer of
|
|
||||||
* 0x00000000ffff0000000000000000000000000000000000000000000000000000
|
|
||||||
* so we use a big endian 64 bit unsigned integer centred on the 5th byte to
|
|
||||||
* cover a huge range of difficulty targets, though not all 256 bits' worth */
|
|
||||||
void set_target(unsigned char *dest_target, double diff)
|
void set_target(unsigned char *dest_target, double diff)
|
||||||
{
|
{
|
||||||
unsigned char target[32];
|
unsigned char target[32], rtarget[32];
|
||||||
uint64_t *data64, h64;
|
uint64_t *data64, h64;
|
||||||
double d64;
|
double d64;
|
||||||
|
|
||||||
d64 = diffone;
|
if (opt_scrypt)
|
||||||
|
d64 = 0xFFFF00000000ull;
|
||||||
|
else
|
||||||
|
d64 = 0xFFFF0000ull;
|
||||||
d64 /= diff;
|
d64 /= diff;
|
||||||
h64 = d64;
|
h64 = d64;
|
||||||
|
|
||||||
memset(target, 0, 32);
|
memset(rtarget, 0xFF, 32);
|
||||||
if (h64) {
|
data64 = (uint64_t *)rtarget;
|
||||||
unsigned char rtarget[32];
|
|
||||||
|
|
||||||
memset(rtarget, 0, 32);
|
|
||||||
if (opt_scrypt)
|
|
||||||
data64 = (uint64_t *)(rtarget + 2);
|
|
||||||
else
|
|
||||||
data64 = (uint64_t *)(rtarget + 4);
|
|
||||||
*data64 = htobe64(h64);
|
*data64 = htobe64(h64);
|
||||||
swab256(target, rtarget);
|
swab256(target, rtarget);
|
||||||
} else {
|
|
||||||
/* Support for the classic all FFs just-below-1 diff */
|
|
||||||
if (opt_scrypt)
|
|
||||||
memset(target, 0xff, 30);
|
|
||||||
else
|
|
||||||
memset(target, 0xff, 28);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_debug) {
|
if (opt_debug) {
|
||||||
char *htarget = bin2hex(target, 32);
|
char *htarget = bin2hex(target, 32);
|
||||||
@ -6145,6 +6099,14 @@ static void update_work_stats(struct thr_info *thr, struct work *work)
|
|||||||
{
|
{
|
||||||
work->share_diff = share_diff(work);
|
work->share_diff = share_diff(work);
|
||||||
|
|
||||||
|
if (unlikely(work->share_diff >= current_diff)) {
|
||||||
|
work->block = true;
|
||||||
|
work->pool->solved++;
|
||||||
|
found_blocks++;
|
||||||
|
work->mandatory = true;
|
||||||
|
applog(LOG_NOTICE, "Found block for pool %d!", work->pool->pool_no);
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&stats_lock);
|
mutex_lock(&stats_lock);
|
||||||
total_diff1 += work->device_diff;
|
total_diff1 += work->device_diff;
|
||||||
thr->cgpu->diff1 += work->device_diff;
|
thr->cgpu->diff1 += work->device_diff;
|
||||||
|
@ -63,9 +63,6 @@ static const char *msg_reply = "Reply";
|
|||||||
#define KLN_KILLWORK_TEMP 53.5
|
#define KLN_KILLWORK_TEMP 53.5
|
||||||
#define KLN_COOLED_DOWN 45.5
|
#define KLN_COOLED_DOWN 45.5
|
||||||
|
|
||||||
// If 5 late updates in a row, try to reset the device
|
|
||||||
#define KLN_LATE_UPDATE_LIMIT 5
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Work older than 5s will already be completed
|
* Work older than 5s will already be completed
|
||||||
* FYI it must not be possible to complete 256 work
|
* FYI it must not be possible to complete 256 work
|
||||||
@ -74,12 +71,29 @@ static const char *msg_reply = "Reply";
|
|||||||
*/
|
*/
|
||||||
#define OLD_WORK_MS ((int)(5 * 1000))
|
#define OLD_WORK_MS ((int)(5 * 1000))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How many incorrect slave counts to ignore in a row
|
||||||
|
* 2 means it allows random grabage returned twice
|
||||||
|
* Until slaves are implemented, this should never occur
|
||||||
|
* so allowing 2 in a row should ignore random errros
|
||||||
|
*/
|
||||||
|
#define KLN_ISS_IGNORE 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the queue status hasn't been updated for this long then do it now
|
* If the queue status hasn't been updated for this long then do it now
|
||||||
* 5GH/s = 859ms per full nonce range
|
* 5GH/s = 859ms per full nonce range
|
||||||
*/
|
*/
|
||||||
#define LATE_UPDATE_MS ((int)(2.5 * 1000))
|
#define LATE_UPDATE_MS ((int)(2.5 * 1000))
|
||||||
|
|
||||||
|
// If 5 late updates in a row, try to reset the device
|
||||||
|
#define LATE_UPDATE_LIMIT 5
|
||||||
|
|
||||||
|
// If the reset fails sleep for 1s
|
||||||
|
#define LATE_UPDATE_SLEEP_MS 1000
|
||||||
|
|
||||||
|
// However give up after 8s
|
||||||
|
#define LATE_UPDATE_NODEV_MS ((int)(8.0 * 1000))
|
||||||
|
|
||||||
struct device_drv klondike_drv;
|
struct device_drv klondike_drv;
|
||||||
|
|
||||||
typedef struct klondike_header {
|
typedef struct klondike_header {
|
||||||
@ -194,12 +208,12 @@ typedef struct jobque {
|
|||||||
int workqc;
|
int workqc;
|
||||||
struct timeval last_update;
|
struct timeval last_update;
|
||||||
bool overheat;
|
bool overheat;
|
||||||
|
bool flushed;
|
||||||
int late_update_count;
|
int late_update_count;
|
||||||
int late_update_sequential;
|
int late_update_sequential;
|
||||||
} JOBQUE;
|
} JOBQUE;
|
||||||
|
|
||||||
struct klondike_info {
|
struct klondike_info {
|
||||||
bool shutdown;
|
|
||||||
pthread_rwlock_t stat_lock;
|
pthread_rwlock_t stat_lock;
|
||||||
struct thr_info replies_thr;
|
struct thr_info replies_thr;
|
||||||
cglock_t klist_lock;
|
cglock_t klist_lock;
|
||||||
@ -216,6 +230,7 @@ struct klondike_info {
|
|||||||
uint64_t hashcount;
|
uint64_t hashcount;
|
||||||
uint64_t errorcount;
|
uint64_t errorcount;
|
||||||
uint64_t noisecount;
|
uint64_t noisecount;
|
||||||
|
int incorrect_slave_sequential;
|
||||||
|
|
||||||
// us Delay from USB reply to being processed
|
// us Delay from USB reply to being processed
|
||||||
double delay_count;
|
double delay_count;
|
||||||
@ -301,7 +316,7 @@ static KLIST *allocate_kitem(struct cgpu_info *klncgpu)
|
|||||||
cg_wunlock(&klninfo->klist_lock);
|
cg_wunlock(&klninfo->klist_lock);
|
||||||
|
|
||||||
if (ran_out > 0)
|
if (ran_out > 0)
|
||||||
applog(LOG_ERR, "%s", errbuf);
|
applog(LOG_WARNING, "%s", errbuf);
|
||||||
|
|
||||||
return kitem;
|
return kitem;
|
||||||
}
|
}
|
||||||
@ -540,7 +555,7 @@ static KLIST *GetReply(struct cgpu_info *klncgpu, uint8_t cmd, uint8_t dev)
|
|||||||
KLIST *kitem;
|
KLIST *kitem;
|
||||||
int retries = CMD_REPLY_RETRIES;
|
int retries = CMD_REPLY_RETRIES;
|
||||||
|
|
||||||
while (retries-- > 0 && klninfo->shutdown == false) {
|
while (retries-- > 0 && klncgpu->shutdown == false) {
|
||||||
cgsleep_ms(REPLY_WAIT_TIME);
|
cgsleep_ms(REPLY_WAIT_TIME);
|
||||||
cg_rlock(&klninfo->klist_lock);
|
cg_rlock(&klninfo->klist_lock);
|
||||||
kitem = klninfo->used;
|
kitem = klninfo->used;
|
||||||
@ -696,16 +711,13 @@ static bool klondike_init(struct cgpu_info *klncgpu)
|
|||||||
// boundaries are checked by device, with valid values returned
|
// boundaries are checked by device, with valid values returned
|
||||||
if (opt_klondike_options != NULL) {
|
if (opt_klondike_options != NULL) {
|
||||||
int hashclock;
|
int hashclock;
|
||||||
double temp1, temp2;
|
double temptarget;
|
||||||
|
|
||||||
sscanf(opt_klondike_options, "%d:%lf:%lf:%"SCNu8,
|
sscanf(opt_klondike_options, "%d:%lf", &hashclock, &temptarget);
|
||||||
&hashclock,
|
|
||||||
&temp1, &temp2,
|
|
||||||
&kline.cfg.fantarget);
|
|
||||||
SET_HASHCLOCK(kline.cfg.hashclock, hashclock);
|
SET_HASHCLOCK(kline.cfg.hashclock, hashclock);
|
||||||
kline.cfg.temptarget = cvtCToKln(temp1);
|
kline.cfg.temptarget = cvtCToKln(temptarget);
|
||||||
kline.cfg.tempcritical = cvtCToKln(temp2);
|
kline.cfg.tempcritical = 0; // hard code for old firmware
|
||||||
kline.cfg.fantarget = (int)255*kline.cfg.fantarget/100;
|
kline.cfg.fantarget = 0xff; // hard code for old firmware
|
||||||
size = sizeof(kline.cfg) - 2;
|
size = sizeof(kline.cfg) - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -932,13 +944,13 @@ static void *klondike_get_replies(void *userdata)
|
|||||||
struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data);
|
struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data);
|
||||||
KLIST *kitem = NULL;
|
KLIST *kitem = NULL;
|
||||||
char *hexdata;
|
char *hexdata;
|
||||||
int err, recd, slaves, dev;
|
int err, recd, slaves, dev, isc;
|
||||||
bool overheat;
|
bool overheat, sent;
|
||||||
|
|
||||||
applog(LOG_DEBUG, "%s%i: listening for replies",
|
applog(LOG_DEBUG, "%s%i: listening for replies",
|
||||||
klncgpu->drv->name, klncgpu->device_id);
|
klncgpu->drv->name, klncgpu->device_id);
|
||||||
|
|
||||||
while (klninfo->shutdown == false) {
|
while (klncgpu->shutdown == false) {
|
||||||
if (klncgpu->usbinfo.nodev)
|
if (klncgpu->usbinfo.nodev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -956,7 +968,9 @@ static void *klondike_get_replies(void *userdata)
|
|||||||
}
|
}
|
||||||
if (!err && recd == REPLY_SIZE) {
|
if (!err && recd == REPLY_SIZE) {
|
||||||
cgtime(&(kitem->tv_when));
|
cgtime(&(kitem->tv_when));
|
||||||
|
rd_lock(&(klninfo->stat_lock));
|
||||||
kitem->block_seq = klninfo->block_seq;
|
kitem->block_seq = klninfo->block_seq;
|
||||||
|
rd_unlock(&(klninfo->stat_lock));
|
||||||
if (opt_log_level <= READ_DEBUG) {
|
if (opt_log_level <= READ_DEBUG) {
|
||||||
hexdata = bin2hex((unsigned char *)&(kitem->kline.hd.dev), recd-1);
|
hexdata = bin2hex((unsigned char *)&(kitem->kline.hd.dev), recd-1);
|
||||||
applog(READ_DEBUG, "%s%i:%d reply [%c:%s]",
|
applog(READ_DEBUG, "%s%i:%d reply [%c:%s]",
|
||||||
@ -993,27 +1007,59 @@ static void *klondike_get_replies(void *userdata)
|
|||||||
klondike_check_nonce(klncgpu, kitem);
|
klondike_check_nonce(klncgpu, kitem);
|
||||||
display_kline(klncgpu, &kitem->kline, msg_reply);
|
display_kline(klncgpu, &kitem->kline, msg_reply);
|
||||||
break;
|
break;
|
||||||
case KLN_CMD_STATUS:
|
|
||||||
case KLN_CMD_WORK:
|
case KLN_CMD_WORK:
|
||||||
|
// We can't do/check this until it's initialised
|
||||||
|
if (klninfo->initialised) {
|
||||||
|
dev = kitem->kline.ws.dev;
|
||||||
|
if (kitem->kline.ws.workqc == 0) {
|
||||||
|
bool idle = false;
|
||||||
|
rd_lock(&(klninfo->stat_lock));
|
||||||
|
if (klninfo->jobque[dev].flushed == false)
|
||||||
|
idle = true;
|
||||||
|
slaves = klninfo->status[0].kline.ws.slavecount;
|
||||||
|
rd_lock(&(klninfo->stat_lock));
|
||||||
|
if (idle)
|
||||||
|
applog(LOG_WARNING, "%s%i:%d went idle before work was sent",
|
||||||
|
klncgpu->drv->name,
|
||||||
|
klncgpu->device_id,
|
||||||
|
dev);
|
||||||
|
}
|
||||||
|
wr_lock(&(klninfo->stat_lock));
|
||||||
|
klninfo->jobque[dev].flushed = false;
|
||||||
|
wr_lock(&(klninfo->stat_lock));
|
||||||
|
}
|
||||||
|
case KLN_CMD_STATUS:
|
||||||
case KLN_CMD_ABORT:
|
case KLN_CMD_ABORT:
|
||||||
// We can't do/check this until it's initialised
|
// We can't do/check this until it's initialised
|
||||||
if (klninfo->initialised) {
|
if (klninfo->initialised) {
|
||||||
|
isc = 0;
|
||||||
dev = kitem->kline.ws.dev;
|
dev = kitem->kline.ws.dev;
|
||||||
wr_lock(&(klninfo->stat_lock));
|
wr_lock(&(klninfo->stat_lock));
|
||||||
klninfo->jobque[dev].workqc = (int)(kitem->kline.ws.workqc);
|
klninfo->jobque[dev].workqc = (int)(kitem->kline.ws.workqc);
|
||||||
cgtime(&(klninfo->jobque[dev].last_update));
|
cgtime(&(klninfo->jobque[dev].last_update));
|
||||||
slaves = klninfo->status[0].kline.ws.slavecount;
|
slaves = klninfo->status[0].kline.ws.slavecount;
|
||||||
overheat = klninfo->jobque[dev].overheat;
|
overheat = klninfo->jobque[dev].overheat;
|
||||||
|
if (dev == 0) {
|
||||||
|
if (kitem->kline.ws.slavecount != slaves)
|
||||||
|
isc = ++klninfo->incorrect_slave_sequential;
|
||||||
|
else
|
||||||
|
isc = klninfo->incorrect_slave_sequential = 0;
|
||||||
|
}
|
||||||
wr_unlock(&(klninfo->stat_lock));
|
wr_unlock(&(klninfo->stat_lock));
|
||||||
|
|
||||||
if (kitem->kline.ws.slavecount != slaves) {
|
if (isc) {
|
||||||
applog(LOG_ERR, "%s%i:%d reply [%c] has a diff # of slaves=%d"
|
applog(LOG_ERR, "%s%i:%d reply [%c] has a diff"
|
||||||
" (curr=%d) dropping device to hotplug",
|
" # of slaves=%d (curr=%d)%s",
|
||||||
klncgpu->drv->name, klncgpu->device_id,
|
klncgpu->drv->name,
|
||||||
dev, (char)(kitem->kline.ws.cmd),
|
klncgpu->device_id,
|
||||||
|
dev,
|
||||||
|
(char)(kitem->kline.ws.cmd),
|
||||||
(int)(kitem->kline.ws.slavecount),
|
(int)(kitem->kline.ws.slavecount),
|
||||||
slaves);
|
slaves,
|
||||||
klninfo->shutdown = true;
|
isc <= KLN_ISS_IGNORE ? "" :
|
||||||
|
" disabling device");
|
||||||
|
if (isc > KLN_ISS_IGNORE)
|
||||||
|
usb_nodev(klncgpu);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1026,22 +1072,24 @@ static void *klondike_get_replies(void *userdata)
|
|||||||
klninfo->jobque[dev].overheat = true;
|
klninfo->jobque[dev].overheat = true;
|
||||||
wr_unlock(&(klninfo->stat_lock));
|
wr_unlock(&(klninfo->stat_lock));
|
||||||
|
|
||||||
applog(LOG_ERR, "%s%i:%d Critical overheat (%.0fC)",
|
applog(LOG_WARNING, "%s%i:%d Critical overheat (%.0fC)",
|
||||||
klncgpu->drv->name, klncgpu->device_id,
|
klncgpu->drv->name,
|
||||||
|
klncgpu->device_id,
|
||||||
dev, temp);
|
dev, temp);
|
||||||
|
|
||||||
zero_kline(&kline);
|
zero_kline(&kline);
|
||||||
kline.hd.cmd = KLN_CMD_ABORT;
|
kline.hd.cmd = KLN_CMD_ABORT;
|
||||||
kline.hd.dev = dev;
|
kline.hd.dev = dev;
|
||||||
if (!SendCmd(klncgpu, &kline, KSENDHD(0))) {
|
sent = SendCmd(klncgpu, &kline, KSENDHD(0));
|
||||||
applog(LOG_ERR, "%s%i:%d failed to abort work"
|
kln_disable(klncgpu, dev, false);
|
||||||
" - dropping device to hotplug",
|
if (!sent) {
|
||||||
|
applog(LOG_ERR, "%s%i:%d overheat failed to"
|
||||||
|
" abort work - disabling device",
|
||||||
klncgpu->drv->name,
|
klncgpu->drv->name,
|
||||||
klncgpu->device_id,
|
klncgpu->device_id,
|
||||||
dev);
|
dev);
|
||||||
klninfo->shutdown = true;
|
usb_nodev(klncgpu);
|
||||||
}
|
}
|
||||||
kln_disable(klncgpu, dev, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1080,13 +1128,13 @@ static void klondike_flush_work(struct cgpu_info *klncgpu)
|
|||||||
KLINE kline;
|
KLINE kline;
|
||||||
int slaves, dev;
|
int slaves, dev;
|
||||||
|
|
||||||
|
wr_lock(&(klninfo->stat_lock));
|
||||||
klninfo->block_seq++;
|
klninfo->block_seq++;
|
||||||
|
slaves = klninfo->status[0].kline.ws.slavecount;
|
||||||
|
wr_unlock(&(klninfo->stat_lock));
|
||||||
|
|
||||||
applog(LOG_DEBUG, "%s%i: flushing work",
|
applog(LOG_DEBUG, "%s%i: flushing work",
|
||||||
klncgpu->drv->name, klncgpu->device_id);
|
klncgpu->drv->name, klncgpu->device_id);
|
||||||
rd_lock(&(klninfo->stat_lock));
|
|
||||||
slaves = klninfo->status[0].kline.ws.slavecount;
|
|
||||||
rd_unlock(&(klninfo->stat_lock));
|
|
||||||
zero_kline(&kline);
|
zero_kline(&kline);
|
||||||
kline.hd.cmd = KLN_CMD_ABORT;
|
kline.hd.cmd = KLN_CMD_ABORT;
|
||||||
for (dev = 0; dev <= slaves; dev++) {
|
for (dev = 0; dev <= slaves; dev++) {
|
||||||
@ -1097,6 +1145,7 @@ static void klondike_flush_work(struct cgpu_info *klncgpu)
|
|||||||
memcpy((void *)&(klninfo->status[dev]),
|
memcpy((void *)&(klninfo->status[dev]),
|
||||||
kitem,
|
kitem,
|
||||||
sizeof(klninfo->status[dev]));
|
sizeof(klninfo->status[dev]));
|
||||||
|
klninfo->jobque[dev].flushed = true;
|
||||||
wr_unlock(&(klninfo->stat_lock));
|
wr_unlock(&(klninfo->stat_lock));
|
||||||
kitem = release_kitem(klncgpu, kitem);
|
kitem = release_kitem(klncgpu, kitem);
|
||||||
}
|
}
|
||||||
@ -1142,7 +1191,7 @@ static void klondike_shutdown(struct thr_info *thr)
|
|||||||
|
|
||||||
kln_disable(klncgpu, klninfo->status[0].kline.ws.slavecount, true);
|
kln_disable(klncgpu, klninfo->status[0].kline.ws.slavecount, true);
|
||||||
|
|
||||||
klncgpu->shutdown = klninfo->shutdown = true;
|
klncgpu->shutdown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void klondike_thread_enable(struct thr_info *thr)
|
static void klondike_thread_enable(struct thr_info *thr)
|
||||||
@ -1228,10 +1277,13 @@ static bool klondike_queue_full(struct cgpu_info *klncgpu)
|
|||||||
{
|
{
|
||||||
struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data);
|
struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data);
|
||||||
struct work *work = NULL;
|
struct work *work = NULL;
|
||||||
int dev, queued, slaves, seq;
|
int dev, queued, slaves, seq, howlong;
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
bool nowork;
|
bool nowork;
|
||||||
|
|
||||||
|
if (klncgpu->shutdown == true)
|
||||||
|
return true;
|
||||||
|
|
||||||
cgtime(&now);
|
cgtime(&now);
|
||||||
rd_lock(&(klninfo->stat_lock));
|
rd_lock(&(klninfo->stat_lock));
|
||||||
slaves = klninfo->status[0].kline.ws.slavecount;
|
slaves = klninfo->status[0].kline.ws.slavecount;
|
||||||
@ -1240,25 +1292,30 @@ static bool klondike_queue_full(struct cgpu_info *klncgpu)
|
|||||||
klninfo->jobque[dev].late_update_count++;
|
klninfo->jobque[dev].late_update_count++;
|
||||||
seq = ++klninfo->jobque[dev].late_update_sequential;
|
seq = ++klninfo->jobque[dev].late_update_sequential;
|
||||||
rd_unlock(&(klninfo->stat_lock));
|
rd_unlock(&(klninfo->stat_lock));
|
||||||
if (seq < KLN_LATE_UPDATE_LIMIT) {
|
if (seq < LATE_UPDATE_LIMIT) {
|
||||||
applog(LOG_ERR, "%s%i:%d late update",
|
applog(LOG_DEBUG, "%s%i:%d late update",
|
||||||
klncgpu->drv->name, klncgpu->device_id, dev);
|
klncgpu->drv->name, klncgpu->device_id, dev);
|
||||||
klondike_get_stats(klncgpu);
|
klondike_get_stats(klncgpu);
|
||||||
goto que;
|
goto que;
|
||||||
} else {
|
} else {
|
||||||
applog(LOG_ERR, "%s%i:%d late update (%d) reached - attempting reset",
|
applog(LOG_WARNING, "%s%i:%d late update (%d) reached - attempting reset",
|
||||||
klncgpu->drv->name, klncgpu->device_id,
|
klncgpu->drv->name, klncgpu->device_id,
|
||||||
dev, KLN_LATE_UPDATE_LIMIT);
|
dev, LATE_UPDATE_LIMIT);
|
||||||
control_init(klncgpu);
|
control_init(klncgpu);
|
||||||
kln_enable(klncgpu);
|
kln_enable(klncgpu);
|
||||||
klondike_get_stats(klncgpu);
|
klondike_get_stats(klncgpu);
|
||||||
rd_lock(&(klninfo->stat_lock));
|
rd_lock(&(klninfo->stat_lock));
|
||||||
if (ms_tdiff(&now, &(klninfo->jobque[dev].last_update)) > LATE_UPDATE_MS) {
|
howlong = ms_tdiff(&now, &(klninfo->jobque[dev].last_update));
|
||||||
|
if (howlong > LATE_UPDATE_MS) {
|
||||||
rd_unlock(&(klninfo->stat_lock));
|
rd_unlock(&(klninfo->stat_lock));
|
||||||
|
if (howlong > LATE_UPDATE_NODEV_MS) {
|
||||||
applog(LOG_ERR, "%s%i:%d reset failed - dropping device",
|
applog(LOG_ERR, "%s%i:%d reset failed - dropping device",
|
||||||
klncgpu->drv->name, klncgpu->device_id, dev);
|
klncgpu->drv->name, klncgpu->device_id, dev);
|
||||||
klninfo->shutdown = true;
|
usb_nodev(klncgpu);
|
||||||
return false;
|
} else
|
||||||
|
cgsleep_ms(LATE_UPDATE_SLEEP_MS);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1283,7 +1340,7 @@ tryagain:
|
|||||||
if (temp <= KLN_COOLED_DOWN) {
|
if (temp <= KLN_COOLED_DOWN) {
|
||||||
klninfo->jobque[dev].overheat = false;
|
klninfo->jobque[dev].overheat = false;
|
||||||
rd_unlock(&(klninfo->stat_lock));
|
rd_unlock(&(klninfo->stat_lock));
|
||||||
applog(LOG_ERR, "%s%i:%d Overheat recovered (%.0fC)",
|
applog(LOG_WARNING, "%s%i:%d Overheat recovered (%.0fC)",
|
||||||
klncgpu->drv->name, klncgpu->device_id,
|
klncgpu->drv->name, klncgpu->device_id,
|
||||||
dev, temp);
|
dev, temp);
|
||||||
kln_enable(klncgpu);
|
kln_enable(klncgpu);
|
||||||
@ -1345,6 +1402,7 @@ static int64_t klondike_scanwork(struct thr_info *thr)
|
|||||||
klninfo->noncecount = 0;
|
klninfo->noncecount = 0;
|
||||||
rd_unlock(&(klninfo->stat_lock));
|
rd_unlock(&(klninfo->stat_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
return newhashcount;
|
return newhashcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
usbutils.c
34
usbutils.c
@ -1390,6 +1390,20 @@ static void release_cgpu(struct cgpu_info *cgpu)
|
|||||||
cgminer_usb_unlock_bd(cgpu->drv, cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address);
|
cgminer_usb_unlock_bd(cgpu->drv, cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Force a NODEV on a device so it goes back to hotplug
|
||||||
|
*/
|
||||||
|
void usb_nodev(struct cgpu_info *cgpu)
|
||||||
|
{
|
||||||
|
int pstate;
|
||||||
|
|
||||||
|
DEVWLOCK(cgpu, pstate);
|
||||||
|
|
||||||
|
release_cgpu(cgpu);
|
||||||
|
|
||||||
|
DEVWUNLOCK(cgpu, pstate);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use the same usbdev thus locking is across all related devices
|
* Use the same usbdev thus locking is across all related devices
|
||||||
*/
|
*/
|
||||||
@ -2530,14 +2544,14 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t
|
|||||||
cgtimer_t now, already_done;
|
cgtimer_t now, already_done;
|
||||||
double sleep_estimate;
|
double sleep_estimate;
|
||||||
double write_time = (double)(usbdev->last_write_siz) /
|
double write_time = (double)(usbdev->last_write_siz) /
|
||||||
(double)(usbdev->cps);
|
(double)(usbdev->cps) * 1000;
|
||||||
|
|
||||||
cgtimer_time(&now);
|
cgtimer_time(&now);
|
||||||
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
||||||
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
||||||
|
|
||||||
if (sleep_estimate > 0.0) {
|
if (sleep_estimate > 0.0) {
|
||||||
cgsleep_ms_r(&usbdev->cgt_last_write, write_time * 1000.0);
|
cgsleep_ms_r(&usbdev->cgt_last_write, write_time);
|
||||||
cgpu->usbinfo.read_delay_count++;
|
cgpu->usbinfo.read_delay_count++;
|
||||||
cgpu->usbinfo.total_read_delay += sleep_estimate;
|
cgpu->usbinfo.total_read_delay += sleep_estimate;
|
||||||
}
|
}
|
||||||
@ -2631,14 +2645,14 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t
|
|||||||
cgtimer_t now, already_done;
|
cgtimer_t now, already_done;
|
||||||
double sleep_estimate;
|
double sleep_estimate;
|
||||||
double write_time = (double)(usbdev->last_write_siz) /
|
double write_time = (double)(usbdev->last_write_siz) /
|
||||||
(double)(usbdev->cps);
|
(double)(usbdev->cps) * 1000;
|
||||||
|
|
||||||
cgtimer_time(&now);
|
cgtimer_time(&now);
|
||||||
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
||||||
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
||||||
|
|
||||||
if (sleep_estimate > 0.0) {
|
if (sleep_estimate > 0.0) {
|
||||||
cgsleep_ms_r(&usbdev->cgt_last_write, write_time * 1000.0);
|
cgsleep_ms_r(&usbdev->cgt_last_write, write_time);
|
||||||
cgpu->usbinfo.read_delay_count++;
|
cgpu->usbinfo.read_delay_count++;
|
||||||
cgpu->usbinfo.total_read_delay += sleep_estimate;
|
cgpu->usbinfo.total_read_delay += sleep_estimate;
|
||||||
}
|
}
|
||||||
@ -2778,14 +2792,14 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_
|
|||||||
cgtimer_t now, already_done;
|
cgtimer_t now, already_done;
|
||||||
double sleep_estimate;
|
double sleep_estimate;
|
||||||
double write_time = (double)(usbdev->last_write_siz) /
|
double write_time = (double)(usbdev->last_write_siz) /
|
||||||
(double)(usbdev->cps);
|
(double)(usbdev->cps) * 1000;
|
||||||
|
|
||||||
cgtimer_time(&now);
|
cgtimer_time(&now);
|
||||||
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
||||||
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
||||||
|
|
||||||
if (sleep_estimate > 0.0) {
|
if (sleep_estimate > 0.0) {
|
||||||
cgsleep_ms_r(&usbdev->cgt_last_write, write_time * 1000.0);
|
cgsleep_ms_r(&usbdev->cgt_last_write, write_time);
|
||||||
cgpu->usbinfo.write_delay_count++;
|
cgpu->usbinfo.write_delay_count++;
|
||||||
cgpu->usbinfo.total_write_delay += sleep_estimate;
|
cgpu->usbinfo.total_write_delay += sleep_estimate;
|
||||||
}
|
}
|
||||||
@ -2917,14 +2931,14 @@ int __usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bReques
|
|||||||
cgtimer_t now, already_done;
|
cgtimer_t now, already_done;
|
||||||
double sleep_estimate;
|
double sleep_estimate;
|
||||||
double write_time = (double)(usbdev->last_write_siz) /
|
double write_time = (double)(usbdev->last_write_siz) /
|
||||||
(double)(usbdev->cps);
|
(double)(usbdev->cps) * 1000;
|
||||||
|
|
||||||
cgtimer_time(&now);
|
cgtimer_time(&now);
|
||||||
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
||||||
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
||||||
|
|
||||||
if (sleep_estimate > 0.0) {
|
if (sleep_estimate > 0.0) {
|
||||||
cgsleep_ms_r(&usbdev->cgt_last_write, write_time * 1000.0);
|
cgsleep_ms_r(&usbdev->cgt_last_write, write_time);
|
||||||
cgpu->usbinfo.write_delay_count++;
|
cgpu->usbinfo.write_delay_count++;
|
||||||
cgpu->usbinfo.total_write_delay += sleep_estimate;
|
cgpu->usbinfo.total_write_delay += sleep_estimate;
|
||||||
}
|
}
|
||||||
@ -2999,14 +3013,14 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
|
|||||||
cgtimer_t now, already_done;
|
cgtimer_t now, already_done;
|
||||||
double sleep_estimate;
|
double sleep_estimate;
|
||||||
double write_time = (double)(usbdev->last_write_siz) /
|
double write_time = (double)(usbdev->last_write_siz) /
|
||||||
(double)(usbdev->cps);
|
(double)(usbdev->cps) * 1000;
|
||||||
|
|
||||||
cgtimer_time(&now);
|
cgtimer_time(&now);
|
||||||
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
cgtimer_sub(&now, &usbdev->cgt_last_write, &already_done);
|
||||||
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
sleep_estimate = write_time - cgtimer_to_ms(&already_done);
|
||||||
|
|
||||||
if (sleep_estimate > 0.0) {
|
if (sleep_estimate > 0.0) {
|
||||||
cgsleep_ms_r(&usbdev->cgt_last_write, write_time * 1000.0);
|
cgsleep_ms_r(&usbdev->cgt_last_write, write_time);
|
||||||
cgpu->usbinfo.read_delay_count++;
|
cgpu->usbinfo.read_delay_count++;
|
||||||
cgpu->usbinfo.total_read_delay += sleep_estimate;
|
cgpu->usbinfo.total_read_delay += sleep_estimate;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,8 @@ bool async_usb_transfers(void);
|
|||||||
void cancel_usb_transfers(void);
|
void cancel_usb_transfers(void);
|
||||||
void usb_all(int level);
|
void usb_all(int level);
|
||||||
const char *usb_cmdname(enum usb_cmds cmd);
|
const char *usb_cmdname(enum usb_cmds cmd);
|
||||||
void usb_applog(struct cgpu_info *bflsc, enum usb_cmds cmd, char *msg, int amount, int err);
|
void usb_applog(struct cgpu_info *cgpu, enum usb_cmds cmd, char *msg, int amount, int err);
|
||||||
|
void usb_nodev(struct cgpu_info *cgpu);
|
||||||
struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig);
|
struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig);
|
||||||
struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads);
|
struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads);
|
||||||
struct cgpu_info *usb_free_cgpu(struct cgpu_info *cgpu);
|
struct cgpu_info *usb_free_cgpu(struct cgpu_info *cgpu);
|
||||||
|
56
util.c
56
util.c
@ -588,10 +588,13 @@ char *get_proxy(char *url, struct pool *pool)
|
|||||||
void __bin2hex(char *s, const unsigned char *p, size_t len)
|
void __bin2hex(char *s, const unsigned char *p, size_t len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||||
|
|
||||||
for (i = 0; i < (int)len; i++)
|
for (i = 0; i < (int)len; i++) {
|
||||||
sprintf(s + (i * 2), "%02x", (unsigned int)p[i]);
|
*s++ = hex[p[i] >> 4];
|
||||||
|
*s++ = hex[p[i] & 0xF];
|
||||||
|
}
|
||||||
|
*s++ = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a malloced array string of a binary value of arbitrary length. The
|
/* Returns a malloced array string of a binary value of arbitrary length. The
|
||||||
@ -615,33 +618,48 @@ char *bin2hex(const unsigned char *p, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Does the reverse of bin2hex but does not allocate any ram */
|
/* Does the reverse of bin2hex but does not allocate any ram */
|
||||||
|
static const int hex2bin_tbl[256] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
};
|
||||||
bool hex2bin(unsigned char *p, const char *hexstr, size_t len)
|
bool hex2bin(unsigned char *p, const char *hexstr, size_t len)
|
||||||
{
|
{
|
||||||
|
int nibble1, nibble2;
|
||||||
|
unsigned char idx;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
while (*hexstr && len) {
|
while (*hexstr && len) {
|
||||||
char hex_byte[4];
|
|
||||||
unsigned int v;
|
|
||||||
|
|
||||||
if (unlikely(!hexstr[1])) {
|
if (unlikely(!hexstr[1])) {
|
||||||
applog(LOG_ERR, "hex2bin str truncated");
|
applog(LOG_ERR, "hex2bin str truncated");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(hex_byte, 0, 4);
|
idx = *hexstr++;
|
||||||
hex_byte[0] = hexstr[0];
|
nibble1 = hex2bin_tbl[idx];
|
||||||
hex_byte[1] = hexstr[1];
|
idx = *hexstr++;
|
||||||
|
nibble2 = hex2bin_tbl[idx];
|
||||||
|
|
||||||
if (unlikely(sscanf(hex_byte, "%x", &v) != 1)) {
|
if (unlikely((nibble1 < 0) || (nibble2 < 0))) {
|
||||||
applog(LOG_INFO, "hex2bin sscanf '%s' failed", hex_byte);
|
applog(LOG_ERR, "hex2bin scan failed");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = (unsigned char) v;
|
*p++ = (((unsigned char)nibble1) << 4) | ((unsigned char)nibble2);
|
||||||
|
--len;
|
||||||
p++;
|
|
||||||
hexstr += 2;
|
|
||||||
len--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(len == 0 && *hexstr == 0))
|
if (likely(len == 0 && *hexstr == 0))
|
||||||
@ -1061,9 +1079,13 @@ void cgtimer_time(cgtimer_t *ts_start)
|
|||||||
|
|
||||||
static void liSleep(LARGE_INTEGER *li, int timeout)
|
static void liSleep(LARGE_INTEGER *li, int timeout)
|
||||||
{
|
{
|
||||||
HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
HANDLE hTimer;
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
|
|
||||||
|
if (unlikely(timeout <= 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||||
if (unlikely(!hTimer))
|
if (unlikely(!hTimer))
|
||||||
quit(1, "Failed to create hTimer in liSleep");
|
quit(1, "Failed to create hTimer in liSleep");
|
||||||
ret = SetWaitableTimer(hTimer, li, 0, NULL, NULL, 0);
|
ret = SetWaitableTimer(hTimer, li, 0, NULL, NULL, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user