[llvm-commits] [PATCH] Thread-safe ManagedStatic
Chris Lattner
clattner at apple.com
Tue May 19 12:41:25 PDT 2009
>> 2. Again, we only need a single global lock, we do not need a mutex
>> per ManagedStatic.
>
> Conversely, why have only one? Also, see my answer to #3.
Because it takes less space.
>> 3. Why do you create your own mutex out of atomic operations instead
>> of just using a pthreads lock? spinning is not always an efficient
>> solution to contention, particularly if your machine really only has
>> one cpu! (in which case you end up spinning away the rest of your
>> timeslice)
>
> Portability. llvm::sys::Mutex _cannot_ be made to work, because on
> Windows
> it has to have a non-trivial constructor.
This is irrelevant. We are going to have a bunch of "global" state
for all the stuff that uniques stuff. The managed static is just the
first piece of it. When the app calls llvm_start_multithread_mode(),
this function can set up the global mutex and do whatever else it
wants to do, while the app is still single threaded. This means that
it is perfectly safe to have:
Mutex *TheGlobalMutex;
and use:
TheGlobalMutex->lock();
places, because you know that TheGlobalMutex will be allocated and
initialized when the app is single threaded.
> Also, this is pretty much the ideal case for spinlocks.
> Initialization only happens once and
> we're using a separate mutex for each object, so we don't expect
> significant contention over
> the life of the program. Plus, the initialization itself should be
> fairly fast. This means that
> the spinning thread can continue immediately after the lock is
> released, rather than having
> to wait for the OS to wake it up.
ManagedStatic is a generic class, meaning that it can take an
arbitrary amount of time to initialize. One initialization can
potentially also cause initialization of other objects: make sure the
global mutex is recursive.
>>
>> efficient, I think it would be good to special case the scenario when
>> there is only one LLVM thread. Why not make clients explicitly opt-
>> in
>> to multithreaded llvm, by making an explicit llvm_multithread call?
>> If multithreading is disabled, this call should return an error. If
>> enabled, it would set a global. All the various "locking" clients
>> could just check the global before taking potential heavy-weight
>> locks.
>
> We already handle this in a somewhat different way. When threading
> is disabled,
> llvm::sys::Mutex operations are turned into no-ops, and
> MemoryFence() and
> CompareAndSwap() are given non-atomic implementations.
You are confusing the case when llvm is compiled without
multithreading support with the case where it is compiled with
threading support but that app is not using it.
-Chris
More information about the llvm-commits
mailing list