Browse Source

Merge branch 'cg_merges_20130822a' into bfgminer

Luke Dashjr 12 years ago
parent
commit
e7b57d3633
3 changed files with 60 additions and 123 deletions
  1. 9 3
      configure.ac
  2. 40 115
      util.c
  3. 11 5
      util.h

+ 9 - 3
configure.ac

@@ -83,7 +83,7 @@ DLOPEN_FLAGS="-ldl"
 WS2_LIBS=""
 MM_LIBS=""
 MATH_LIBS="-lm"
-RT_LIBS="-lrt"
+RT_LIBS=""
 
 case $target in
   amd64-* | x86_64-*)
@@ -108,7 +108,6 @@ case $target in
     DLOPEN_FLAGS=""
     WS2_LIBS="-lws2_32"
     MM_LIBS="-lwinmm"
-    RT_LIBS=""
     AC_DEFINE([_WIN32_WINNT], [0x0501], "WinNT version for XP+ support")
     AC_DEFINE([FD_SETSIZE], [4096], [Maximum sockets before fd_set overflows])
     ;;
@@ -914,7 +913,14 @@ AC_TRY_COMPILE([
 ],[
 	AC_MSG_RESULT([yes])
 	AC_DEFINE([HAVE_CLOCK_GETTIME_MONOTONIC], [1], [Defined to 1 if clock_gettime(CLOCK_MONOTONIC) is defined])
-	AC_SEARCH_LIBS([clock_gettime],[rt posix4])
+	save_LIBS="${LIBS}"
+	AC_SEARCH_LIBS([clock_gettime],[rt posix4],[
+		if test "x${ac_cv_search_clock_gettime}" != "xnone required"; then
+			RT_LIBS="${ac_cv_search_clock_gettime}"
+		fi
+	])
+	LIBS="${save_LIBS}"
+	AC_CHECK_FUNCS([clock_nanosleep])
 	AC_MSG_CHECKING([for clock_gettime(CLOCK_MONOTONIC_RAW)])
 	AC_TRY_COMPILE([
 		#define _GNU_SOURCE

+ 40 - 115
util.c

@@ -1054,6 +1054,7 @@ void setup_pthread_cancel_workaround()
 #endif
 
 static void _now_gettimeofday(struct timeval *);
+static void _cgsleep_us_r_nanosleep(cgtimer_t *, int64_t);
 
 #ifdef HAVE_POOR_GETTIMEOFDAY
 static struct timeval tv_timeofday_offset;
@@ -1116,6 +1117,7 @@ void _now_is_not_set(__maybe_unused struct timeval *tv)
 }
 
 void (*timer_set_now)(struct timeval *tv) = _now_is_not_set;
+void (*cgsleep_us_r)(cgtimer_t *, int64_t) = _cgsleep_us_r_nanosleep;
 
 #ifdef HAVE_CLOCK_GETTIME_MONOTONIC
 static clockid_t bfg_timer_clk;
@@ -1133,6 +1135,22 @@ void _now_clock_gettime(struct timeval *tv)
 	};
 }
 
+#ifdef HAVE_CLOCK_NANOSLEEP
+static
+void _cgsleep_us_r_monotonic(cgtimer_t *tv_start, int64_t us)
+{
+	struct timeval tv_end[1];
+	struct timespec ts_end[1];
+	int ret;
+	
+	timer_set_delay(tv_end, tv_start, us);
+	timeval_to_spec(ts_end, tv_end);
+	do {
+		ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts_end, NULL);
+	} while (ret == EINTR);
+}
+#endif
+
 static
 bool _bfg_try_clock_gettime(clockid_t clk)
 {
@@ -1158,7 +1176,12 @@ void bfg_init_time()
 	else
 #endif
 	if (_bfg_try_clock_gettime(CLOCK_MONOTONIC))
+	{
 		applog(LOG_DEBUG, "Timers: Using clock_gettime(CLOCK_MONOTONIC)");
+#ifdef HAVE_CLOCK_NANOSLEEP
+		cgsleep_us_r = _cgsleep_us_r_monotonic;
+#endif
+	}
 	else
 #endif
 #ifdef WIN32
@@ -1254,65 +1277,7 @@ void timeraddspec(struct timespec *a, const struct timespec *b)
 	}
 }
 
-static int timespec_to_ms(struct timespec *ts)
-{
-	return ts->tv_sec * 1000 + ts->tv_nsec / 1000000;
-}
-
-/* These are cgminer specific sleep functions that use an absolute nanosecond
- * resolution timer to avoid poor usleep accuracy and overruns. */
 #ifndef WIN32
-void cgtimer_time(cgtimer_t *ts_start)
-{
-	clock_gettime(CLOCK_MONOTONIC, ts_start);
-}
-
-static void nanosleep_abstime(struct timespec *ts_end)
-{
-	int ret;
-
-	do {
-		ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts_end, NULL);
-	} while (ret == EINTR);
-}
-
-/* Reentrant version of cgsleep functions allow start time to be set separately
- * from the beginning of the actual sleep, allowing scheduling delays to be
- * counted in the sleep. */
-void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
-{
-	struct timespec ts_end;
-
-	ms_to_timespec(&ts_end, ms);
-	timeraddspec(&ts_end, ts_start);
-	nanosleep_abstime(&ts_end);
-}
-
-void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
-{
-	struct timespec ts_end;
-
-	us_to_timespec(&ts_end, us);
-	timeraddspec(&ts_end, ts_start);
-	nanosleep_abstime(&ts_end);
-}
-
-int cgtimer_to_ms(cgtimer_t *cgt)
-{
-	return timespec_to_ms(cgt);
-}
-
-/* Subtracts b from a and stores it in res. */
-void cgtimer_sub(cgtimer_t *a, cgtimer_t *b, cgtimer_t *res)
-{
-	res->tv_sec = a->tv_sec - b->tv_sec;
-	res->tv_nsec = a->tv_nsec - b->tv_nsec;
-	if (res->tv_nsec < 0) {
-		res->tv_nsec += 1000000000;
-		res->tv_sec--;
-	}
-}
-
 static
 void _now_gettimeofday(struct timeval *tv)
 {
@@ -1345,70 +1310,30 @@ void _now_gettimeofday(struct timeval *tv)
 	tv->tv_sec = lidiv.quot;
 	tv->tv_usec = lidiv.rem / 10;
 }
+#endif
 
-void cgtimer_time(cgtimer_t *ts_start)
-{
-	lldiv_t lidiv;;
-
-	decius_time(&lidiv);
-	ts_start->tv_sec = lidiv.quot;
-	ts_start->tv_nsec = lidiv.quot * 100;
-}
-
-/* Subtract b from a */
-static void timersubspec(struct timespec *a, const struct timespec *b)
-{
-	a->tv_sec -= b->tv_sec;
-	a->tv_nsec -= b->tv_nsec;
-	if (a->tv_nsec < 0) {
-		a->tv_nsec += 1000000000;
-		a->tv_sec--;
-	}
-}
-
-static void cgsleep_spec(struct timespec *ts_diff, const struct timespec *ts_start)
-{
-	struct timespec now;
-
-	timeraddspec(ts_diff, ts_start);
-	cgtimer_time(&now);
-	timersubspec(ts_diff, &now);
-	if (unlikely(ts_diff->tv_sec < 0))
-		return;
-	nanosleep(ts_diff, NULL);
-}
-
-void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
-{
-	struct timespec ts_diff;
-
-	ms_to_timespec(&ts_diff, ms);
-	cgsleep_spec(&ts_diff, ts_start);
-}
-
-void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
-{
-	struct timespec ts_diff;
-
-	us_to_timespec(&ts_diff, us);
-	cgsleep_spec(&ts_diff, ts_start);
-}
-
-int cgtimer_to_ms(cgtimer_t *cgt)
+void cgsleep_ms_r(cgtimer_t *tv_start, int ms)
 {
-	return timespec_to_ms(cgt);
+	cgsleep_us_r(tv_start, ((int64_t)ms) * 1000);
 }
 
-void cgtimer_sub(cgtimer_t *a, cgtimer_t *b, cgtimer_t *res)
+static
+void _cgsleep_us_r_nanosleep(cgtimer_t *tv_start, int64_t us)
 {
-	res->tv_sec = a->tv_sec - b->tv_sec;
-	res->tv_nsec = a->tv_nsec - b->tv_nsec;
-	if (res->tv_nsec < 0) {
-		res->tv_nsec += 1000000000;;
-		res->tv_sec--;
+	struct timeval tv_timer[1], tv[1];
+	struct timespec ts[1];
+	
+	timer_set_delay(tv_timer, tv_start, us);
+	while (true)
+	{
+		timer_set_now(tv);
+		if (!timercmp(tv_timer, tv, >))
+			return;
+		timersub(tv_timer, tv, tv);
+		timeval_to_spec(ts, tv);
+		nanosleep(ts, NULL);
 	}
 }
-#endif
 
 void cgsleep_ms(int ms)
 {

+ 11 - 5
util.h

@@ -98,7 +98,7 @@ bool isCspace(int c)
 	}
 }
 
-typedef struct timespec cgtimer_t;
+typedef struct timeval cgtimer_t;
 
 struct thr_info;
 struct pool;
@@ -132,12 +132,18 @@ void ms_to_timespec(struct timespec *spec, int64_t ms);
 void timeraddspec(struct timespec *a, const struct timespec *b);
 void cgsleep_ms(int ms);
 void cgsleep_us(int64_t us);
-void cgtimer_time(cgtimer_t *ts_start);
+#define cgtimer_time(ts_start) timer_set_now(ts_start)
 #define cgsleep_prepare_r(ts_start) cgtimer_time(ts_start)
 void cgsleep_ms_r(cgtimer_t *ts_start, int ms);
-void cgsleep_us_r(cgtimer_t *ts_start, int64_t us);
-int cgtimer_to_ms(cgtimer_t *cgt);
-void cgtimer_sub(cgtimer_t *a, cgtimer_t *b, cgtimer_t *res);
+void (*cgsleep_us_r)(cgtimer_t *ts_start, int64_t us);
+
+static inline
+int cgtimer_to_ms(cgtimer_t *cgt)
+{
+	return (cgt->tv_sec * 1000) + (cgt->tv_usec / 1000);
+}
+
+#define cgtimer_sub(a, b, res)  timersub(a, b, res)
 double us_tdiff(struct timeval *end, struct timeval *start);
 double tdiff(struct timeval *end, struct timeval *start);
 bool _stratum_send(struct pool *pool, char *s, ssize_t len, bool force);