After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 69668 - Add GLib analogy to pthread_once
Add GLib analogy to pthread_once
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: general
1.3.x
Other All
: Low enhancement
: ---
Assigned To: gtkdev
gtkdev
: 55102 (view as bug list)
Depends on:
Blocks: 65041
 
 
Reported: 2002-01-25 15:16 UTC by Sebastian Wilhelmi
Modified: 2011-02-18 16:07 UTC
See Also:
GNOME target: ---
GNOME version: Unversioned Enhancement


Attachments
a full implementation in terms of g_thread abstraction (6.44 KB, patch)
2002-02-18 22:31 UTC, Miroslaw Dobrzanski-Neumann
none Details | Review
patch to implement GOnce and g_once (9.09 KB, patch)
2002-02-21 15:58 UTC, Sebastian Wilhelmi
none Details | Review

Description Sebastian Wilhelmi 2002-01-25 15:16:14 UTC
Having GOnce datatype and a 
g_once (GOnce* once, GVoidFunc initalize) function, we could make a general
solution to the problems of #61228 and the static mutex on plaform without
native static mutexes:

See

http://bugzilla.gnome.org/show_bug.cgi?id=61228

http://mail.gnome.org/archives/gtk-devel-list/2001-May/msg00147.html

We can use code like (beware: pseudocode)

g_once (GOnce* once, GVoidFunc initalize)
{
  if (*once)
    return;
 
  G_LOCK(once);
    initalize();
  G_UNLOCK(once);

  *once = TRUE;
}

The values of READ_MEMORY_BARRIER of
glibc/linuxthreads/sysdeps/*/pt-machine.h will be of interest, as the
source of pthread_once in glibc looks like:

  /* Test without locking first for speed */
  if (*once_control == DONE) {
    READ_MEMORY_BARRIER();
    return 0;
  }
  /* Lock and test again */

READ_MEMORY_BARRIER is empty for arm, cris, hppa, i386, i386/i686, ia64,
m68k, sh, s390/s390-32, s390/s390-64 and set to some asm for sparc/sparc32,
sparc/sparc64, alpha, mips, powerpc. For the first group I think, it would
be save to use the double locking idiom. The second group would need full
locking unless we implement the read memory barrier ourself copying from
linuxthreads, which I wouldn't like.

NB for implementing: Beware of recursion into the GOnce handler!

(A whole other possibility would be to simply __use__, what pthread_once
 offers and use the full locking on platforms, which have no counterpart.
 Thinking twice about it, this seems to be the best solution.)
Comment 1 Miroslaw Dobrzanski-Neumann 2002-02-18 22:31:00 UTC
Created attachment 6767 [details] [review]
a full implementation in terms of g_thread abstraction
Comment 2 Miroslaw Dobrzanski-Neumann 2002-02-18 22:37:56 UTC
Attachment 6767 [details]
The implementation uses a double check technique to provide a very
fast go over in almost all cases where the intializer has been already
run. It bases on the atomic read access for machine words. When in
doubt the full locking is performed and initializer is run if needed.
Comment 3 Sebastian Wilhelmi 2002-02-19 09:09:20 UTC
Your solution is not guaranteed to work. We have this discussion every
half year. Basically the double check pattern is not safe for some
(admittedly not so common) systems. We could use this technique, where
it is allowed, and fall back to full locking on the other platforms.

I think, we should support calling a function, which takes an argument
(gpointer) and returns a gpointer to make this more useful. Such an
implementation could be used to implement
g_static_mutex_get_mutex_impl, which is my aim in including g_once.
Your implementation couldn't do that. Actually the pthread
implementation is of very limited use due to that.

The proposed interface would look like this:

gpointer g_once (GOnce* once, GThreadFunc initalize, gpointer arg);




Comment 4 Sebastian Wilhelmi 2002-02-21 14:48:34 UTC
*** Bug 55102 has been marked as a duplicate of this bug. ***
Comment 5 Sebastian Wilhelmi 2002-02-21 15:57:55 UTC
Attached you'll find an implementation of GOnce and 

gpointer g_once (GOnce* once, GThreadFunc initalize, gpointer arg)

and a test in thread-test.c (modelled after the one in the patch of
Miroslaw)

Also it uses the information, whether double checked locking is safe
to use, to make GStaticMutex faster. Docs are not included yet, but
should be no problem getting in, if and when this is committed.
Comment 6 Sebastian Wilhelmi 2002-02-21 15:58:28 UTC
Created attachment 6807 [details] [review]
patch to implement GOnce and g_once
Comment 7 Owen Taylor 2003-07-04 15:26:41 UTC
This looks good to commit to me; I'm a little concerned about
the fallback implementation being a bottleneck on sparc though.
(ppc also a possible concern, but I don't think people care
as much about GNOME performance on slow ppc machines as on
slow sparc machines)

Brian - do you know someone knowledgable about the low-level
sparc details you could get to take look at this?


Comment 8 Sebastian Wilhelmi 2003-07-04 20:44:06 UTC
I'll not have internet access for the next 2 month. So if you want
that in, you got to do it yourself. Thanks. This is indeed the last
time I'll check my email for that long. Scary.
Comment 9 Matthias Clasen 2003-07-08 23:44:45 UTC
Scary indeed. I've committed your patch with docs.