Richard W.M. Jones
2017-Apr-19 16:46 UTC
[Libguestfs] [PATCH v2 0/2] daemon: Move the useful 'is_zero' function into common code.
v1 -> v2: The first patch is the same (the pure refactoring), but in the second patch I implement Eric Blake's suggested version. Rich.
Richard W.M. Jones
2017-Apr-19 16:46 UTC
[Libguestfs] [PATCH v2 1/2] daemon: Move the useful 'is_zero' function into common code.
This is largely a simple refactoring, but it combines another definition of this function from virt-builder which had a slightly different prototype. --- builder/pxzcat-c.c | 20 +------------------- daemon/daemon.h | 18 ------------------ lib/guestfs-internal-all.h | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 37 deletions(-) diff --git a/builder/pxzcat-c.c b/builder/pxzcat-c.c index 33923b532..ef37849ed 100644 --- a/builder/pxzcat-c.c +++ b/builder/pxzcat-c.c @@ -409,24 +409,6 @@ parse_indexes (value filenamev, int fd) return combined_index; } -/* Return true iff the buffer is all zero bytes. - * - * Note that gcc is smart enough to optimize this properly: - * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989 - */ -static inline int -is_zero (const unsigned char *buffer, size_t size) -{ - size_t i; - - for (i = 0; i < size; ++i) { - if (buffer[i] != 0) - return 0; - } - - return 1; -} - struct global_state { /* Current iterator. Threads update this, but it is protected by a * mutex, and each thread takes a copy of it when working on it. @@ -681,7 +663,7 @@ worker_thread (void *vp) /* Don't write if the block is all zero, to preserve output file * sparseness. However we have to update oposition. */ - if (!is_zero (outbuf, wsz)) { + if (!is_zero ((char *) outbuf, wsz)) { if (xpwrite (global->ofd, outbuf, wsz, oposition) == -1) { perror (global->outputfile); return &state->status; diff --git a/daemon/daemon.h b/daemon/daemon.h index 332e2966a..a317139a5 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -327,24 +327,6 @@ extern void pulse_mode_cancel (void); */ extern void notify_progress_no_ratelimit (uint64_t position, uint64_t total, const struct timeval *now); -/* Return true iff the buffer is all zero bytes. - * - * Note that gcc is smart enough to optimize this properly: - * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989 - */ -static inline int -is_zero (const char *buffer, size_t size) -{ - size_t i; - - for (i = 0; i < size; ++i) { - if (buffer[i] != 0) - return 0; - } - - return 1; -} - /* Helper for functions that need a root filesystem mounted. * NB. Cannot be used for FileIn functions. */ diff --git a/lib/guestfs-internal-all.h b/lib/guestfs-internal-all.h index 0c841ff67..4f7433332 100644 --- a/lib/guestfs-internal-all.h +++ b/lib/guestfs-internal-all.h @@ -89,6 +89,24 @@ #define xdr_uint32_t xdr_u_int32_t #endif +/* Return true iff the buffer is all zero bytes. + * + * Note that gcc is smart enough to optimize this properly: + * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989 + */ +static inline int +is_zero (const char *buffer, size_t size) +{ + size_t i; + + for (i = 0; i < size; ++i) { + if (buffer[i] != 0) + return 0; + } + + return 1; +} + /* Macro which compiles the regexp once when the program/library is * loaded, and frees it when the library is unloaded. */ -- 2.12.0
Richard W.M. Jones
2017-Apr-19 16:46 UTC
[Libguestfs] [PATCH v2 2/2] lib: Reimplement is_zero.
As suggested by Eric Blake. --- lib/guestfs-internal-all.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/guestfs-internal-all.h b/lib/guestfs-internal-all.h index 4f7433332..7da93828e 100644 --- a/lib/guestfs-internal-all.h +++ b/lib/guestfs-internal-all.h @@ -32,6 +32,8 @@ #ifndef GUESTFS_INTERNAL_ALL_H_ #define GUESTFS_INTERNAL_ALL_H_ +#include <string.h> + /* This is also defined in <guestfs.h>, so don't redefine it. */ #if defined(__GNUC__) && !defined(GUESTFS_GCC_VERSION) # define GUESTFS_GCC_VERSION \ @@ -89,20 +91,18 @@ #define xdr_uint32_t xdr_u_int32_t #endif -/* Return true iff the buffer is all zero bytes. - * - * Note that gcc is smart enough to optimize this properly: - * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989 - */ +/* Return true iff the buffer is all zero bytes. */ static inline int is_zero (const char *buffer, size_t size) { size_t i; + const size_t limit = MIN (size, 16); - for (i = 0; i < size; ++i) { - if (buffer[i] != 0) + for (i = 0; i < limit; ++i) + if (buffer[i]) return 0; - } + if (size != limit) + return !memcmp (buffer, buffer + 16, size - 16); return 1; } -- 2.12.0
Pino Toscano
2017-Apr-20 12:30 UTC
Re: [Libguestfs] [PATCH v2 0/2] daemon: Move the useful 'is_zero' function into common code.
On Wednesday, 19 April 2017 18:46:37 CEST Richard W.M. Jones wrote:> v1 -> v2: > > The first patch is the same (the pure refactoring), but in the second > patch I implement Eric Blake's suggested version.LGTM -- can you please add Eric's text to the comment of is_zero, so it is easier to remember why the 16-bytes trick is done? Thanks, -- Pino Toscano
Richard W.M. Jones
2017-Apr-20 13:38 UTC
Re: [Libguestfs] [PATCH v2 0/2] daemon: Move the useful 'is_zero' function into common code.
On Thu, Apr 20, 2017 at 02:30:52PM +0200, Pino Toscano wrote:> On Wednesday, 19 April 2017 18:46:37 CEST Richard W.M. Jones wrote: > > v1 -> v2: > > > > The first patch is the same (the pure refactoring), but in the second > > patch I implement Eric Blake's suggested version. > > LGTM -- can you please add Eric's text to the comment of is_zero, so > it is easier to remember why the 16-bytes trick is done?Done, thanks. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org
Maybe Matching Threads
- [PATCH] daemon: Move the useful 'is_zero' function into common code.
- Re: [PATCH] daemon: Move the useful 'is_zero' function into common code.
- Re: [PATCH] daemon: Move the useful 'is_zero' function into common code.
- [PATCH 0/5] Use less stack.
- Re: [PATCH v2 0/2] daemon: Move the useful 'is_zero' function into common code.