diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-01-22 16:59:20 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-01-22 16:59:20 +0000 |
commit | 44e3ee8a2aaee5df49cd440446fee4525144255f (patch) | |
tree | 450cf688ca2c46221c9e4447da0bbabde0398b29 | |
parent | ba223c29da480b40b38678c66636ee9910973a47 (diff) | |
download | hqemu-44e3ee8a2aaee5df49cd440446fee4525144255f.zip hqemu-44e3ee8a2aaee5df49cd440446fee4525144255f.tar.gz |
I/O vector helpers (Avi Kivity)
In general, it is not possible to predict the size of of an I/O vector since
a contiguous guest region may map to a disconiguous host region. Add some
helpers to manage I/O vector growth.
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6396 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | cutils.c | 47 | ||||
-rw-r--r-- | qemu-common.h | 12 |
2 files changed, 59 insertions, 0 deletions
@@ -101,3 +101,50 @@ int qemu_fls(int i) { return 32 - clz32(i); } + +/* io vectors */ + +void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint) +{ + qiov->iov = qemu_malloc(alloc_hint * sizeof(struct iovec)); + qiov->niov = 0; + qiov->nalloc = alloc_hint; +} + +void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len) +{ + if (qiov->niov == qiov->nalloc) { + qiov->nalloc = 2 * qiov->nalloc + 1; + qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec)); + } + qiov->iov[qiov->niov].iov_base = base; + qiov->iov[qiov->niov].iov_len = len; + ++qiov->niov; +} + +void qemu_iovec_destroy(QEMUIOVector *qiov) +{ + qemu_free(qiov->iov); +} + +void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf) +{ + uint8_t *p = (uint8_t *)buf; + int i; + + for (i = 0; i < qiov->niov; ++i) { + memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len); + p += qiov->iov[i].iov_len; + } +} + +void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf) +{ + const uint8_t *p = (const uint8_t *)buf; + int i; + + for (i = 0; i < qiov->niov; ++i) { + memcpy(qiov->iov[i].iov_base, p, qiov->iov[i].iov_len); + p += qiov->iov[i].iov_len; + } +} diff --git a/qemu-common.h b/qemu-common.h index d83e61b..ae773e0 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -191,6 +191,18 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id); /* Force QEMU to stop what it's doing and service IO */ void qemu_service_io(void); +typedef struct QEMUIOVector { + struct iovec *iov; + int niov; + int nalloc; +} QEMUIOVector; + +void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); +void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); +void qemu_iovec_destroy(QEMUIOVector *qiov); +void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf); +void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf); + #endif /* dyngen-exec.h hack */ #endif |