GLib weak refs depend on cascade of locks, including global ones, which makes them non-scalable
@mpiechotka
Submitted by Maciej Marcin Piechotka Link to original bug (#705728)
Description
Created attachment 251245 0001-Introduce-a-per-GObject-mutex-for-weak-references.patch
Current implementation of weak refs use a cascade of locks, including global ones. Proposed patch uses a single Object-specific mutex to handle the weak references.
There is slight change in behaviour - previously all weak references were cleared when count reached 0 even if object was resurrected. Now they are not cleared in such case unless they are check in that moment.
Benchmark results - I could not find any statistical difference in time of make check time or time of threadtests. I have constructed a benchmark which used heavy use of weak references and the results were as follows:
+---------+----------------+---------------+ | Threads | Original | Modified | +---------+----------------+---------------+ | 1 | 1.535 ± 0.008 | 1.413 ± 0.004 | | 2 | 3.0 ± 0.17 | 1.475 ± 0.006 | | 4 | 16 ± 1 | 1.79 ± 0.03 | | 8 | 45 ± 1 | 3.47 ± 0.09 | +---------+----------------+---------------+
Testing platform: 4 core i7 ivy bridge. Flags: -O2 -march=native -Wl,-O1 -Wl,--as-needed -Wl,--add-needed -Wl,--hash-style=both -Wl,--sort-common -Wl,--no-keep-memory
Patch 251245, "0001-Introduce-a-per-GObject-mutex-for-weak-references.patch":
0001-Introduce-a-per-GObject-mutex-for-weak-references.patch