aboutsummaryrefslogtreecommitdiff
path: root/cutils.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-02-15 17:18:04 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-02-15 17:18:04 -0600
commit65b31cc207b8ab949033870acf55bb124d12848e (patch)
treec7727e413b24d8ae024fea2ab455f8c49be02b20 /cutils.c
parentb2d4b3f7b8c8ad0519c4705a3b850446068e6946 (diff)
parentb867672884afc39b6537a8aa6aa2f20a5154bf4f (diff)
downloadqemu-65b31cc207b8ab949033870acf55bb124d12848e.zip
qemu-65b31cc207b8ab949033870acf55bb124d12848e.tar.gz
qemu-65b31cc207b8ab949033870acf55bb124d12848e.tar.bz2
Merge remote-tracking branch 'kwolf/for-anthony' into staging
* kwolf/for-anthony: AHCI: Masking of IRQs actually masks them sheepdog: fix co_recv coroutine context AHCI: Fix port reset race rewrite QEMU_BUILD_BUG_ON qcow2: Keep unknown header extension when rewriting header qcow2: Update whole header at once vpc: Round up image size during fixed image creation vpc: Add support for Fixed Disk type iSCSI: add configuration variables for iSCSI qemu-io: add write -z option for bdrv_co_write_zeroes qed: add .bdrv_co_write_zeroes() support qed: replace is_write with flags field block: perform zero-detection during copy-on-read block: add .bdrv_co_write_zeroes() interface cutils: extract buffer_is_zero() from qemu-img.c
Diffstat (limited to 'cutils.c')
-rw-r--r--cutils.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/cutils.c b/cutils.c
index a6ffd46..af308cd 100644
--- a/cutils.c
+++ b/cutils.c
@@ -303,6 +303,41 @@ void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count,
}
}
+/*
+ * Checks if a buffer is all zeroes
+ *
+ * Attention! The len must be a multiple of 4 * sizeof(long) due to
+ * restriction of optimizations in this function.
+ */
+bool buffer_is_zero(const void *buf, size_t len)
+{
+ /*
+ * Use long as the biggest available internal data type that fits into the
+ * CPU register and unroll the loop to smooth out the effect of memory
+ * latency.
+ */
+
+ size_t i;
+ long d0, d1, d2, d3;
+ const long * const data = buf;
+
+ assert(len % (4 * sizeof(long)) == 0);
+ len /= sizeof(long);
+
+ for (i = 0; i < len; i += 4) {
+ d0 = data[i + 0];
+ d1 = data[i + 1];
+ d2 = data[i + 2];
+ d3 = data[i + 3];
+
+ if (d0 || d1 || d2 || d3) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
#ifndef _WIN32
/* Sets a specific flag */
int fcntl_setfl(int fd, int flag)