[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 01/17] qdev: remove PropertyInfo.qtype field
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH 01/17] qdev: remove PropertyInfo.qtype field |
Date: |
Thu, 11 May 2017 13:59:06 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) |
Cc Paolo, because I have a question for him at the end.
Eric Blake <address@hidden> writes:
> On 05/09/2017 12:35 PM, Marc-André Lureau wrote:
>> Remove dependency on qapi qtype, replace a field by a few helper
>> functions to determine the default value type (introduced in commit
>> 4f2d3d7).
>>
>> Signed-off-by: Marc-André Lureau <address@hidden>
>> ---
>> include/hw/qdev-core.h | 1 -
>> include/hw/qdev-properties.h | 5 -----
>> hw/core/qdev.c | 32 ++++++++++++++++++++++++++------
>> 3 files changed, 26 insertions(+), 12 deletions(-)
>>
>> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
>> index 4bf86b0ad8..0f21a500cd 100644
>> --- a/include/hw/qdev-core.h
>> +++ b/include/hw/qdev-core.h
>> @@ -225,7 +225,6 @@ struct Property {
>> PropertyInfo *info;
>> ptrdiff_t offset;
>> uint8_t bitnr;
>> - QType qtype;
>> int64_t defval;
>> int arrayoffset;
>> PropertyInfo *arrayinfo;
As we'll see in the rest of the patch, member qtype is only used by
qdev_property_add_static(). It has nothing to do with QObject there, it
merely helps sorting properties into buckets "uninteresting", "boolean",
"enumeration", "integer".
>> diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
>> index 1d69fa7a8f..16d5d0629b 100644
>> --- a/include/hw/qdev-properties.h
>> +++ b/include/hw/qdev-properties.h
>> @@ -42,7 +42,6 @@ extern PropertyInfo qdev_prop_arraylen;
#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) {
\
.name = (_name), \
>> .info = &(_prop), \
>> .offset = offsetof(_state, _field) \
>> + type_check(_type,typeof_field(_state, _field)), \
>> - .qtype = QTYPE_QINT, \
>> .defval = (_type)_defval, \
>> }
>> #define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
>> @@ -51,7 +50,6 @@ extern PropertyInfo qdev_prop_arraylen;
#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
.name = (_name), \
.info = &(qdev_prop_bit), \
>> .bitnr = (_bit), \
>> .offset = offsetof(_state, _field) \
>> + type_check(uint32_t,typeof_field(_state, _field)), \
>> - .qtype = QTYPE_QBOOL, \
>> .defval = (bool)_defval, \
>> }
>> #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) { \
>> @@ -60,7 +58,6 @@ extern PropertyInfo qdev_prop_arraylen;
#define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) { \
.name = (_name), \
.info = &(qdev_prop_bit64), \
>> .bitnr = (_bit), \
>> .offset = offsetof(_state, _field) \
>> + type_check(uint64_t, typeof_field(_state, _field)), \
>> - .qtype = QTYPE_QBOOL, \
>> .defval = (bool)_defval, \
>> }
>>
>> @@ -69,7 +66,6 @@ extern PropertyInfo qdev_prop_arraylen;
#define DEFINE_PROP_BOOL(_name, _state, _field, _defval) { \
.name = (_name), \
>> .info = &(qdev_prop_bool), \
>> .offset = offsetof(_state, _field) \
>> + type_check(bool, typeof_field(_state, _field)), \
>> - .qtype = QTYPE_QBOOL, \
>> .defval = (bool)_defval, \
>> }
>>
>> @@ -105,7 +101,6 @@ extern PropertyInfo qdev_prop_arraylen;>
#define DEFINE_PROP_ARRAY(_name, _state, _field, \
_arrayfield, _arrayprop, _arraytype) { \
.name = (PROP_ARRAY_LEN_PREFIX _name), \
.info = &(qdev_prop_arraylen), \
>> .offset = offsetof(_state, _field) \
>> + type_check(uint32_t, typeof_field(_state, _field)), \
>> - .qtype = QTYPE_QINT, \
>> .arrayinfo = &(_arrayprop), \
>> .arrayfieldsize = sizeof(_arraytype), \
>> .arrayoffset = offsetof(_state, _arrayfield), \
Note for later:
* Member qtype can be QTYPE_QINT, QTYPE_QBOOL or zero (no initializer),
i.e. QTYPE_NONE.
* Properties defined with DEFINE_PROP_BIT(), DEFINE_PROP_BIT64() and
DEFINE_PROP_BOOL() are QTYPE_QBOOL. These are all boolean properties.
I didn't check whether the converse is also true, i.e. all boolean
properties are defined that way.
* Properties defined with DEFINE_PROP_DEFAULT() and DEFINE_PROP_ARRAY()
are QTYPE_QINT. On closer examination, the former are all integer and
enumeration properties, and the latter are all arrays of integer. I
didn't check whether the converse is also true.
>> +++ b/hw/core/qdev.c
>> @@ -755,6 +755,30 @@ static void qdev_property_add_legacy(DeviceState *dev,
>> Property *prop,
>> g_free(name);
>> }
>>
>> +static bool prop_info_is_bool(const PropertyInfo *info)
>> +{
>> + return info == &qdev_prop_bit
>> + || info == &qdev_prop_bit64
>> + || info == &qdev_prop_bool;
>> +}
>
> I guess we can expand these helpers if we add more property types later.
>
>> +
>> +static bool prop_info_is_int(const PropertyInfo *info)
>> +{
>> + return info == &qdev_prop_uint8
>> + || info == &qdev_prop_uint16
>> + || info == &qdev_prop_uint32
>> + || info == &qdev_prop_int32
>> + || info == &qdev_prop_uint64
>
> Interesting dissimilarity between existing types, but not the fault of
> your patch.
>
>> + || info == &qdev_prop_size
>> + || info == &qdev_prop_pci_devfn
>
> Okay so far.
>
>> + || info == &qdev_prop_on_off_auto
>> + || info == &qdev_prop_losttickpolicy
>> + || info == &qdev_prop_blockdev_on_error
>> + || info == &qdev_prop_bios_chs_trans
>
> Aren't these four enums rather than ints?
>
>> + || info == &qdev_prop_blocksize
>> + || info == &qdev_prop_arraylen;
>> +}
>> +
>
>> @@ -794,16 +818,12 @@ void qdev_property_add_static(DeviceState *dev,
>> Property *prop,
>> prop->info->description,
>> &error_abort);
>>
>> - if (prop->qtype == QTYPE_NONE) {
>> - return;
>> - }
>> -
>> - if (prop->qtype == QTYPE_QBOOL) {
>> + if (prop_info_is_bool(prop->info)) {
>> object_property_set_bool(obj, prop->defval, prop->name,
>> &error_abort);
>> } else if (prop->info->enum_table) {
>> object_property_set_str(obj, prop->info->enum_table[prop->defval],
>> prop->name, &error_abort);
>> - } else if (prop->qtype == QTYPE_QINT) {
>> + } else if (prop_info_is_int(prop->info)) {
>> object_property_set_int(obj, prop->defval, prop->name,
>> &error_abort);
Old code:
* Property is either uninteresting (QTYPE_NONE), boolean (QTYPE_QBOOL),
integer, enumeration or array of integer (QTYPE_QINT)
* If uninteresting (QTYPE_NONE), do nothing.
* If boolean (QTYPE_QBOOL), object_property_set_bool()
* If enumeration (QTYPE_QINT and info->enum_table),
object_property_set_str()
* If integer or array of integer (QTYPE_QINT and not info->enum_table),
object_property_set_int()
The patch drops the check of QTYPE_NONE. No change as long as
info->enum_table implies QTYPE_QINT. Plausible, but we need to
double-check.
> So enum_table has priority over prop_info_is_int(), in which case, the
> four types I pointed out as being enums will still use set_str() rather
> than set_int().
Yes.
I'm not sure I fully understand this code's logic. It's from Paolo's
commit 4f2d3d7, moved here in commit fdae245.
> I'm not necessarily sold on this patch - previously, the type was local
> to the declaration of the struct (you could tell by reading
> qdev_prop_bit that it was a boolean type); now the type is remote (you
> have to hunt elsewhere to see how the property is categorized). I'm not
> rejecting it (I see how getting rid of a dependency on QType makes it
> easier for the rest of the series to change QType underpinnings), but
> wonder if that is a strong enough justification.
>
> But if we DO keep it, you'll want a v2 that cleans up the
> prop_info_is_int() impedance mismatch.
The patch cleans up a mild abuse of QType for another purpose. I like
that.
What I don't like is enumerating PropertyInfo in helpers. A relatively
straightforward way to avoid this would be moving the part of
qdev_property_add_static() that varies between properties into a new
PropertyInfo method. Assumes that *all* instances of the same
PropertyInfo should behave the same. Paolo, is that the case?
[Qemu-devel] [PATCH 04/17] qapi: merge QInt and QFloat in QNum, Marc-André Lureau, 2017/05/09