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 651467 - Add pointer sized bitlocks
Add pointer sized bitlocks
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gthread
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
: 651351 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2011-05-30 11:53 UTC by Alexander Larsson
Modified: 2011-06-04 00:55 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Implement pointer sized bitlocks (5.10 KB, patch)
2011-05-30 11:54 UTC, Alexander Larsson
none Details | Review
Implement pointer sized bitlocks (5.01 KB, patch)
2011-05-30 12:20 UTC, Alexander Larsson
none Details | Review
Implement pointer sized bitlocks (4.97 KB, patch)
2011-05-30 15:45 UTC, Allison Karlitskaya (desrt)
reviewed Details | Review
asm (3.51 KB, patch)
2011-06-03 20:24 UTC, Allison Karlitskaya (desrt)
none Details | Review
pointers (10.75 KB, patch)
2011-06-03 20:24 UTC, Allison Karlitskaya (desrt)
none Details | Review

Description Alexander Larsson 2011-05-30 11:53:37 UTC
It would be nice to have pointer sized bitlocks, then we can use those to make a threadsafe GDataList. 

This is broken out from bug #650823.
Comment 1 Alexander Larsson 2011-05-30 11:54:04 UTC
Created attachment 188879 [details] [review]
Implement pointer sized bitlocks
Comment 2 Alexander Larsson 2011-05-30 12:00:49 UTC
Ok, this patch doesn't work anymore with the new names of stuff. Will fix up.
Comment 3 Alexander Larsson 2011-05-30 12:20:04 UTC
Created attachment 188881 [details] [review]
Implement pointer sized bitlocks
Comment 4 Alexander Larsson 2011-05-30 12:20:49 UTC
New, working version. This is used for the stuff in bug 650458
Comment 5 Allison Karlitskaya (desrt) 2011-05-30 15:06:49 UTC
*** Bug 651351 has been marked as a duplicate of this bug. ***
Comment 6 Allison Karlitskaya (desrt) 2011-05-30 15:12:59 UTC
As a simplifying measure, I suggest we restrict pointer bitlocks to be contained in the lowest few bits of the pointer.  From a practical standpoint I'm sure nobody would try to use more than the lowest 2 or 3 bits anyway, and it also means that you don't end up with portability problems when moving your code from 64bit to 32bit machines.

As an added benefit, the implementation gets _much_ easier: on little endian, we never need to do any math at all (since the lowest bits are always at the same memory address).  Ditto any 32 bit machine (since pointer size is integer size).  All that's left is big endian 64bit, and in that case we simply add 4.
Comment 7 Allison Karlitskaya (desrt) 2011-05-30 15:45:50 UTC
Created attachment 188890 [details] [review]
Implement pointer sized bitlocks
Comment 8 Allison Karlitskaya (desrt) 2011-05-30 15:50:07 UTC
I think this should work (but I didn't test it).  Some notes:

  - changed the docs to say that it only works for bits 0..31

  - changed the since tags

  - used the simple logic described in comment 6

  - changed the interface from gpointer* to void* to avoid aliasing warnings.
    We should consider adding macros to make it safer.

  - use the same contention indicators since there is no harm in aliasing
    here (just a spurious WAKE call that the kernel will ignore anyway).  If
    we wanted to, we could increase the size of the array as an alternative.

  - recopy the function bodies from their int counterparts.  They are now
    almost identical code (with changes only to the types and addition of
    the int_address call).
Comment 9 Matthias Clasen 2011-05-31 11:09:17 UTC
Review of attachment 188890 [details] [review]:

::: glib/gbitlock.c
@@ +325,3 @@
+ * g_pointer_bit_lock:
+ * @address: a pointer to a pointer
+ * @lock_bit: a bit value between 0 and 31

I think the documentation needs to be a bit more explicit about the fact that @lock_bit is restricted to the lower half of the address.
Hiding that in the description of @lock_bit is not clear.
Comment 10 Allison Karlitskaya (desrt) 2011-05-31 15:28:13 UTC
(In reply to comment #9)
> I think the documentation needs to be a bit more explicit about the fact that
> @lock_bit is restricted to the lower half of the address.
> Hiding that in the description of @lock_bit is not clear.

I agree.  I'll also add an assert to enforce it.

Everything else is OK?
Comment 11 Matthias Clasen 2011-05-31 15:52:01 UTC
(In reply to comment #10)
 
> Everything else is OK?

From my side, yes. Of course, fully supporting bit locks on pointers would be nicer, still. But this would solve the immediate need to move ahead on datalist scalability improvements.
Comment 12 Matthias Clasen 2011-06-01 22:45:59 UTC
From further discussion with Ryan, before he jumped on a plane, it seems what we really want here for optimal performance is to ensure that we use a 'lock bts' instruction. __sync_fetch_and_or does not quite give us the best code, so we may instead add a g_atomic_pointer_bit_test_and_set() function, and add an asm implementation for x86.

Awaiting a new patch from Ryan here.
Comment 13 Allison Karlitskaya (desrt) 2011-06-02 23:02:43 UTC
I'm actually thinking that it would be more appropriate to provide hand-written ASM versions of bitlocking for x86 and amd64.  I don't want to provide those as standard atomic operations until we have a less-hacky way of supporting them.

See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49244 for my efforts to get something into GCC...

The pointer-sized bitlocks are working but they are *insanely* slow when contended (many times slower than the int-sized ones).  I don't know why.
Comment 14 Matthias Clasen 2011-06-03 14:07:58 UTC
(In reply to comment #13)
> I'm actually thinking that it would be more appropriate to provide hand-written
> ASM versions of bitlocking for x86 and amd64.  I don't want to provide those as
> standard atomic operations until we have a less-hacky way of supporting them.

Fine with me.

> See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49244 for my efforts to get
> something into GCC...
> 
> The pointer-sized bitlocks are working but they are *insanely* slow when
> contended (many times slower than the int-sized ones).  I don't know why.

Is that with g_atomic_pointer_and_or(), or with lock bts ?
Comment 15 Allison Karlitskaya (desrt) 2011-06-03 18:13:52 UTC
With the g_atomic_pointer_and_or().  I'm working on the bts version.  We'll see how much of a difference it makes...
Comment 16 Allison Karlitskaya (desrt) 2011-06-03 20:24:02 UTC
Created attachment 189181 [details] [review]
asm
Comment 17 Allison Karlitskaya (desrt) 2011-06-03 20:24:25 UTC
Created attachment 189182 [details] [review]
pointers
Comment 18 Alexander Larsson 2011-06-03 21:24:28 UTC
Quite weird that the contended case should be so much slower. The only difference is really the size of the atomic operation... Maybe the pointer overlaps two cachelines (32bit in each) or something?
Comment 19 Alexander Larsson 2011-06-03 21:53:48 UTC
Or maybe its the atomic 32bit read after an atomic 64bit write?
Comment 20 Matthias Clasen 2011-06-04 00:55:44 UTC
Ryan found the silly bug:

#if defined (G_BIG_ENDIAN)

should be

#if G_BYTE_ORDER == G_BIG_ENDIAN