Re: instance-private-data issue



On 6 Aug 2003, Owen Taylor wrote:

> On Wed, 2003-08-06 at 08:07, Tim Janik wrote:

> > > All fine, right? Well, actually no. The problem is that
> > > g_type_instance_get_private() looks at:
> > >
> > >  a->g_class->g_type
> > >
> > > to find out the type of a, and thus the offset to the private
> > > data. Well, the way GObject works, a->g_class->g_type is
> > > always MY_TYPE_A in my_a_instance_init(), even when we are
> > > really initializing a MY_TYPE_B.
> >
> > have you written a glib-only test case for this already?
>
> Just checked in a change to testgobject to make it test this.

cool, thanks.

> > > For those not in the know, the reason it works like this is that
> > > the idea is to avoid ever accessing the virtual functions for
> > > MyB until the instance_init for MyB is called. [*]
> > >
> > > So, how do we fix the problem? Two ideas I can come up with:
> > >
> > >  - increase GTypeInstance from 4 bytes to 8 bytes (on
> > >    32 bits), caching the real type *before* the public g_class field.
> >
> > i have to side with Mathieu here. i think this is an exceptionally
> > good example for a bad trade-off. not only is private-data a
> > recently introduced non-essential feature that hasn't correctly
> > worked at all yet, the work-around is only required for a very short
> > moment in an objects lifetime. yet, you're willing to sacrifice
> > an extra pointer per every GObject used out there.
>
> *) While the problem only occurs during object initialization,
>    the cost of solving it occurs for every lookup of private
>    data.

yeah, i predicted that to be one NULL pointer check.

> *) The fact that this is a "non-essential" feature really isn't
>    relevant unless you are proposing removing it.

before i increase every GObject instance by a pointer size,
i'd strongly consider removing that feature.

> I'd love not to have to increase the size of GObject, but I
> do think instance-private data is a valuable enough feature to
> make it worth increasing the size of GObject, *if we can't
> find a better way*.

i don't agree here, but i'm pretty confident we can fix it
without increasing object size.

> > considering that most object trees don't create the majority of
> > their children during init(), using a list as lookup table is
> > probably good enough, though we could use a binary array if you
> > expect more than 8 objects to show up there at a time.
> >
> > for the common case (no object in init()), this means an additional
> > !NULL lookup-table-pointer check for g_type_instance_get_private(),
> > and in case of an object being in init(), the performance hit boils
> > down to a read-lock plus the table lookup.
>
> I don't see how you avoid the read lock on *every* lookup of instance
> private data. Is that too slow? Without timing, I don't know.

well, if you indeed disallow passing objects around in init() functions,
(or at least, disallow passing them around *without* a memory barrier in
the remote thread (there's one in the local thread already with releasing
the write-lock)), you're perfectly save with just:

if (lookup_table)
  {
    read-lock, patchup, etc...
  }

since lookup_table can't be NULL if any instance is in init,
and your thread figures it being non-NULL because it was either
this thread that appended the current instance, or you got the
updated non-NULL value due to the memory barrier.

> > to give an idea, that's roughly as fast as some
> >   g_type_is_a (OBJECT_TYPE, INTERFACE_TAPE);
> > check, which every function does on entry.
>
> Every public function. And
>
>  g_type_is_a (OBJECT_TYPE, ANOTHER_OBJECT_TYPE)
>
> doesn't involve any locks.

it does conditionally, if INTERFACE_TYPE derives from G_TYPE_INTERFACE.
and it does a binary array lookup in that case, so it's pretty much like
the planned changes to g_instance_get_private().

> Regards,
>   				Owen
>

---
ciaoTJ




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