I'm exploring an idea to lazily compute some lookup tables at runtime on a separate thread instead of baking them into the data segment of the executable.
The high-level idea is that the code that would used lookup tables would check if the table is there and, if it is, use it. If not, it would check if the table is being built and, if not, start a thread to build it. If the table is not there, a slower path would be taken.
I'm wondering if the check for "is the table there" can be a lockless if the table, once built, is not delocated (i.e. once built, the table stays on the heap for the rest of the lifetime of the process).
On to specific questions:
Is Option<&[T; N]>
a single word? I'm thinking that it should be, considering that the reference can be a pointer without the length, since length is part of the type, and None fits into the same pointer as null.
If a thread sees that a static Option<&[T; N]>
is Some(arr)
, is it always safe to access arr
? That is, does the memory model actually match my expectation that a word written to by one thread either shows up as fully not yet written or fully written to another thread and that if the address of the heap allocation has been written to a word and the word has become visible to other threads, those threads can also see the heap-allocated memory and what was written to the heap-allocated memory prior to the address of the buffer getting written to the shared word? (std::sync::atomic::Ordering
suggests that it might not be OK to expect the writes to the allocated buffer to be visible to all threads that can see the address of the buffer.)
As for the "is the table being built" check if the "is the table there" check fails, is there some kind of less-expensive-than-mutex test-and-set primitive for a boolean that makes a one-way transition? (I guess if "is the table there" is lockless, making "is the table being built" lockless doesn't really matter, but I'm curious if it can be made lockless, too.) Is compare_exchange
on AtomicBool
it?