qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/3] vmstate: introduce calc_size VMStateField


From: Mitsyanko Igor
Subject: [Qemu-devel] [PATCH 1/3] vmstate: introduce calc_size VMStateField
Date: Mon, 26 Dec 2011 14:03:42 +0400

New calc_size field in VMStateField is supposed to help us easily add 
save/restore
support of dynamically allocated buffers in device's states.
There are some cases when information on size of dynamically allocated buffer is
already presented in specific device's state structure, but in such a form, that
can not be used with existing VMStateField interface. Currently, we either can 
get size from
another variable in device's state as it is with VMSTATE_VBUFFER_* macros, or 
we can
also multiply value kept in a variable by a constant with 
VMSTATE_BUFFER_MULTIPLY
macro. If we need to perform any other action, we're forced to add additional
variable with size information to device state structure with the only intention
to use it in VMStateDescription structure. This approach is not very pretty. 
Adding extra
flags to VMStateFlags enum for every other possible operation with size field
seems redundant, and still it would't cover cases when we need to perform a set 
of
operations to get size value.
With this new .calc_size field we can calculate size of dynamic array in 
whichever
way we need.

Signed-off-by: Mitsyanko Igor <address@hidden>
---
 hw/hw.h  |   14 +++++++-------
 savevm.c |   14 ++++++++------
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index efa04d1..8ce4475 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -303,9 +303,9 @@ enum VMStateFlags {
     VMS_ARRAY_OF_POINTER = 0x040,
     VMS_VARRAY_UINT16    = 0x080,  /* Array with size in uint16_t field */
     VMS_VBUFFER          = 0x100,  /* Buffer with size in int32_t field */
-    VMS_MULTIPLY         = 0x200,  /* multiply "size" field by field_size */
-    VMS_VARRAY_UINT8     = 0x400,  /* Array with size in uint8_t field*/
-    VMS_VARRAY_UINT32    = 0x800,  /* Array with size in uint32_t field*/
+    VMS_CALC_SIZE        = 0x200,  /* calculate size of dynamic buffer */
+    VMS_VARRAY_UINT8     = 0x400,  /* Array with size in uint8_t field */
+    VMS_VARRAY_UINT32    = 0x800,  /* Array with size in uint32_t field */
 };
 
 typedef struct {
@@ -321,6 +321,7 @@ typedef struct {
     const VMStateDescription *vmsd;
     int version_id;
     bool (*field_exists)(void *opaque, int version_id);
+    int (*calc_size)(void *opaque, int version_id);
 } VMStateField;
 
 typedef struct VMStateSubsection {
@@ -584,14 +585,13 @@ extern const VMStateInfo vmstate_info_unused_buffer;
     .offset       = vmstate_offset_buffer(_state, _field) + _start,  \
 }
 
-#define VMSTATE_BUFFER_MULTIPLY(_field, _state, _version, _test, _start, 
_field_size, _multiply) { \
+#define VMSTATE_VBUFFER_CALCSIZE(_field, _state, _version, _test, _start, 
_calc_size) { \
     .name         = (stringify(_field)),                             \
     .version_id   = (_version),                                      \
     .field_exists = (_test),                                         \
-    .size_offset  = vmstate_offset_value(_state, _field_size, uint32_t),\
-    .size         = (_multiply),                                      \
+    .calc_size    = (_calc_size),                                    \
     .info         = &vmstate_info_buffer,                            \
-    .flags        = VMS_VBUFFER|VMS_MULTIPLY,                        \
+    .flags        = VMS_VBUFFER|VMS_CALC_SIZE|VMS_POINTER,           \
     .offset       = offsetof(_state, _field),                        \
     .start        = (_start),                                        \
 }
diff --git a/savevm.c b/savevm.c
index f153c25..19f8985 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1412,9 +1412,10 @@ int vmstate_load_state(QEMUFile *f, const 
VMStateDescription *vmsd,
             int size = field->size;
 
             if (field->flags & VMS_VBUFFER) {
-                size = *(int32_t *)(opaque+field->size_offset);
-                if (field->flags & VMS_MULTIPLY) {
-                    size *= field->size;
+                if (field->flags & VMS_CALC_SIZE) {
+                    size = field->calc_size(opaque, vmsd->version_id);
+                } else {
+                    size = *(int32_t *)(opaque+field->size_offset);
                 }
             }
             if (field->flags & VMS_ARRAY) {
@@ -1476,9 +1477,10 @@ void vmstate_save_state(QEMUFile *f, const 
VMStateDescription *vmsd,
             int size = field->size;
 
             if (field->flags & VMS_VBUFFER) {
-                size = *(int32_t *)(opaque+field->size_offset);
-                if (field->flags & VMS_MULTIPLY) {
-                    size *= field->size;
+                if (field->flags & VMS_CALC_SIZE) {
+                    size = field->calc_size(opaque, vmsd->version_id);
+                } else {
+                    size = *(int32_t *)(opaque+field->size_offset);
                 }
             }
             if (field->flags & VMS_ARRAY) {
-- 
1.7.4.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]