Browse Source

Merge commit 'bc0e27c' into bfgminer

Luke Dashjr 11 years ago
parent
commit
b41a8ca2ff
4 changed files with 97 additions and 46 deletions
  1. 38 30
      miner.c
  2. 8 1
      miner.h
  3. 48 15
      util.c
  4. 3 0
      util.h

+ 38 - 30
miner.c

@@ -363,10 +363,10 @@ char *current_fullhash;
 static char datestamp[40];
 static char blocktime[32];
 time_t block_time;
-static char best_share[8] = "0";
+static char best_share[ALLOC_H2B_SHORTV] = "0";
 double current_diff = 0xFFFFFFFFFFFFFFFFULL;
-static char block_diff[8];
-static char net_hashrate[10];
+static char block_diff[ALLOC_H2B_SHORTV];
+static char net_hashrate[ALLOC_H2B_SHORT];
 double best_diff = 0;
 
 static bool known_blkheight_current;
@@ -3139,7 +3139,6 @@ enum h2bs_fmt {
 	H2B_SPACED,  // "xxx.x MH/s"
 	H2B_SHORTV,  // Like H2B_SHORT, but omit space for base unit
 };
-static const size_t h2bs_fmt_size[] = {6, 10, 11};
 
 enum bfu_floatprec {
 	FUP_INTEGER,
@@ -3195,15 +3194,24 @@ int format_unit3(char *buf, size_t sz, enum bfu_floatprec fprec, const char *mea
 			_SNP("%u", (unsigned int)hashrate);
 	}
 	
-	switch (fmt) {
-	case H2B_SPACED:
-		_SNP(" ");
-	case H2B_SHORT:
-		_SNP("%c%s", _unitchar[unit], measurement);
-	default:
-		break;
-	case H2B_SHORTV:
-		_SNP("%.1s%s", (unit == _unitbase) ? "" : &_unitchar[unit], measurement);
+	if (fmt != H2B_NOUNIT)
+	{
+		char uc[3] = {_unitchar[unit], '\0'};
+		switch (fmt) {
+			case H2B_SPACED:
+				_SNP(" ");
+			default:
+				break;
+			case H2B_SHORTV:
+				if (isspace(uc[0]))
+					uc[0] = '\0';
+		}
+		
+		if (uc[0] == '\xb5')
+			// Convert to UTF-8
+			snprintf(uc, sizeof(uc), "%s", U8_MICRO);
+		
+		_SNP("%s%s", uc, measurement);
 	}
 	
 	return rv;
@@ -3324,7 +3332,8 @@ void test_decimal_width()
 		format_unit2(testbuf1, sizeof(testbuf1), true, "x", H2B_SHORT, testn      , -1);
 		format_unit2(testbuf2, sizeof(testbuf2), true, "x", H2B_SHORT, testn * 1e3, -1);
 		format_unit2(testbuf3, sizeof(testbuf3), true, "x", H2B_SHORT, testn * 1e6, -1);
-		width = snprintf(printbuf, sizeof(printbuf), "%10g %s %s %s |", testn, testbuf1, testbuf2, testbuf3);
+		snprintf(printbuf, sizeof(printbuf), "%10g %s %s %s |", testn, testbuf1, testbuf2, testbuf3);
+		width = utf8_strlen(printbuf);
 		if (unlikely((saved != -1) && (width != saved))) {
 			applog(LOG_ERR, "Test width mismatch in format_unit2! %d not %d at %10g", width, saved, testn);
 			applog(LOG_ERR, "%s", printbuf);
@@ -3339,7 +3348,8 @@ void test_decimal_width()
 		format_unit2(testbuf2, sizeof(testbuf2), true, "x", H2B_SHORT, testn * 1e3, -1);
 		format_unit2(testbuf3, sizeof(testbuf3), true, "x", H2B_SHORT, testn * 1e6, -1);
 		format_unit2(testbuf4, sizeof(testbuf4), true, "x", H2B_SHORT, testn * 1e9, -1);
-		width = snprintf(printbuf, sizeof(printbuf), "%10g %s %s %s %s |", testn, testbuf1, testbuf2, testbuf3, testbuf4);
+		snprintf(printbuf, sizeof(printbuf), "%10g %s %s %s %s |", testn, testbuf1, testbuf2, testbuf3, testbuf4);
+		width = utf8_strlen(printbuf);
 		if (unlikely((saved != -1) && (width != saved))) {
 			applog(LOG_ERR, "Test width mismatch in pick_unit! %d not %d at %10g", width, saved, testn);
 			applog(LOG_ERR, "%s", printbuf);
@@ -3428,7 +3438,7 @@ void get_statline3(char *buf, size_t bufsz, struct cgpu_info *cgpu, bool for_cur
 #endif
 	struct device_drv *drv = cgpu->drv;
 	enum h2bs_fmt hashrate_style = for_curses ? H2B_SHORT : H2B_SPACED;
-	char cHr[h2bs_fmt_size[H2B_NOUNIT]], aHr[h2bs_fmt_size[H2B_NOUNIT]], uHr[h2bs_fmt_size[hashrate_style]];
+	char cHr[ALLOC_H2B_NOUNIT+1], aHr[ALLOC_H2B_NOUNIT+1], uHr[max(ALLOC_H2B_SHORT, ALLOC_H2B_SPACED)+3+1];
 	char rejpcbuf[6];
 	char bnbuf[6];
 	double dev_runtime;
@@ -3484,7 +3494,7 @@ void get_statline3(char *buf, size_t bufsz, struct cgpu_info *cgpu, bool for_cur
 	
 	multi_format_unit_array2(
 		((char*[]){cHr, aHr, uHr}),
-		((size_t[]){h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[hashrate_style]}),
+		((size_t[]){sizeof(cHr), sizeof(aHr), sizeof(uHr)}),
 		true, "h/s", hashrate_style,
 		3,
 		1e6*rolling,
@@ -3650,17 +3660,15 @@ void bfg_waddstr(WINDOW *win, const char *s)
 		if (p != s)
 			waddnstr(win, s, p - s);
 		w = utf8_decode(p, &wlen);
-		if (unlikely(p[0] == '\xb5'))  // HACK for Mu (SI prefix micro-)
-		{
-			w = unicode_micro;
-			wlen = 1;
-		}
 		s = p += wlen;
 		switch(w)
 		{
 			// NOTE: U+F000-U+F7FF are reserved for font hacks
 			case '\0':
 				return;
+			case 0xb5:  // micro symbol
+				w = unicode_micro;
+				goto default_addch;
 			case 0xf000:  // "bad" off
 				wattroff(win, attr_bad);
 				break;
@@ -3687,6 +3695,7 @@ void bfg_waddstr(WINDOW *win, const char *s)
 				if (w > WCHAR_MAX || !iswprint(w))
 					w = '*';
 			default:
+default_addch:
 				if (w > WCHAR_MAX || !(iswprint(w) || w == '\n'))
 				{
 #if REPLACEMENT_CHAR <= WCHAR_MAX
@@ -3877,7 +3886,7 @@ one_workable_pool: ;
 		  current_hash, block_diff, net_hashrate, blocktime);
 	
 	income = total_diff_accepted * 3600 * block_subsidy / total_secs / current_diff;
-	char bwstr[12], incomestr[13];
+	char bwstr[(ALLOC_H2B_SHORT*2)+3+1], incomestr[ALLOC_H2B_SHORT+6+1];
 	format_unit3(incomestr, sizeof(incomestr), FUP_BTC, "BTC/hr", H2B_SHORT, income/1e8, -1);
 	cg_mvwprintw(statuswin, 4, 0, " ST:%d  F:%d  NB:%d  AS:%d  BW:[%s]  E:%.2f  I:%s  BS:%s",
 		ts,
@@ -4182,9 +4191,9 @@ static
 void share_result_msg(const struct work *work, const char *disp, const char *reason, bool resubmit, const char *worktime) {
 	struct cgpu_info *cgpu;
 	const unsigned char *hashpart = &work->hash[opt_scrypt ? 26 : 24];
-	char shrdiffdisp[16];
+	char shrdiffdisp[ALLOC_H2B_SHORTV];
 	const double tgtdiff = work->work_difficulty;
-	char tgtdiffdisp[16];
+	char tgtdiffdisp[ALLOC_H2B_SHORTV];
 	char where[20];
 	
 	cgpu = get_thr_cgpu(work->thr_id);
@@ -6505,7 +6514,7 @@ static bool input_pool(bool live);
 static void display_pool_summary(struct pool *pool)
 {
 	double efficiency = 0.0;
-	char xfer[17], bw[19];
+	char xfer[ALLOC_H2B_NOUNIT+ALLOC_H2B_SPACED+4+1], bw[ALLOC_H2B_NOUNIT+ALLOC_H2B_SPACED+6+1];
 	int pool_secs;
 
 	if (curses_active_locked()) {
@@ -6763,7 +6772,6 @@ void zero_bestshare(void)
 	int i;
 
 	best_diff = 0;
-	memset(best_share, 0, 8);
 	suffix_string(best_diff, best_share, sizeof(best_share), 0);
 
 	for (i = 0; i < total_pools; i++) {
@@ -7705,7 +7713,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 	static double local_mhashes_done = 0;
 	double local_mhashes = (double)hashes_done / 1000000.0;
 	bool showlog = false;
-	char cHr[h2bs_fmt_size[H2B_NOUNIT]], aHr[h2bs_fmt_size[H2B_NOUNIT]], uHr[h2bs_fmt_size[H2B_SPACED]];
+	char cHr[ALLOC_H2B_NOUNIT+1], aHr[ALLOC_H2B_NOUNIT+1], uHr[ALLOC_H2B_SPACED+3+1];
 	char rejpcbuf[6];
 	char bnbuf[6];
 	struct thr_info *thr;
@@ -7788,7 +7796,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 	
 	multi_format_unit_array2(
 		((char*[]){cHr, aHr, uHr}),
-		((size_t[]){h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[H2B_NOUNIT], h2bs_fmt_size[H2B_SPACED]}),
+		((size_t[]){sizeof(cHr), sizeof(aHr), sizeof(uHr)}),
 		true, "h/s", H2B_SHORT,
 		3,
 		1e6*total_rolling,
@@ -10166,7 +10174,7 @@ void print_summary(void)
 	struct timeval diff;
 	int hours, mins, secs, i;
 	double utility, efficiency = 0.0;
-	char xfer[17], bw[19];
+	char xfer[(ALLOC_H2B_SPACED*2)+4+1], bw[(ALLOC_H2B_SPACED*2)+6+1];
 	int pool_secs;
 
 	timersub(&total_tv_end, &total_tv_start, &diff);

+ 8 - 1
miner.h

@@ -436,9 +436,16 @@ struct cgminer_pool_stats {
 	uint64_t net_bytes_received;
 };
 
+
 #define PRIprepr "-6s"
 #define PRIpreprv "s"
 
+#define ALLOC_H2B_NOUNIT  6
+#define ALLOC_H2B_SHORT   7
+#define ALLOC_H2B_SPACED  8
+#define ALLOC_H2B_SHORTV  7
+
+
 struct cgpu_info {
 	int cgminer_id;
 	int device_line_id;
@@ -1162,7 +1169,7 @@ struct pool {
 	int seq_getfails;
 	int solved;
 	double diff1;
-	char diff[8];
+	char diff[ALLOC_H2B_SHORTV];
 	int quota;
 	int quota_gcd;
 	int quota_used;

+ 48 - 15
util.c

@@ -1394,33 +1394,36 @@ double tdiff(struct timeval *end, struct timeval *start)
 }
 
 
+int utf8_len(const uint8_t b)
+{
+	if (!(b & 0x80))
+		return 1;
+	if (!(b & 0x20))
+		return 2;
+	else
+	if (!(b & 0x10))
+		return 3;
+	else
+		return 4;
+}
+
 int32_t utf8_decode(const void *b, int *out_len)
 {
 	int32_t w;
 	const unsigned char *s = b;
 	
-	if (!(s[0] & 0x80))
-	{
+	*out_len = utf8_len(s[0]);
+	
+	if (*out_len == 1)
 		// ASCII
-		*out_len = 1;
 		return s[0];
-	}
 	
 #ifdef STRICT_UTF8
 	if (unlikely(!(s[0] & 0x40)))
 		goto invalid;
-#endif
-	
-	if (!(s[0] & 0x20))
-		*out_len = 2;
-	else
-	if (!(s[0] & 0x10))
-		*out_len = 3;
-	else
-	if (likely(!(s[0] & 8)))
-		*out_len = 4;
-	else
+	if (unlikely(s[0] & 0x38 == 0x38))
 		goto invalid;
+#endif
 	
 	w = s[0] & ((2 << (6 - *out_len)) - 1);
 	for (int i = 1; i < *out_len; ++i)
@@ -1441,9 +1444,28 @@ int32_t utf8_decode(const void *b, int *out_len)
 	
 	return w;
 
+#ifdef STRICT_UTF8
 invalid:
 	*out_len = 1;
 	return REPLACEMENT_CHAR;
+#endif
+}
+
+size_t utf8_strlen(const void * const b)
+{
+	const uint8_t *s = b;
+	size_t c = 0;
+	int clen, i;
+	while (s[0])
+	{
+		clen = utf8_len(s[0]);
+		for (i = 0; i < clen; ++i)
+			if (!s[i])
+				clen = 1;
+		++c;
+		s += clen;
+	}
+	return c;
 }
 
 static
@@ -1452,6 +1474,17 @@ void _utf8_test(const char *s, const wchar_t expected, int expectedlen)
 	int len;
 	wchar_t r;
 	
+	if (expected != REPLACEMENT_CHAR)
+	{
+		len = utf8_len(((uint8_t*)s)[0]);
+		if (len != expectedlen)
+			applog(LOG_ERR, "UTF-8 test U+%06lX (len %d) failed: got utf8_len=>%d", (unsigned long)expected, expectedlen, len);
+		len = utf8_strlen(s);
+		if (len != (s[0] ? 1 : 0))
+			applog(LOG_ERR, "UTF-8 test U+%06lX (len %d) failed: got utf8_strlen=>%d", (unsigned long)expected, expectedlen, len);
+		len = -1;
+	}
+	
 	r = utf8_decode(s, &len);
 	if (unlikely(r != expected || expectedlen != len))
 		applog(LOG_ERR, "UTF-8 test U+%06lX (len %d) failed: got U+%06lX (len %d)", (unsigned long)expected, expectedlen, (unsigned long)r, len);

+ 3 - 0
util.h

@@ -480,9 +480,12 @@ struct timeval *select_timeout(struct timeval *tvp_timeout, struct timeval *tvp_
 
 #define REPLACEMENT_CHAR (0xFFFD)
 #define U8_DEGREE "\xc2\xb0"
+#define U8_MICRO  "\xc2\xb5"
 #define U8_HLINE  "\xe2\x94\x80"
 #define U8_BTEE   "\xe2\x94\xb4"
+extern int utf8_len(uint8_t);
 extern int32_t utf8_decode(const void *, int *out_len);
+extern size_t utf8_strlen(const void *);
 extern void utf8_test();