All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.