Re: instance-private-data issue
- From: Owen Taylor <otaylor redhat com>
- To: Tim Janik <timj gtk org>
- Cc: Gtk+ Developers <gtk-devel-list gnome org>
- Subject: Re: instance-private-data issue
- Date: 06 Aug 2003 15:10:47 -0400
On Wed, 2003-08-06 at 12:28, Tim Janik wrote:
> > > 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.
Hmm, so your plan is essentially (suppressing storing the
classes for each object for simplicity):
G_LOCK_DEFINE_STATIC (initializing_instances);
GSList *initializing_instances = NULL;
gboolean initializing_intances_empty = TRUE;
static void
add_initializing_instance (gpointer instance)
{
G_LOCK (initializing_instances);
initializing_instances = g_slist_prepend (initializing_instances, instance);
initializing_instances_empty = FALSE;
G_UNLOCK (initializing_instances);
}
static void
remove_initializing_instance (gpointer instance)
{
G_LOCK (initializing_instances);
initializing_instances = g_slist_remove (initializing_instances, instance);
initializing_instances_empty = initializing_instances == NULL;
G_UNLOCK (initializing_instances);
}
static gboolean
instance_is_initializing (gpointer instance)
{
gboolean found;
if (!initializing_instances_empty)
{
G_LOCK (initializing_instances);
found = g_slist_find (initializing_instances, instances) != NULL;
G_UNLOCK (initializing_instances)'
}
}
(The initializing_instances_empty variable is actually superfluous, but
would be needed if you were using an array.)
and the claim is that:
* If there are any objects being initialized in this thread, then
this thread must see initializing_instances_empty as TRUE, since
*) After add_initializing_instance, it will be seen as TRUE
by this thread
*) No thread can set it FALSE until after this thread calls
remove_initializing_instance on the object
Yeah, I think that does work. It's not as quite as good as
ultra-fast thread-private-data (__thread) because it's certainly
possible to have an object that in its init does something slow
(reads in a big file fom disk, say), but probably good enough.
Regards,
Owen
[
Does it make sense to use a separate lock rather than the
global gtype reader-writer lock? I think it might, since
avoiding write-locks when not actually modifying the type
data is a good thing.
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]