Commit 44e3ee8a2aaee5df49cd440446fee4525144255f
1 parent
ba223c29
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
Showing
2 changed files
with
59 additions
and
0 deletions
cutils.c
| ... | ... | @@ -101,3 +101,50 @@ int qemu_fls(int i) |
| 101 | 101 | { |
| 102 | 102 | return 32 - clz32(i); |
| 103 | 103 | } |
| 104 | + | |
| 105 | +/* io vectors */ | |
| 106 | + | |
| 107 | +void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint) | |
| 108 | +{ | |
| 109 | + qiov->iov = qemu_malloc(alloc_hint * sizeof(struct iovec)); | |
| 110 | + qiov->niov = 0; | |
| 111 | + qiov->nalloc = alloc_hint; | |
| 112 | +} | |
| 113 | + | |
| 114 | +void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len) | |
| 115 | +{ | |
| 116 | + if (qiov->niov == qiov->nalloc) { | |
| 117 | + qiov->nalloc = 2 * qiov->nalloc + 1; | |
| 118 | + qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec)); | |
| 119 | + } | |
| 120 | + qiov->iov[qiov->niov].iov_base = base; | |
| 121 | + qiov->iov[qiov->niov].iov_len = len; | |
| 122 | + ++qiov->niov; | |
| 123 | +} | |
| 124 | + | |
| 125 | +void qemu_iovec_destroy(QEMUIOVector *qiov) | |
| 126 | +{ | |
| 127 | + qemu_free(qiov->iov); | |
| 128 | +} | |
| 129 | + | |
| 130 | +void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf) | |
| 131 | +{ | |
| 132 | + uint8_t *p = (uint8_t *)buf; | |
| 133 | + int i; | |
| 134 | + | |
| 135 | + for (i = 0; i < qiov->niov; ++i) { | |
| 136 | + memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len); | |
| 137 | + p += qiov->iov[i].iov_len; | |
| 138 | + } | |
| 139 | +} | |
| 140 | + | |
| 141 | +void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf) | |
| 142 | +{ | |
| 143 | + const uint8_t *p = (const uint8_t *)buf; | |
| 144 | + int i; | |
| 145 | + | |
| 146 | + for (i = 0; i < qiov->niov; ++i) { | |
| 147 | + memcpy(qiov->iov[i].iov_base, p, qiov->iov[i].iov_len); | |
| 148 | + p += qiov->iov[i].iov_len; | |
| 149 | + } | |
| 150 | +} | ... | ... |
qemu-common.h
| ... | ... | @@ -191,6 +191,18 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id); |
| 191 | 191 | /* Force QEMU to stop what it's doing and service IO */ |
| 192 | 192 | void qemu_service_io(void); |
| 193 | 193 | |
| 194 | +typedef struct QEMUIOVector { | |
| 195 | + struct iovec *iov; | |
| 196 | + int niov; | |
| 197 | + int nalloc; | |
| 198 | +} QEMUIOVector; | |
| 199 | + | |
| 200 | +void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); | |
| 201 | +void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); | |
| 202 | +void qemu_iovec_destroy(QEMUIOVector *qiov); | |
| 203 | +void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf); | |
| 204 | +void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf); | |
| 205 | + | |
| 194 | 206 | #endif /* dyngen-exec.h hack */ |
| 195 | 207 | |
| 196 | 208 | #endif | ... | ... |