qemu-devel
[Top][All Lists]
Advanced

[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?



reply via email to

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