From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34161) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zw9s3-00032R-5R for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:26:04 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zw9s1-0000ir-Sz for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:26:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51093) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zw9s1-0000il-KT for qemu-devel@nongnu.org; Tue, 10 Nov 2015 09:26:01 -0500 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 57F3EA3B40 for ; Tue, 10 Nov 2015 14:26:01 +0000 (UTC) From: Juan Quintela Date: Tue, 10 Nov 2015 15:24:57 +0100 Message-Id: <1447165546-27784-9-git-send-email-quintela@redhat.com> In-Reply-To: <1447165546-27784-1-git-send-email-quintela@redhat.com> References: <1447165546-27784-1-git-send-email-quintela@redhat.com> Subject: [Qemu-devel] [PULL 08/57] Add qemu_get_buffer_in_place to avoid copies some of the time List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: amit.shah@redhat.com, dgilbert@redhat.com From: "Dr. David Alan Gilbert" qemu_get_buffer always copies the data it reads to a users buffer, however in many cases the file buffer inside qemu_file could be given back to the caller, avoiding the copy. This isn't always possible depending on the size and alignment of the data. Thus 'qemu_get_buffer_in_place' either copies the data to a supplied buffer or updates a pointer to the internal buffer if convenient. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- include/migration/qemu-file.h | 2 ++ migration/qemu-file.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h index 29a338d..86bb972 100644 --- a/include/migration/qemu-file.h +++ b/include/migration/qemu-file.h @@ -163,9 +163,11 @@ void qemu_put_be32(QEMUFile *f, unsigned int v); void qemu_put_be64(QEMUFile *f, uint64_t v); size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset); size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size); +size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size); ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, int level); int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src); + /* * Note that you can only peek continuous bytes from where the current pointer * is; you aren't guaranteed to be able to peak to +n bytes unless you've diff --git a/migration/qemu-file.c b/migration/qemu-file.c index df49023..e41a677 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -434,6 +434,43 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size) } /* + * Read 'size' bytes of data from the file. + * 'size' can be larger than the internal buffer. + * + * The data: + * may be held on an internal buffer (in which case *buf is updated + * to point to it) that is valid until the next qemu_file operation. + * OR + * will be copied to the *buf that was passed in. + * + * The code tries to avoid the copy if possible. + * + * It will return size bytes unless there was an error, in which case it will + * return as many as it managed to read (assuming blocking fd's which + * all current QEMUFile are) + * + * Note: Since **buf may get changed, the caller should take care to + * keep a pointer to the original buffer if it needs to deallocate it. + */ +size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size) +{ + if (size < IO_BUF_SIZE) { + size_t res; + uint8_t *src; + + res = qemu_peek_buffer(f, &src, size, 0); + + if (res == size) { + qemu_file_skip(f, res); + *buf = src; + return res; + } + } + + return qemu_get_buffer(f, *buf, size); +} + +/* * Peeks a single byte from the buffer; this isn't guaranteed to work if * offset leaves a gap after the previous read/peeked data. */ -- 2.5.0