From c14f2ec64241185326e475f63d783655d6f7de5e Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 3 Mar 2013 19:33:20 +1100 Subject: [PATCH 01/11] API V1.25 - add 'Last Valid Work' time for each device --- API-README | 12 +++++++++++- api.c | 3 ++- cgminer.c | 4 ++++ miner.h | 1 + 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/API-README b/API-README index c1c4ca44..567f1658 100644 --- a/API-README +++ b/API-README @@ -140,6 +140,8 @@ The list of requests - a (*) means it requires privileged access - and replies a Last Share Time=NNN, <- standand long time in seconds (or 0 if none) of last accepted share Last Share Pool=N, <- pool number (or -1 if none) + Last Valid Work=NNN, <- standand long time in seconds + of last work returned that wasn't an HW: Will not report PGAs if PGA mining is disabled Will not report CPUs if CPU mining is disabled @@ -412,7 +414,14 @@ miner.php - an example web page to access the API Feature Changelog for external applications using the API: -API V1.24 +API V1.25 + +Modified API commands: + 'devs' 'gpu' and 'pga' - add 'Last Valid Work' + +---------- + +API V1.24 (cgminer v2.11.0) Added API commands: 'zero' @@ -420,6 +429,7 @@ Added API commands: Modified API commands: 'pools' - add 'Best Share' 'devs' and 'pga' - add 'No Device' for PGAs if MMQ or BFL compiled + 'stats' - add pool: 'Net Bytes Sent', 'Net Bytes Recv' ---------- diff --git a/api.c b/api.c index 9140df64..e23548a2 100644 --- a/api.c +++ b/api.c @@ -133,7 +133,7 @@ static const char SEPARATOR = '|'; #define SEPSTR "|" static const char GPUSEP = ','; -static const char *APIVERSION = "1.24"; +static const char *APIVERSION = "1.25"; static const char *DEAD = "Dead"; #if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) static const char *SICK = "Sick"; @@ -1623,6 +1623,7 @@ static void cpustatus(struct io_data *io_data, int cpu, bool isjson, bool precom root = api_add_diff(root, "Difficulty Accepted", &(cgpu->diff_accepted), false); root = api_add_diff(root, "Difficulty Rejected", &(cgpu->diff_rejected), false); root = api_add_diff(root, "Last Share Difficulty", &(cgpu->last_share_diff), false); + root = api_add_time(root, "Last Valid Work", &(cgpu->last_device_valid_work), false); root = print_data(root, buf, isjson, precom); io_add(io_data, buf); diff --git a/cgminer.c b/cgminer.c index 7dcf2047..3c702576 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5406,6 +5406,10 @@ static bool hashtest(struct thr_info *thr, struct work *work) goto out; } + mutex_lock(&stats_lock); + thr->cgpu->last_device_valid_work = time(NULL); + mutex_unlock(&stats_lock); + ret = fulltest(hash2, work->target); if (!ret) { applog(LOG_INFO, "Share below target"); diff --git a/miner.h b/miner.h index 5be502f8..a6872e4d 100644 --- a/miner.h +++ b/miner.h @@ -497,6 +497,7 @@ struct cgpu_info { int last_share_pool; time_t last_share_pool_time; double last_share_diff; + time_t last_device_valid_work; time_t device_last_well; time_t device_last_not_well; From 41f099edffe8ff39514e11c0f1233366a8b76a89 Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 3 Mar 2013 19:53:34 +1100 Subject: [PATCH 02/11] API - return Last Valid Work --- api.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api.c b/api.c index e23548a2..44cbf7f2 100644 --- a/api.c +++ b/api.c @@ -1516,6 +1516,7 @@ static void gpustatus(struct io_data *io_data, int gpu, bool isjson, bool precom root = api_add_diff(root, "Difficulty Accepted", &(cgpu->diff_accepted), false); root = api_add_diff(root, "Difficulty Rejected", &(cgpu->diff_rejected), false); root = api_add_diff(root, "Last Share Difficulty", &(cgpu->last_share_diff), false); + root = api_add_time(root, "Last Valid Work", &(cgpu->last_device_valid_work), false); root = print_data(root, buf, isjson, precom); io_add(io_data, buf); @@ -1587,6 +1588,7 @@ static void pgastatus(struct io_data *io_data, int pga, bool isjson, bool precom #if defined(USE_MODMINER) || defined(USE_BITFORCE) root = api_add_bool(root, "No Device", &(cgpu->usbinfo.nodev), false); #endif + root = api_add_time(root, "Last Valid Work", &(cgpu->last_device_valid_work), false); root = print_data(root, buf, isjson, precom); io_add(io_data, buf); From 5d3faba603f2e1e127feeb4703624cc6d775432e Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 3 Mar 2013 20:30:44 +1100 Subject: [PATCH 03/11] miner.php report 'Last Valid Work' as time before request --- miner.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/miner.php b/miner.php index dd9ff399..8e79c68a 100644 --- a/miner.php +++ b/miner.php @@ -641,6 +641,14 @@ function fmt($section, $name, $value, $when, $alldata) $class = classlastshare($when, $alldata, $warnclass, $errorclass); } break; + case 'GPU.Last Valid Work': + case 'PGA.Last Valid Work': + case 'DEVS.Last Valid Work': + if ($value == 0) + $ret = 'Never'; + else + $ret = ($value - $when) . 's'; + break; case 'POOL.Last Share Time': if ($value == 0) $ret = 'Never'; From e35e8ae135c4e9452874bc0818f87e09b7479df0 Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 09:45:07 +1100 Subject: [PATCH 04/11] Implement and use usb_cleanup() on shutdown or restart --- cgminer.c | 10 ++++++++++ usbutils.c | 16 +++++++++++++++- usbutils.h | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index 3c702576..910bce5d 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2842,6 +2842,16 @@ static void __kill_work(void) applog(LOG_DEBUG, "Killing off API thread"); thr = &control_thr[api_thr_id]; thr_info_cancel(thr); + +#if defined(USE_MODMINER) || defined(USE_BITFORCE) + /* Release USB resources in case it's a restart + * and not a QUIT */ + if (!opt_scrypt) { + applog(LOG_DEBUG, "Releasing all USB devices"); + usb_cleanup(); + } +#endif + } /* This should be the common exit path */ diff --git a/usbutils.c b/usbutils.c index f0dd7c77..27c67cea 100644 --- a/usbutils.c +++ b/usbutils.c @@ -184,6 +184,7 @@ static const char *C_SETFLOW_S = "SetFlowCtrl"; static const char *C_SETMODEM_S = "SetModemCtrl"; static const char *C_PURGERX_S = "PurgeRx"; static const char *C_PURGETX_S = "PurgeTx"; +static const char *C_FLASHREPLY_S = "FlashReply"; #ifdef EOL #undef EOL @@ -572,6 +573,7 @@ static void cgusb_check_init() usb_commands[C_SETMODEM] = C_SETMODEM_S; usb_commands[C_PURGERX] = C_PURGERX_S; usb_commands[C_PURGETX] = C_PURGETX_S; + usb_commands[C_FLASHREPLY] = C_FLASHREPLY_S; stats_initialised = true; } @@ -1522,5 +1524,17 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest void usb_cleanup() { - // TODO: + int i; + + mutex_lock(&devices_lock); + for (i = 0; i < total_devices; i++) { + switch (devices[i]->drv->drv_id) { + case DRIVER_BITFORCE: + case DRIVER_MODMINER: + release_cgpu(devices[i]); + default: + break; + } + } + mutex_unlock(&devices_lock); } diff --git a/usbutils.h b/usbutils.h index 1ec19360..fc6340f0 100644 --- a/usbutils.h +++ b/usbutils.h @@ -122,6 +122,7 @@ enum usb_cmds { C_SETMODEM, C_PURGERX, C_PURGETX, + C_FLASHREPLY, C_MAX }; From aed1e516db1ab2ce30cc2144398c2845e30069c1 Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 10:16:44 +1100 Subject: [PATCH 05/11] usb_cleanup() use correct locking mechanism --- usbutils.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/usbutils.c b/usbutils.c index 27c67cea..6b2997e2 100644 --- a/usbutils.c +++ b/usbutils.c @@ -1524,17 +1524,18 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest void usb_cleanup() { + struct cgpu_info *cgpu; int i; - mutex_lock(&devices_lock); for (i = 0; i < total_devices; i++) { - switch (devices[i]->drv->drv_id) { + cgpu = get_devices(i); + switch (cgpu->drv->drv_id) { case DRIVER_BITFORCE: case DRIVER_MODMINER: - release_cgpu(devices[i]); + release_cgpu(cgpu); + break; default: break; } } - mutex_unlock(&devices_lock); } From 97cb77d18a3ad46b179f5a967fef90f0e41005a7 Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 14:06:15 +1100 Subject: [PATCH 06/11] curses - fix - put a dev_width inside #ifdef --- cgminer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cgminer.c b/cgminer.c index 910bce5d..5300e1ea 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6715,7 +6715,9 @@ void enable_device(struct cgpu_info *cgpu) mutex_unlock(&devices_lock); if (hotplug_mode) { new_threads += cgpu->threads; +#ifdef HAVE_CURSES adj_width(mining_threads + new_threads, &dev_width); +#endif } else { mining_threads += cgpu->threads; #ifdef HAVE_CURSES From be8cadbc46f0d25e912df851f89142f54cbc66ea Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 17:26:11 +1100 Subject: [PATCH 07/11] Hotplug - allow setting interval via --hotplug or API --- API-README | 12 ++++++++++++ api.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ cgminer.c | 32 ++++++++++++++++++++++++-------- miner.h | 1 + 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/API-README b/API-README index 567f1658..de6233cd 100644 --- a/API-README +++ b/API-README @@ -361,6 +361,14 @@ The list of requests - a (*) means it requires privileged access - and replies a shown on the cgminer display like is normally displayed on exit. + hotplug|N (*) none There is no reply section just the STATUS section + stating that the hotplug setting succeeded + If the code is not compiled with hotplug in it, the + the warning reply will be 'Hotplug is not available' + If N=0 then hotplug will be disabled + If N>0 && <=9999, then hotplug will check for new + devices every N seconds + When you enable, disable or restart a GPU or PGA, you will also get Thread messages in the cgminer status window @@ -416,8 +424,12 @@ Feature Changelog for external applications using the API: API V1.25 +Added API commands: + 'hotplug' + Modified API commands: 'devs' 'gpu' and 'pga' - add 'Last Valid Work' + 'config' - add 'Hotplug' ---------- diff --git a/api.c b/api.c index 44cbf7f2..bb14105b 100644 --- a/api.c +++ b/api.c @@ -149,6 +149,8 @@ static const char *UNKNOWN = "Unknown"; static const char *DYNAMIC = _DYNAMIC; #endif +static __maybe_unused const char *NONE = "None"; + static const char *YES = "Y"; static const char *NO = "N"; static const char *NULLSTR = "(null)"; @@ -392,6 +394,11 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_ZERSUM 96 #define MSG_ZERNOSUM 97 #define MSG_USBNODEV 98 +#define MSG_INVHPLG 99 +#define MSG_HOTPLUG 100 +#define MSG_DISHPLG 101 +#define MSG_NOHPLG 102 +#define MSG_MISHPLG 102 enum code_severity { SEVERITY_ERR, @@ -421,6 +428,7 @@ enum code_parameters { PARAM_BOTH, PARAM_BOOL, PARAM_SET, + PARAM_INT, PARAM_NONE }; @@ -572,6 +580,11 @@ struct CODES { #if defined(USE_MODMINER) || defined(USE_BITFORCE) { SEVERITY_ERR, MSG_USBNODEV, PARAM_PGA, "PGA%d has no device" }, #endif + { SEVERITY_ERR, MSG_INVHPLG, PARAM_STR, "Invalid value for hotplug (%s) must be 0..9999" }, + { SEVERITY_SUCC, MSG_HOTPLUG, PARAM_INT, "Hotplug check set to %ds" }, + { SEVERITY_SUCC, MSG_DISHPLG, PARAM_NONE, "Hotplug disabled" }, + { SEVERITY_WARN, MSG_NOHPLG, PARAM_NONE, "Hotplug is not available" }, + { SEVERITY_ERR, MSG_MISHPLG, PARAM_NONE, "Missing hotplug parameter" }, { SEVERITY_FAIL, 0, 0, NULL } }; @@ -1254,6 +1267,7 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p case PARAM_PGA: case PARAM_CPU: case PARAM_PID: + case PARAM_INT: sprintf(buf, codes[i].description, paramid); break; case PARAM_POOL: @@ -1426,6 +1440,14 @@ static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ root = api_add_int(root, "ScanTime", &opt_scantime, false); root = api_add_int(root, "Queue", &opt_queue, false); root = api_add_int(root, "Expiry", &opt_expiry, false); +#if defined(USE_MODMINER) || defined(USE_BITFORCE) + if (hotplug_time == 0) + root = api_add_const(root, "Hotplug", DISABLED, false); + else + root = api_add_int(root, "Hotplug", &hotplug_time, false); +#else + root = api_add_const(root, "Hotplug", NONE, false); +#endif root = print_data(root, buf, isjson, false); io_add(io_data, buf); @@ -3308,6 +3330,34 @@ static void dozero(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *p message(io_data, MSG_ZERNOSUM, 0, all ? "All" : "BestShare", isjson); } +static void dohotplug(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +{ +#if defined(USE_MODMINER) || defined(USE_BITFORCE) + int value; + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISHPLG, 0, NULL, isjson); + return; + } + + value = atoi(param); + if (value < 0 || value > 9999) { + message(io_data, MSG_INVHPLG, 0, param, isjson); + return; + } + + hotplug_time = value; + + if (value) + message(io_data, MSG_HOTPLUG, value, NULL, isjson); + else + message(io_data, MSG_DISHPLG, 0, NULL, isjson); +#else + message(io_data, MSG_NOHPLG, 0, NULL, isjson); + return; +#endif +} + static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, char group); struct CMDS { @@ -3368,6 +3418,7 @@ struct CMDS { { "pgaset", pgaset, true }, #endif { "zero", dozero, true }, + { "hotplug", dohotplug, true }, { NULL, NULL, false } }; diff --git a/cgminer.c b/cgminer.c index 5300e1ea..2a51afe6 100644 --- a/cgminer.c +++ b/cgminer.c @@ -165,6 +165,7 @@ bool hotplug_mode; static int new_devices; static int new_threads; static int start_devices; +int hotplug_time = 5; #ifdef HAVE_LIBUSB pthread_mutex_t cgusb_lock; @@ -984,6 +985,14 @@ static struct opt_table opt_config_table[] = { set_intensity, NULL, NULL, "Intensity of GPU scanning (d or " _MIN_INTENSITY_STR " -> " _MAX_INTENSITY_STR ", default: d to maintain desktop interactivity)"), #endif + OPT_WITH_ARG("--hotplug", + set_int_0_to_9999, NULL, &hotplug_time, +#if defined(USE_MODMINER) || defined(USE_BITFORCE) + "Seconds between hotplug checks (0 means never check)" +#else + opt_hidden +#endif + ), #if defined(HAVE_OPENCL) || defined(HAVE_MODMINER) OPT_WITH_ARG("--kernel-path|-K", opt_set_charp, opt_show_charp, &opt_kernel_path, @@ -6853,24 +6862,31 @@ static void *hotplug_thread(void __maybe_unused *userdata) hotplug_mode = true; - while (0x2a) { - nmsleep(5000); + nmsleep(5000); + while (0x2a) { // Version 0.1 just add the devices on - worry about using nodev later - new_devices = 0; - new_threads = 0; + if (hotplug_time == 0) + nmsleep(5000); + else { + new_devices = 0; + new_threads = 0; #ifdef USE_BITFORCE - bitforce_drv.drv_detect(); + bitforce_drv.drv_detect(); #endif #ifdef USE_MODMINER - modminer_drv.drv_detect(); + modminer_drv.drv_detect(); #endif - if (new_devices) - hotplug_process(); + if (new_devices) + hotplug_process(); + + // hotplug_time >0 && <=9999 + nmsleep(hotplug_time * 1000); + } } return NULL; diff --git a/miner.h b/miner.h index a6872e4d..07918c69 100644 --- a/miner.h +++ b/miner.h @@ -801,6 +801,7 @@ extern void add_pool_details(struct pool *pool, bool live, char *url, char *user #endif extern bool hotplug_mode; +extern int hotplug_time; extern struct list_head scan_devices; extern int nDevs; extern int opt_n_threads; From f8e7012d73c39a4642bc0d3fb83136a2054d183e Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 17:29:58 +1100 Subject: [PATCH 08/11] api.c fix MSG overlap --- api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.c b/api.c index bb14105b..f30a75e2 100644 --- a/api.c +++ b/api.c @@ -398,7 +398,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_HOTPLUG 100 #define MSG_DISHPLG 101 #define MSG_NOHPLG 102 -#define MSG_MISHPLG 102 +#define MSG_MISHPLG 103 enum code_severity { SEVERITY_ERR, From 1bfc7120f70289a5e856eb0f458924a7b50c6d64 Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 18:02:35 +1100 Subject: [PATCH 09/11] README --hotplug --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index d25c9c22..7bb9d3a8 100644 --- a/README +++ b/README @@ -149,6 +149,7 @@ Options for both config file and command line: --expiry|-E Upper bound on how many seconds after getting work we consider a share from it stale (default: 120) --failover-only Don't leak work to backup pools when primary pool is lagging --fix-protocol Do not redirect to a different getwork protocol (eg. stratum) +--hotplug Set hotplug check time to seconds (0=never default: 5) - only with libusb --kernel-path|-K Specify a path to where bitstream and kernel files are (default: "/usr/local/bin") --load-balance Change multipool strategy from failover to efficiency based balance --log|-l Interval in seconds between log output (default: 5) From f1ab8ea9e7eba981c9d087fed46ff86f9eb938ec Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 21:18:42 +1100 Subject: [PATCH 10/11] Release MMQ device only once (not 4 times) --- usbutils.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/usbutils.c b/usbutils.c index 6b2997e2..a4527a85 100644 --- a/usbutils.c +++ b/usbutils.c @@ -859,6 +859,10 @@ static void release_cgpu(struct cgpu_info *cgpu) struct cgpu_info *lookcgpu; int i; + // It has already been done + if (cgpu->usbinfo.nodev) + return; + cgpu->usbinfo.nodev = true; cgpu->usbinfo.nodev_count++; gettimeofday(&(cgpu->usbinfo.last_nodev), NULL); From 120e9a072d8527e20c19d0488edf62c7bd95254f Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 4 Mar 2013 22:46:34 +1100 Subject: [PATCH 11/11] make rw locks: mining_thr_lock and devices_lock --- api.c | 10 +++++----- cgminer.c | 48 ++++++++++++++++++++++++------------------------ miner.h | 4 ++-- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/api.c b/api.c index f30a75e2..6acf6014 100644 --- a/api.c +++ b/api.c @@ -1161,7 +1161,7 @@ static int numpgas() int count = 0; int i; - mutex_lock(&devices_lock); + rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { #ifdef USE_BITFORCE if (devices[i]->drv->drv_id == DRIVER_BITFORCE) @@ -1180,7 +1180,7 @@ static int numpgas() count++; #endif } - mutex_unlock(&devices_lock); + rd_unlock(&devices_lock); return count; } @@ -1189,7 +1189,7 @@ static int pgadevice(int pgaid) int count = 0; int i; - mutex_lock(&devices_lock); + rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { #ifdef USE_BITFORCE if (devices[i]->drv->drv_id == DRIVER_BITFORCE) @@ -1211,12 +1211,12 @@ static int pgadevice(int pgaid) goto foundit; } - mutex_unlock(&devices_lock); + rd_unlock(&devices_lock); return -1; foundit: - mutex_unlock(&devices_lock); + rd_unlock(&devices_lock); return i; } #endif diff --git a/cgminer.c b/cgminer.c index 2a51afe6..e4885926 100644 --- a/cgminer.c +++ b/cgminer.c @@ -180,8 +180,8 @@ static pthread_rwlock_t blk_lock; static pthread_mutex_t sshare_lock; pthread_rwlock_t netacc_lock; -pthread_mutex_t mining_thr_lock; -pthread_mutex_t devices_lock; +pthread_rwlock_t mining_thr_lock; +pthread_rwlock_t devices_lock; static pthread_mutex_t lp_lock; static pthread_cond_t lp_cond; @@ -379,9 +379,9 @@ struct thr_info *get_thread(int thr_id) { struct thr_info *thr; - mutex_lock(&mining_thr_lock); + rd_lock(&mining_thr_lock); thr = mining_thr[thr_id]; - mutex_unlock(&mining_thr_lock); + rd_unlock(&mining_thr_lock); return thr; } @@ -396,9 +396,9 @@ struct cgpu_info *get_devices(int id) { struct cgpu_info *cgpu; - mutex_lock(&devices_lock); + rd_lock(&devices_lock); cgpu = devices[id]; - mutex_unlock(&devices_lock); + rd_unlock(&devices_lock); return cgpu; } @@ -762,24 +762,24 @@ static void load_temp_cutoffs() if (val < 0 || val > 200) quit(1, "Invalid value passed to set temp cutoff"); - mutex_lock(&devices_lock); + rd_lock(&devices_lock); devices[device]->cutofftemp = val; - mutex_unlock(&devices_lock); + rd_unlock(&devices_lock); } } else { - mutex_lock(&devices_lock); + rd_lock(&devices_lock); for (i = device; i < total_devices; ++i) { if (!devices[i]->cutofftemp) devices[i]->cutofftemp = opt_cutofftemp; } - mutex_unlock(&devices_lock); + rd_unlock(&devices_lock); return; } if (device <= 1) { - mutex_lock(&devices_lock); + rd_lock(&devices_lock); for (i = device; i < total_devices; ++i) devices[i]->cutofftemp = val; - mutex_unlock(&devices_lock); + rd_unlock(&devices_lock); } } @@ -3496,10 +3496,10 @@ static void restart_threads(void) /* Discard staged work that is now stale */ discard_stale(); - mutex_lock(&mining_thr_lock); + rd_lock(&mining_thr_lock); for (i = 0; i < mining_threads; i++) mining_thr[i]->work_restart = true; - mutex_unlock(&mining_thr_lock); + rd_unlock(&mining_thr_lock); mutex_lock(&restart_lock); pthread_cond_broadcast(&restart_cond); @@ -6152,10 +6152,10 @@ static void *watchdog_thread(void __maybe_unused *userdata) applog(LOG_WARNING, "Will restart execution as scheduled at %02d:%02d", schedstart.tm.tm_hour, schedstart.tm.tm_min); sched_paused = true; - mutex_lock(&mining_thr_lock); + rd_lock(&mining_thr_lock); for (i = 0; i < mining_threads; i++) mining_thr[i]->pause = true; - mutex_unlock(&mining_thr_lock); + rd_unlock(&mining_thr_lock); } else if (sched_paused && should_run()) { applog(LOG_WARNING, "Restarting execution as per start time %02d:%02d scheduled", schedstart.tm.tm_hour, schedstart.tm.tm_min); @@ -6719,9 +6719,9 @@ void fill_device_drv(struct cgpu_info *cgpu) void enable_device(struct cgpu_info *cgpu) { cgpu->deven = DEV_ENABLED; - mutex_lock(&devices_lock); + wr_lock(&devices_lock); devices[cgpu->cgminer_id = cgminer_id_count++] = cgpu; - mutex_unlock(&devices_lock); + wr_unlock(&devices_lock); if (hotplug_mode) { new_threads += cgpu->threads; #ifdef HAVE_CURSES @@ -6764,9 +6764,9 @@ bool add_cgpu(struct cgpu_info*cgpu) cgpu->device_id = d->lastid = 0; HASH_ADD_STR(devids, name, d); } - mutex_lock(&devices_lock); + wr_lock(&devices_lock); devices = realloc(devices, sizeof(struct cgpu_info *) * (total_devices + new_devices + 2)); - mutex_unlock(&devices_lock); + wr_unlock(&devices_lock); if (hotplug_mode) devices[total_devices + new_devices++] = cgpu; else @@ -6802,9 +6802,9 @@ static void hotplug_process() cgpu->rolling = cgpu->total_mhashes = 0; } - mutex_lock(&mining_thr_lock); + wr_lock(&mining_thr_lock); mining_thr = realloc(mining_thr, sizeof(thr) * (mining_threads + new_threads + 1)); - mutex_unlock(&mining_thr_lock); + wr_unlock(&mining_thr_lock); if (!mining_thr) quit(1, "Failed to hotplug realloc mining_thr"); for (i = 0; i < new_threads; i++) { @@ -6933,8 +6933,8 @@ int main(int argc, char *argv[]) mutex_init(&sshare_lock); rwlock_init(&blk_lock); rwlock_init(&netacc_lock); - mutex_init(&mining_thr_lock); - mutex_init(&devices_lock); + rwlock_init(&mining_thr_lock); + rwlock_init(&devices_lock); mutex_init(&lp_lock); if (unlikely(pthread_cond_init(&lp_cond, NULL))) diff --git a/miner.h b/miner.h index 07918c69..5520d879 100644 --- a/miner.h +++ b/miner.h @@ -757,8 +757,8 @@ extern pthread_mutex_t cgusb_lock; extern pthread_mutex_t hash_lock; extern pthread_mutex_t console_lock; extern pthread_mutex_t ch_lock; -extern pthread_mutex_t mining_thr_lock; -extern pthread_mutex_t devices_lock; +extern pthread_rwlock_t mining_thr_lock; +extern pthread_rwlock_t devices_lock; extern pthread_mutex_t restart_lock; extern pthread_cond_t restart_cond;