Mark H Weaver <m...@netris.org> writes: >> Two are stuck here: >> >> #0 __lll_lock_wait () at >> ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135 >> #1 0x00007f343ca69bb5 in __GI___pthread_mutex_lock ( >> mutex=mutex@entry=0x7f343d4f0f40 <bytes_until_gc_lock>) >> at ../nptl/pthread_mutex_lock.c:80 >> #2 0x00007f343d213e20 in scm_gc_register_allocation (size=size@entry=16) >> at ../../libguile/gc.c:591 > > This is the global GC allocation lock, which might be an issue if your > threads are performing a lot of heap allocation.
Sorry, I spoke too quickly here, although what I wrote is not far from the truth. 'bytes_until_gc_lock' is used by Guile to protect its global counter of how much plain 'malloc' memory has been allocated since the last garbage collection. Once it reaches a certain threshold, a garbage collection is forced. Why do we have this? Sometimes the GC heap contains a large number of small collectible objects which reference much larger objects in plain 'malloc' memory. For example, this can happen if you're creating a lot of bignums, which are small GC objects pointing to digit data stored in 'malloc' memory. The garbage collector doesn't trigger because there's plenty of free memory in the GC heap, and it doesn't know that those small objects are keeping alive much larger objects elsewhere. However, if this particular lock is a pain point for you, there are things we could do to improve this. One idea that comes to mind is to keep smaller per-thread counters, which are only added to the global counter after they reach a certain threshold value. In this case, we don't need a precise global count. Mark