diff --git a/README b/README index 7c411d90..0cb57209 100644 --- a/README +++ b/README @@ -749,8 +749,19 @@ The list of requests - a (*) means it requires privileged access - and replies a to the API and success if you do have privilege The command doesn't change anything in cgminer -When you enable, disable or restart a GPU, you will also get Thread messages in -the cgminer status window + pgaenable|N (*) + none There is no reply section just the STATUS section + stating the results of the enable request + You cannot enable a PGA if it's status is not WELL + This is only available if PGA mining is enabled + + pgadisable|N (*) + none There is no reply section just the STATUS section + stating the results of the disable request + This is only available if PGA mining is enabled + +When you enable, disable or restart a GPU or PGA, you will also get Thread messages +in the cgminer status window When you switch to a different pool to the current one, you will get a 'Switching to URL' message in the cgminer status windows diff --git a/api.c b/api.c index 1879c38f..953b1938 100644 --- a/api.c +++ b/api.c @@ -329,6 +329,14 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_NUMPGA 59 #define MSG_NOTIFY 60 +#if defined(USE_BITFORCE) || defined(USE_ICARUS) +#define MSG_PGALRENA 61 +#define MSG_PGALRDIS 62 +#define MSG_PGAENA 63 +#define MSG_PGADIS 64 +#define MSG_PGAUNW 65 +#endif + enum code_severity { SEVERITY_ERR, SEVERITY_WARN, @@ -400,6 +408,11 @@ struct CODES { { SEVERITY_ERR, MSG_PGANON, PARAM_NONE, "No PGAs" }, { SEVERITY_SUCC, MSG_PGADEV, PARAM_PGA, "PGA%d" }, { SEVERITY_ERR, MSG_INVPGA, PARAM_PGAMAX, "Invalid PGA id %d - range is 0 - %d" }, + { SEVERITY_INFO, MSG_PGALRENA,PARAM_PGA, "PGA %d already enabled" }, + { SEVERITY_INFO, MSG_PGALRDIS,PARAM_PGA, "PGA %d already disabled" }, + { SEVERITY_INFO, MSG_PGAENA, PARAM_PGA, "PGA %d sent enable message" }, + { SEVERITY_INFO, MSG_PGADIS, PARAM_PGA, "PGA %d set disable flag" }, + { SEVERITY_ERR, MSG_PGAUNW, PARAM_PGA, "PGA %d is not flagged WELL, cannot enable" }, #endif #ifdef WANT_CPUMINE { SEVERITY_ERR, MSG_CPUNON, PARAM_NONE, "No CPUs" }, @@ -955,6 +968,99 @@ static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson) if (isjson) strcat(io_buffer, JSON_CLOSE); } + +static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) +{ + int numpga = numpgas(); + struct thr_info *thr; + int pga; + int id; + int i; + + if (numpga == 0) { + strcpy(io_buffer, message(MSG_PGANON, 0, NULL, isjson)); + return; + } + + if (param == NULL || *param == '\0') { + strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + return; + } + + id = atoi(param); + if (id < 0 || id >= numpga) { + strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + return; + } + + int dev = pgadevice(id); + if (dev < 0) { // Should never happen + strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + return; + } + + struct cgpu_info *cgpu = devices[dev]; + + if (cgpu->deven != DEV_DISABLED) { + strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson)); + return; + } + + if (cgpu->status != LIFE_WELL) { + strcpy(io_buffer, message(MSG_PGAUNW, id, NULL, isjson)); + return; + } + + for (i = 0; i < mining_threads; i++) { + pga = thr_info[i].cgpu->device_id; + if (pga == dev) { + thr = &thr_info[i]; + cgpu->deven = DEV_ENABLED; + tq_push(thr->q, &ping); + } + } + + strcpy(io_buffer, message(MSG_PGAENA, id, NULL, isjson)); +} + +static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) +{ + int numpga = numpgas(); + int id; + + if (numpga == 0) { + strcpy(io_buffer, message(MSG_PGANON, 0, NULL, isjson)); + return; + } + + if (param == NULL || *param == '\0') { + strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + return; + } + + id = atoi(param); + if (id < 0 || id >= numpga) { + strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + return; + } + + int dev = pgadevice(id); + if (dev < 0) { // Should never happen + strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + return; + } + + struct cgpu_info *cgpu = devices[dev]; + + if (cgpu->deven == DEV_DISABLED) { + strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson)); + return; + } + + cgpu->deven = DEV_DISABLED; + + strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); +} #endif #ifdef WANT_CPUMINE @@ -1720,6 +1826,8 @@ struct CMDS { { "gpu", gpudev, false }, #if defined(USE_BITFORCE) || defined(USE_ICARUS) { "pga", pgadev, false }, + { "pgaenable", pgaenable, true }, + { "pgadisable", pgadisable, true }, #endif #ifdef WANT_CPUMINE { "cpu", cpudev, false }, diff --git a/cgminer.c b/cgminer.c index c99999f9..dcb506e8 100644 --- a/cgminer.c +++ b/cgminer.c @@ -221,6 +221,7 @@ static int include_count = 0; #if defined(unix) static char *opt_stderr_cmd = NULL; + static int forkpid = 0; #endif // defined(unix) bool ping = true; @@ -4121,6 +4122,13 @@ void quit(int status, const char *format, ...) fprintf(stderr, "\n"); fflush(stderr); +#if defined(unix) + if (forkpid > 0) { + kill(forkpid, SIGTERM); + forkpid = 0; + } +#endif + exit(status); } @@ -4265,14 +4273,14 @@ out: } // Fork a child process - r = fork(); - if (r<0) { + forkpid = fork(); + if (forkpid<0) { perror("fork - failed to fork child process for --monitor"); exit(1); } // Child: launch monitor command - if (0==r) { + if (0==forkpid) { // Make stdin read end of pipe r = dup2(pfd[0], 0); if (r<0) { @@ -4839,5 +4847,12 @@ begin_bench: free(block); } +#if defined(unix) + if (forkpid > 0) { + kill(forkpid, SIGTERM); + forkpid = 0; + } +#endif + return 0; } diff --git a/miner.h b/miner.h index f244e819..cdcb44c9 100644 --- a/miner.h +++ b/miner.h @@ -507,7 +507,7 @@ extern int add_pool_details(bool live, char *url, char *user, char *pass); #define ADD_POOL_OK 0 #define MAX_GPUDEVICES 16 -#define MAX_DEVICES 32 +#define MAX_DEVICES 64 #define MAX_POOLS (32) #define MIN_INTENSITY -10