public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org, Tejun Heo <tj@kernel.org>
Subject: [PATCH 01/12] bitmap: restructure bitmap_sn[list]printf()
Date: Wed, 10 Dec 2014 10:52:43 -0500	[thread overview]
Message-ID: <1418226774-30215-2-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1418226774-30215-1-git-send-email-tj@kernel.org>

bitmap_sn[list]printf() implement formatting a bitmap into the
specified string buffer.  We want to add functions which target a
different output (printk).  To enable that, this patch restructures
bitmap_sn[list]printf() so that the formatting and outputting are
separate.

Formatting is now handled by bitmap_print[_list]() and
bitmap_sn[list]printf() wrap the formatting functions with the output
callback bitmap_scnprintf_fn() which fills the string buffer.  A later
patch will implement bitmap_pr_cont[_list]() by adding a different
outputting callback.

This patch doesn't change the behaviors of bitmap_sn[list]printf().

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 lib/bitmap.c | 113 ++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 73 insertions(+), 40 deletions(-)

diff --git a/lib/bitmap.c b/lib/bitmap.c
index 324ea9e..f1d6351 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -372,25 +372,33 @@ EXPORT_SYMBOL(bitmap_find_next_zero_area_off);
  * second version by Paul Jackson, third by Joe Korty.
  */
 
+struct bitmap_scnprintf_data {
+	char		*buf;
+	unsigned int	buflen;
+	unsigned int	len;
+};
+
+typedef __printf(2, 3) void (*bitmap_printfn_t)(void *data, const char *fmt, ...);
+
+static void bitmap_scnprintf_fn(void *data, const char *fmt, ...)
+{
+	struct bitmap_scnprintf_data *bsd = data;
+	va_list args;
+
+	va_start(args, fmt);
+	bsd->len += vscnprintf(bsd->buf + bsd->len, bsd->buflen - bsd->len,
+			       fmt, args);
+	va_end(args);
+}
+
 #define CHUNKSZ				32
 #define nbits_to_hold_value(val)	fls(val)
 #define BASEDEC 10		/* fancier cpuset lists input in decimal */
 
-/**
- * bitmap_scnprintf - convert bitmap to an ASCII hex string.
- * @buf: byte buffer into which string is placed
- * @buflen: reserved size of @buf, in bytes
- * @maskp: pointer to bitmap to convert
- * @nmaskbits: size of bitmap, in bits
- *
- * Exactly @nmaskbits bits are displayed.  Hex digits are grouped into
- * comma-separated sets of eight digits per set.  Returns the number of
- * characters which were written to *buf, excluding the trailing \0.
- */
-int bitmap_scnprintf(char *buf, unsigned int buflen,
-	const unsigned long *maskp, int nmaskbits)
+static void bitmap_print(const unsigned long *maskp, int nmaskbits,
+			 bitmap_printfn_t printfn, void *printfn_data)
 {
-	int i, word, bit, len = 0;
+	int i, word, bit;
 	unsigned long val;
 	const char *sep = "";
 	int chunksz;
@@ -406,12 +414,30 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
 		word = i / BITS_PER_LONG;
 		bit = i % BITS_PER_LONG;
 		val = (maskp[word] >> bit) & chunkmask;
-		len += scnprintf(buf+len, buflen-len, "%s%0*lx", sep,
-			(chunksz+3)/4, val);
+		printfn(printfn_data, "%s%0*lx", sep, (chunksz+3)/4, val);
 		chunksz = CHUNKSZ;
 		sep = ",";
 	}
-	return len;
+}
+
+/**
+ * bitmap_scnprintf - convert bitmap to an ASCII hex string.
+ * @buf: byte buffer into which string is placed
+ * @buflen: reserved size of @buf, in bytes
+ * @maskp: pointer to bitmap to convert
+ * @nmaskbits: size of bitmap, in bits
+ *
+ * Exactly @nmaskbits bits are displayed.  Hex digits are grouped into
+ * comma-separated sets of eight digits per set.  Returns the number of
+ * characters which were written to *buf, excluding the trailing \0.
+ */
+int bitmap_scnprintf(char *buf, unsigned int buflen,
+		     const unsigned long *maskp, int nmaskbits)
+{
+	struct bitmap_scnprintf_data bsd = { .buf = buf, .buflen = buflen };
+
+	bitmap_print(maskp, nmaskbits, bitmap_scnprintf_fn, &bsd);
+	return bsd.len;
 }
 EXPORT_SYMBOL(bitmap_scnprintf);
 
@@ -531,20 +557,37 @@ EXPORT_SYMBOL(bitmap_parse_user);
 /*
  * bscnl_emit(buf, buflen, rbot, rtop, bp)
  *
- * Helper routine for bitmap_scnlistprintf().  Write decimal number
- * or range to buf, suppressing output past buf+buflen, with optional
- * comma-prefix.  Return len of what was written to *buf, excluding the
- * trailing \0.
+ * Helper routine for bitmap_scnlistprintf().  Write decimal number or
+ * range to buf, with optional comma-prefix.
  */
-static inline int bscnl_emit(char *buf, int buflen, int rbot, int rtop, int len)
+static inline void bscnl_emit(int rbot, int rtop, bool first,
+			      bitmap_printfn_t printfn, void *printfn_data)
 {
-	if (len > 0)
-		len += scnprintf(buf + len, buflen - len, ",");
+	if (!first)
+		printfn(printfn_data, ",");
 	if (rbot == rtop)
-		len += scnprintf(buf + len, buflen - len, "%d", rbot);
+		printfn(printfn_data, "%d", rbot);
 	else
-		len += scnprintf(buf + len, buflen - len, "%d-%d", rbot, rtop);
-	return len;
+		printfn(printfn_data, "%d-%d", rbot, rtop);
+}
+
+static void bitmap_print_list(const unsigned long *maskp, int nmaskbits,
+			      bitmap_printfn_t printfn, void *printfn_data)
+{
+	bool first = true;
+	/* current bit is 'cur', most recently seen range is [rbot, rtop] */
+	int cur, rbot, rtop;
+
+	rbot = cur = find_first_bit(maskp, nmaskbits);
+	while (cur < nmaskbits) {
+		rtop = cur;
+		cur = find_next_bit(maskp, nmaskbits, cur+1);
+		if (cur >= nmaskbits || cur > rtop + 1) {
+			bscnl_emit(rbot, rtop, first, printfn, printfn_data);
+			rbot = cur;
+			first = false;
+		}
+	}
 }
 
 /**
@@ -566,24 +609,14 @@ static inline int bscnl_emit(char *buf, int buflen, int rbot, int rtop, int len)
 int bitmap_scnlistprintf(char *buf, unsigned int buflen,
 	const unsigned long *maskp, int nmaskbits)
 {
-	int len = 0;
-	/* current bit is 'cur', most recently seen range is [rbot, rtop] */
-	int cur, rbot, rtop;
+	struct bitmap_scnprintf_data bsd = { .buf = buf, .buflen = buflen };
 
 	if (buflen == 0)
 		return 0;
 	buf[0] = 0;
 
-	rbot = cur = find_first_bit(maskp, nmaskbits);
-	while (cur < nmaskbits) {
-		rtop = cur;
-		cur = find_next_bit(maskp, nmaskbits, cur+1);
-		if (cur >= nmaskbits || cur > rtop + 1) {
-			len = bscnl_emit(buf, buflen, rbot, rtop, len);
-			rbot = cur;
-		}
-	}
-	return len;
+	bitmap_print_list(maskp, nmaskbits, bitmap_scnprintf_fn, &bsd);
+	return bsd.len;
 }
 EXPORT_SYMBOL(bitmap_scnlistprintf);
 
-- 
2.1.0


  reply	other threads:[~2014-12-10 15:53 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-10 15:52 [PATCHSET -mm] bitmap, cpumask, nodemask: implement pr_cont functions and use di" Tejun Heo
2014-12-10 15:52 ` Tejun Heo [this message]
2014-12-10 15:52 ` [PATCH 02/12] bitmap, cpumask, nodemask: implement pr_cont variants of formatting functions Tejun Heo
2014-12-10 15:52 ` [PATCH 03/12] mips: use {cpu|node}mask pr_cont and seq output functions Tejun Heo
2014-12-10 15:52 ` [PATCH 04/12] powerpc: " Tejun Heo
2014-12-10 15:52 ` [PATCH 05/12] tile: " Tejun Heo
2014-12-15 16:20   ` Chris Metcalf
2014-12-10 15:52 ` [PATCH 06/12] x86: " Tejun Heo
2014-12-10 15:52 ` [PATCH 07/12] xtensa: " Tejun Heo
2014-12-10 18:38   ` Max Filippov
2014-12-10 15:52 ` [PATCH 08/12] cpuset: " Tejun Heo
2014-12-10 15:52 ` [PATCH 09/12] rcu: " Tejun Heo
2014-12-10 16:29   ` Paul E. McKenney
2014-12-10 15:52 ` [PATCH 10/12] sched: " Tejun Heo
2014-12-15 10:39   ` Peter Zijlstra
2015-01-12 13:31     ` Tejun Heo
2015-01-12 13:50       ` Peter Zijlstra
2015-01-12 13:55         ` Tejun Heo
2015-01-12 14:00           ` Tejun Heo
2014-12-10 15:52 ` [PATCH 11/12] timer: " Tejun Heo
2014-12-10 15:52 ` [PATCH 12/12] percpu: " Tejun Heo
2014-12-10 21:49 ` [PATCHSET -mm] bitmap, cpumask, nodemask: implement pr_cont functions and use di" Andrew Morton
2014-12-10 22:12   ` Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1418226774-30215-2-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox