From: Eric Wong Date: 2018-02-07T23:19:47+00:00 Subject: [ruby-core:85470] Re: [Ruby trunk Bug#14357] thread_safe tests suite segfaults eregontp@gmail.com wrote: > The GIL guarantees all C code is executed with the GIL held, so C code always perfectly sees effects performed by C code of other threads > (except rb_thread_call_without_gvl but it is not used here, is it?). Correct, GVL protects common cases (string/fixnum/etc) > In this case: is the code during a Hash lookup, after calling Ruby's #hash/#eql? expecting some state to not have changed since before the call? > If so, it should be enough to re-check that state after the call. Yes, probably doable. I thought about this while eating; but we can probably use rebuilds_num as a seqlock: unsigned int seq; retry: seq = tab->rebuilds_num; /* needs barriers */ ... ...->compare(a, b); /* may rebuild */ if (tab->rebuilds_num != seq) goto retry; Not free in terms of overhead, but should still be cheap and shouldn't need atomics on the reader side; only memory barriers to ensure correct ordering with some CPUs. > When growing/shrinking a Hash table, the GIL should be held, so that should be observed atomically by other threads. > Or is it the problem that #rehash needs to call back to Ruby code? Right, the rebuild is done entirely with the GVL held, so that's not a problem. It needs to update rebuild_num atomically for the above reader pseudocode to work, but that's a cold path. Vladimir: thoughts? Unsubscribe: