Commit 78d5a81d70ce3fa66257c8842ffd7729919d7576

Paul Sheppard 2012-06-26T12:32:09

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

diff --git a/cgminer.c b/cgminer.c
index 21f3f1e..dbbc045 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -69,9 +69,7 @@ enum workio_commands {
 struct workio_cmd {
 	enum workio_commands	cmd;
 	struct thr_info		*thr;
-	union {
-		struct work	*work;
-	} u;
+	struct work		*work;
 	bool			lagging;
 };
 
@@ -1906,7 +1904,7 @@ static void workio_cmd_free(struct workio_cmd *wc)
 
 	switch (wc->cmd) {
 	case WC_SUBMIT_WORK:
-		free_work(wc->u.work);
+		free_work(wc->work);
 		break;
 	default: /* do nothing */
 		break;
@@ -2166,22 +2164,26 @@ static bool stale_work(struct work *work, bool share)
 	if (work->mandatory)
 		return false;
 
-	if (share)
-		work_expiry = opt_expiry;
-	else if (work->rolltime)
-		work_expiry = work->rolltime;
-	else
-		work_expiry = opt_scantime;
+	if (share) {
+		if (work->rolltime)
+			work_expiry = work->rolltime;
+		else
+			work_expiry = opt_expiry;
+	} else {
+		/* Don't keep rolling work right up to the expiration */
+		if (work->rolltime > opt_scantime)
+			work_expiry = (work->rolltime - opt_scantime) * 2 / 3 + opt_scantime;
+		else /* Shouldn't happen unless someone increases scantime */
+			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;
+	work_expiry -= getwork_delay;
+	if (unlikely(work_expiry < 5))
+		work_expiry = 5;
 
 	gettimeofday(&now, NULL);
 	if ((now.tv_sec - work->tv_staged.tv_sec) >= work_expiry)
@@ -2213,7 +2215,7 @@ static void check_solve(struct work *work)
 static void *submit_work_thread(void *userdata)
 {
 	struct workio_cmd *wc = (struct workio_cmd *)userdata;
-	struct work *work = wc->u.work;
+	struct work *work = wc->work;
 	struct pool *pool = work->pool;
 	struct curl_ent *ce;
 	int failures = 0;
@@ -3845,11 +3847,11 @@ bool submit_work_sync(struct thr_info *thr, const struct work *work_in)
 		return false;
 	}
 
-	wc->u.work = make_work();
+	wc->work = make_work();
 	wc->cmd = WC_SUBMIT_WORK;
 	wc->thr = thr;
-	memcpy(wc->u.work, work_in, sizeof(*work_in));
-	wc->u.work->share_found_time = time(NULL);
+	memcpy(wc->work, work_in, sizeof(*work_in));
+	wc->work->share_found_time = time(NULL);
 
 	applog(LOG_DEBUG, "Pushing submit work to work thread");
 
diff --git a/driver-opencl.c b/driver-opencl.c
index 17be40a..90606fa 100644
--- a/driver-opencl.c
+++ b/driver-opencl.c
@@ -1346,6 +1346,7 @@ static uint64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 	struct cgpu_info *gpu = thr->cgpu;
 	_clState *clState = clStates[thr_id];
 	const cl_kernel *kernel = &clState->kernel;
+	const int dynamic_us = opt_dynamic_interval * 1000;
 
 	cl_int status;
 	size_t globalThreads[1];
@@ -1353,28 +1354,29 @@ static uint64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 	unsigned int threads;
 	unsigned int hashes;
 
-	gettimeofday(&gpu->tv_gpustart, NULL);
 	/* This finish flushes the readbuffer set with CL_FALSE later */
 	clFinish(clState->commandQueue);
 	gettimeofday(&gpu->tv_gpuend, NULL);
 
 	if (gpu->dynamic) {
 		struct timeval diff;
-		suseconds_t gpu_ms;
+		suseconds_t gpu_us;
 
 		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->gpu_ms_average > opt_dynamic_interval) {
-			if (gpu->intensity > MIN_INTENSITY)
-				--gpu->intensity;
-		} else if (gpu->gpu_ms_average < ((opt_dynamic_interval / 2) ? : 1)) {
-			if (gpu->intensity < MAX_INTENSITY)
-				++gpu->intensity;
+		gpu_us = diff.tv_sec * 1000000 + diff.tv_usec;
+		if (likely(gpu_us > 0)) {
+			gpu->gpu_us_average = (gpu->gpu_us_average + gpu_us * 0.63) / 1.63;
+
+			/* Try to not let the GPU be out for longer than 
+			 * opt_dynamic_interval in ms, but increase
+			 * intensity when the system is idle in dynamic mode */
+			if (gpu->gpu_us_average > dynamic_us) {
+				if (gpu->intensity > MIN_INTENSITY)
+					--gpu->intensity;
+			} else if (gpu->gpu_us_average < dynamic_us / 2) {
+				if (gpu->intensity < MAX_INTENSITY)
+					++gpu->intensity;
+			}
 		}
 	}
 	set_threads_hashes(clState->vwidth, &threads, &hashes, globalThreads,
@@ -1408,6 +1410,8 @@ static uint64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 		clFinish(clState->commandQueue);
 	}
 
+	gettimeofday(&gpu->tv_gpustart, NULL);
+
 	if (clState->goffset) {
 		size_t global_work_offset[1];
 
diff --git a/driver-ztex.c b/driver-ztex.c
index e38be74..db22392 100644
--- a/driver-ztex.c
+++ b/driver-ztex.c
@@ -63,7 +63,8 @@ static void ztex_detect(void)
 	struct cgpu_info *ztex;
 
 	cnt = libztex_scanDevices(&ztex_devices);
-	applog(LOG_WARNING, "Found %d ztex board(s)", cnt);
+	if (cnt > 0)
+		applog(LOG_WARNING, "Found %d ztex board%s", cnt, cnt > 1 ? "s" : "");
 
 	for (i = 0; i < cnt; i++) {
 		ztex = calloc(1, sizeof(struct cgpu_info));
diff --git a/fpgautils.c b/fpgautils.c
index 59eb7bc..12e3847 100644
--- a/fpgautils.c
+++ b/fpgautils.c
@@ -15,6 +15,7 @@
 #include <string.h>
 
 #ifndef WIN32
+#include <errno.h>
 #include <termios.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -148,7 +149,21 @@ serial_open(const char*devpath, unsigned long baud, signed short timeout, bool p
 #ifdef WIN32
 	HANDLE hSerial = CreateFile(devpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
 	if (unlikely(hSerial == INVALID_HANDLE_VALUE))
+	{
+		DWORD e = GetLastError();
+		switch (e) {
+		case ERROR_ACCESS_DENIED:
+			applog(LOG_ERR, "Do not have user privileges required to open %s", devpath);
+			break;
+		case ERROR_SHARING_VIOLATION:
+			applog(LOG_ERR, "%s is already in use by another process", devpath);
+			break;
+		default:
+			applog(LOG_DEBUG, "Open %s failed, GetLastError:%u", devpath, e);
+			break;
+		}
 		return -1;
+	}
 
 	// thanks to af_newbie for pointers about this
 	COMMCONFIG comCfg = {0};
@@ -179,15 +194,28 @@ serial_open(const char*devpath, unsigned long baud, signed short timeout, bool p
 	int fdDev = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY);
 
 	if (unlikely(fdDev == -1))
+	{
+		if (errno == EACCES)
+			applog(LOG_ERR, "Do not have user privileges required to open %s", devpath);
+		else
+			applog(LOG_DEBUG, "Open %s failed, errno:%d", devpath, errno);
+
 		return -1;
+	}
 
 	struct termios my_termios;
 
 	tcgetattr(fdDev, &my_termios);
 
 	switch (baud) {
-	case 0: break;
-	case 115200: my_termios.c_cflag = B115200; break;
+	case 0:
+		break;
+	case 115200:
+		my_termios.c_cflag &= ~CBAUD;
+		my_termios.c_cflag |= B115200;
+		break;
+	// TODO: try some higher speeds with the Icarus and BFL to see
+	// if they support them and if setting them makes any difference
 	default:
 		applog(LOG_WARNING, "Unrecognized baud rate: %lu", baud);
 	}
diff --git a/miner.h b/miner.h
index 42ded10..9347d19 100644
--- a/miner.h
+++ b/miner.h
@@ -351,7 +351,7 @@ struct cgpu_info {
 
 	struct timeval tv_gpustart;;
 	struct timeval tv_gpuend;
-	double gpu_ms_average;
+	double gpu_us_average;
 #endif
 
 	float temp;