0

While looking at some codebases on github I have seen that sometimes a mutex table is used instead of local mutexes, selecting a mutex from this table based on, for example, pointer or hash of some other variable & an integer to differentiate the "order" of locks.

My guess is that it is done to avoid creating & destroying mutexes all over the place to improve efficiency, but wouldn't that also create situations where multiple unrelated objects are trying to lock the same mutex & thus need to wait for an unrelated lock to be released as well as waiting for their own lock?

This could potentially be solved by using a very large table, but wouldn't that potentially waste a lot of memory and potentially system resources to just have hundreds of unused mutexes sitting around? Or is this not a big issue overall?

I tried looking it up but all that google gives me is "how to use a mutex" and similar stuff.

EDIT: By "local" I mean, a mutex that is not from a global table and is individually created whenever it is needed instead of picking an existing one from a table.

JustClaire
  • 451
  • 3
  • 11
  • Could you share a link to github with the relevant piece of code? Having a global table of mutexes sounds like an antipattern to me, unless it is some kind of weird, sophisticated optimization. Weird, because creating and destroying mutexes is quite fast, and one should not have a problem with that (well, it might depend on the language). So maybe there's something else happening there. – freakish Mar 27 '22 at 09:40
  • @freakish I have seen it in the depths of MSVC's C++ STL implementation related to atomic wait & spinlock for lock-full atomics, (i think it is in either `atomic.cpp` or `atomic_wait.cpp`, i do not remember exactly which file though). I have also seen it in the past in similar situations in 3d party threading-related libraries. Give me a second, i will find a link to the MSVC STL github – JustClaire Mar 27 '22 at 09:59
  • @freakish Here, found it: https://github.com/microsoft/STL/blob/6d2f8b0ed88ea6cba26cc2151f47f678442c1663/stl/src/atomic_wait.cpp#L362 – JustClaire Mar 27 '22 at 10:01
  • Ok, so in this particular case this is done in order to simulate atomicity of atomic_ref when lock-free is not supported. Note that atomic_ref cannot be initialized with a new lock each time, because what atomic_ref does is it applies atomic operations to the object it holds. And so two atomic_refs to the same underlying object should affect each other. And therefore we have to somehow get a mutex based only on the underlying object. This means a map/dictionary. Of course a static array is a more efficient way to do that. – freakish Mar 27 '22 at 12:31
  • Read more about it here: https://stackoverflow.com/questions/58346307/how-is-stdatomic-ref-implemented-for-non-atomic-types – freakish Mar 27 '22 at 12:33
  • And so this global array of mutexes is used only to solve this particular problem. And this problem exists because of how atomic_ref was designed (in a sort of global way). And IMO this is a bad design. I encourage you to avoid such ideas. – freakish Mar 27 '22 at 12:35

0 Answers0