Zhang via llvm-dev
2018-Jul-24 03:18 UTC
[llvm-dev] Possibility of implementing a low-level naive lock purely with LLVM atomics?
Hi: In our frontend we are attempting to build a lock mechanism without using system apis like pthreads and whatnot for internal reasons. In order to achieve this we are now creating a int32 type GV, and then use atomic load/store and comparisons. The generated IR looks like the following: ``` @Flag = private global i32 0, align 4 %0 = load atomic i32, i32* @Flag acquire, align 4 %1 = icmp eq i32 %0, 1 ....... store atomic i32 1, i32* @Flag release, align 4 ``` However when inspecting the generated assembly on x86-64, the following assembly was generated: ``` mov qword [rbp+var_50], rcx mov qword [rbp+var_48], rdx mov rbx, rsi mov r15, rdi mov eax, dword [l_Flag] ; l_Flag cmp eax, 0x1 ``` Which to my best knowledge is not atomic. I'd like to know how do I fix my frontend to make sure the locking mechanism works Zhang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180724/d01a186f/attachment.html>
Andres Freund via llvm-dev
2018-Jul-24 03:41 UTC
[llvm-dev] Possibility of implementing a low-level naive lock purely with LLVM atomics?
Hi, On 2018-07-24 11:18:42 +0800, Zhang via llvm-dev wrote:> In our frontend we are attempting to build a lock mechanism without using system apis like pthreads and whatnot for internal reasons. > In order to achieve this we are now creating a int32 type GV, and then use atomic load/store and comparisons. The generated IR looks like the following: > > > ``` > @Flag = private global i32 0, align 4 > %0 = load atomic i32, i32* @Flag acquire, align 4 > %1 = icmp eq i32 %0, 1 > ....... > store atomic i32 1, i32* @Flag release, align 4 > ```Isn't the problem here that you need to use an atomic exchange or compare-exchange? Doing the icmp separately from the store can't be right. What you've done is to add ordering constraints, but that doesn't help you. You'd need to use atomicrmw or cmpxchg instructions afaics. Greetings, Andres Freund
mayuyu.io via llvm-dev
2018-Jul-24 07:36 UTC
[llvm-dev] Possibility of implementing a low-level naive lock purely with LLVM atomics?
Thanks Andres. What we basically is trying to achieve is to make sure that some BBs in the function are executed exactly once. Currently we use a GV to mark the execution status and at function start we load the value and do comparison, if executed we just directly branch bypass the BBs. To my best knowledge atomicrmw does the modify in place so we cant’t update the value only after the BB’s execution has finished Zhang> 在 2018年7月24日,11:41,Andres Freund <andres at anarazel.de> 写道: > > Hi, > >> On 2018-07-24 11:18:42 +0800, Zhang via llvm-dev wrote: >> In our frontend we are attempting to build a lock mechanism without using system apis like pthreads and whatnot for internal reasons. >> In order to achieve this we are now creating a int32 type GV, and then use atomic load/store and comparisons. The generated IR looks like the following: >> >> >> ``` >> @Flag = private global i32 0, align 4 >> %0 = load atomic i32, i32* @Flag acquire, align 4 >> %1 = icmp eq i32 %0, 1 >> ....... >> store atomic i32 1, i32* @Flag release, align 4 >> ``` > > Isn't the problem here that you need to use an atomic exchange or > compare-exchange? Doing the icmp separately from the store can't be > right. What you've done is to add ordering constraints, but that doesn't > help you. You'd need to use atomicrmw or cmpxchg instructions afaics. > > Greetings, > > Andres Freund