Hello,
On Tue, Mar 5, 2013 at 10:24 PM, Mark H Weaver <m...@netris.org> wrote: > Hi Noah, > > Noah Lavine <noah.b.lav...@gmail.com> writes: > > I've only read the most recent article you posted, but if I understand > > correctly, there is a third option: (3) somehow find a way to generate > > a portable memory barrier instruction. Is that currently possible? > > If we were to do that, we'd have to add memory barriers in two places: > (1) after writing to the lazily-initialized variable, and (2) before > reading from it. While memory barriers are somewhat more efficient than > mutexes, they are still very expensive. > I'm not sure I understand the issue, but I think I was imagining something like if (variable == SCM_BOOL_F) { acquire_mutex(var_mutex); if (variable == SCM_BOOL_F) { variable = initialize_variable(); memory_barrier(); } release_mutex(var_mutex); } That's really just a normal locking scheme with an added memory barrier to make sure that all threads see an update after the first thread updates the variable. Would that work? > As for portability, C11 is the first C standard to support memory > barriers. For now, our best bet would probably be to use libatomic_ops, > which is also used by libgc. > That means we already depend on libatomic_ops, which is good. However, I see that the website for that library recommends using C11 instead. But I really doubt that this issue is a big enough justification to use either libatomic_ops or C11. > > Probably option (2) is best if we can do it. > > Agreed. Unfortunately, in these cases option (2) would significantly > increase the number of modules that need to be loaded at initialization > time. That's why I reluctantly chose option (1). > That makes sense. Thanks a lot for helping me understand these memory issues. Noah