From 1ec3d69b0ed8cc7a3eba0192685034d5442989e4 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 16 Sep 2010 09:35:34 +0200 Subject: [PATCH] Implement a better num2str() Signed-off-by: Jens Axboe --- Makefile | 1 + Makefile.FreeBSD | 1 + Makefile.NetBSD | 1 + Makefile.aix | 1 + Makefile.mac | 1 + Makefile.solaris | 1 + fio.h | 45 ++------------------------------------------- lib/num2str.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 56 insertions(+), 43 deletions(-) create mode 100644 lib/num2str.c diff --git a/Makefile b/Makefile index 13baee83..04cb60fa 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ OBJS += lib/rand.o OBJS += lib/flist_sort.o +OBJS += lib/num2str.o OBJS += crc/crc7.o OBJS += crc/crc16.o diff --git a/Makefile.FreeBSD b/Makefile.FreeBSD index 5882961a..e4adfca5 100644 --- a/Makefile.FreeBSD +++ b/Makefile.FreeBSD @@ -10,6 +10,7 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ OBJS += lib/rand.o OBJS += lib/flist_sort.o +OBJS += lib/num2str.o OBJS += crc/crc7.o OBJS += crc/crc16.o diff --git a/Makefile.NetBSD b/Makefile.NetBSD index c223ab2e..9378b195 100644 --- a/Makefile.NetBSD +++ b/Makefile.NetBSD @@ -10,6 +10,7 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ OBJS += lib/rand.o OBJS += lib/flist_sort.o +OBJS += lib/num2str.o OBJS += crc/crc7.o OBJS += crc/crc16.o diff --git a/Makefile.aix b/Makefile.aix index 83b5cf4d..32d22a33 100644 --- a/Makefile.aix +++ b/Makefile.aix @@ -11,6 +11,7 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ OBJS += lib/rand.o OBJS += lib/getopt_long.o +OBJS += lib/num2str.o OBJS += crc/crc7.o OBJS += crc/crc16.o diff --git a/Makefile.mac b/Makefile.mac index 77e5f035..952364ae 100644 --- a/Makefile.mac +++ b/Makefile.mac @@ -10,6 +10,7 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ OBJS += lib/rand.o OBJS += lib/flist_sort.o +OBJS += lib/num2str.o OBJS += crc/crc7.o OBJS += crc/crc16.o diff --git a/Makefile.solaris b/Makefile.solaris index 06020c26..e7ff53cb 100644 --- a/Makefile.solaris +++ b/Makefile.solaris @@ -9,6 +9,7 @@ OBJS = gettime.o fio.o ioengines.o init.o stat.o log.o time.o filesetup.o \ OBJS += lib/rand.o OBJS += lib/flist_sort.o +OBJS += lib/num2str.o OBJS += crc/crc7.o OBJS += crc/crc16.o diff --git a/fio.h b/fio.h index e8c025d6..28104cd8 100644 --- a/fio.h +++ b/fio.h @@ -568,6 +568,8 @@ extern void options_mem_dupe(struct thread_data *); extern void options_mem_free(struct thread_data *); extern void td_fill_rand_seeds(struct thread_data *); extern void add_job_opts(const char **); +extern char *num2str(unsigned long, int, int, int); + #define FIO_GETOPT_JOB 0x89988998 #define FIO_NR_OPTIONS (FIO_MAX_OPTS + 128) @@ -653,49 +655,6 @@ static inline int fio_fill_issue_time(struct thread_data *td) return 0; } -/* - * Cheesy number->string conversion, complete with carry rounding error. - */ -static inline char *num2str(unsigned long num, int maxlen, int base, int pow2) -{ - char postfix[] = { ' ', 'K', 'M', 'G', 'P', 'E' }; - unsigned int thousand; - char *buf; - int i; - - if (pow2) - thousand = 1024; - else - thousand = 1000; - - buf = malloc(128); - - for (i = 0; base > 1; i++) - base /= thousand; - - do { - int len, carry = 0; - - len = sprintf(buf, "%'lu", num); - if (len <= maxlen) { - if (i >= 1) { - buf[len] = postfix[i]; - buf[len + 1] = '\0'; - } - return buf; - } - - if ((num % thousand) >= (thousand / 2)) - carry = 1; - - num /= thousand; - num += carry; - i++; - } while (i <= 5); - - return buf; -} - static inline int __should_check_rate(struct thread_data *td, enum fio_ddir ddir) { diff --git a/lib/num2str.c b/lib/num2str.c new file mode 100644 index 00000000..e114cdf8 --- /dev/null +++ b/lib/num2str.c @@ -0,0 +1,48 @@ +#include +#include +#include + +/* + * Cheesy number->string conversion, complete with carry rounding error. + */ +char *num2str(unsigned long num, int maxlen, int base, int pow2) +{ + char postfix[] = { ' ', 'K', 'M', 'G', 'P', 'E' }; + unsigned int thousand[] = { 1000, 1024 }; + unsigned int modulo, decimals; + int post_index; + char tmp[32], fmt[8]; + char *buf; + + buf = malloc(128); + + for (post_index = 0; base > 1; post_index++) + base /= thousand[!!pow2]; + + modulo = -1U; + while (post_index < sizeof(postfix)) { + sprintf(tmp, "%lu", num); + if (strlen(tmp) <= maxlen) + break; + + modulo = num % thousand[!!pow2]; + num /= thousand[!!pow2]; + post_index++; + } + + if (modulo == -1U) { +done: + sprintf(buf, "%lu%c", num, postfix[post_index]); + return buf; + } + + sprintf(tmp, "%lu", num); + decimals = maxlen - strlen(tmp); + if (decimals <= 1) + goto done; + + sprintf(fmt, "%%.%uu", decimals - 1); + sprintf(tmp, fmt, modulo); + sprintf(buf, "%lu.%s%c", num, tmp, postfix[post_index]); + return buf; +} -- 2.25.1