[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] Question about Atomics support in TCC
From: |
Domingo Alvarez Duarte |
Subject: |
Re: [Tinycc-devel] Question about Atomics support in TCC |
Date: |
Thu, 7 Apr 2022 11:30:07 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.7.0 |
Here is the code that runs on linux and also seems to not behave correctly:
====
#include <stdio.h>
//#include <threads.h>
#include <pthread.h>
#include <stdatomic.h>
atomic_int acnt;
int cnt;
//int f(void* thr_data) {
void *f(void* thr_data) {
for (int n = 0; n < 1000; ++n) {
++cnt;
++acnt;
}
return 0;
}
int main(void) {
//thrd_t thr[10];
pthread_t thr[10];
for(int n = 0; n < 10; ++n)
//thrd_create(&thr[n], f, NULL);
pthread_create(&thr[n], NULL, f, NULL);
for(int n = 0; n < 10; ++n)
//thrd_join(thr[n], NULL);
pthread_join(thr[n], NULL);
printf("The atomic counter is %u\n", acnt);
printf("The non-atomic counter is %u\n", cnt);
return 0;
}
====
Looking at the output of objdump for the generated binary from tcc and
gcc I can see that tcc doesn't generate any "lock".
Output from tcc for function "f":
====
00000000004006a3 <f>:
4006a3: 55 push %rbp
4006a4: 48 89 e5 mov %rsp,%rbp
4006a7: 48 81 ec 10 00 00 00 sub $0x10,%rsp
4006ae: 48 89 7d f8 mov %rdi,-0x8(%rbp)
4006b2: b8 00 00 00 00 mov $0x0,%eax
4006b7: 89 45 f4 mov %eax,-0xc(%rbp)
4006ba: 8b 45 f4 mov -0xc(%rbp),%eax
4006bd: 81 f8 e8 03 00 00 cmp $0x3e8,%eax
4006c3: 0f 8d 3e 00 00 00 jge 400707 <f+0x64>
4006c9: e9 0b 00 00 00 jmpq 4006d9 <f+0x36>
4006ce: 8b 45 f4 mov -0xc(%rbp),%eax
4006d1: 83 c0 01 add $0x1,%eax
4006d4: 89 45 f4 mov %eax,-0xc(%rbp)
4006d7: eb e1 jmp 4006ba <f+0x17>
4006d9: 48 8b 05 d8 0a 20 00 mov 0x200ad8(%rip),%rax #
6011b8 <cnt-0x24>
4006e0: 8b 00 mov (%rax),%eax
4006e2: 83 c0 01 add $0x1,%eax
4006e5: 4c 8b 1d cc 0a 20 00 mov 0x200acc(%rip),%r11 #
6011b8 <cnt-0x24>
4006ec: 41 89 03 mov %eax,(%r11)
4006ef: 48 8b 05 ca 0a 20 00 mov 0x200aca(%rip),%rax #
6011c0 <acnt-0x18>
4006f6: 8b 00 mov (%rax),%eax
4006f8: 83 c0 01 add $0x1,%eax
4006fb: 4c 8b 1d be 0a 20 00 mov 0x200abe(%rip),%r11 #
6011c0 <acnt-0x18>
400702: 41 89 03 mov %eax,(%r11)
400705: eb c7 jmp 4006ce <f+0x2b>
400707: 48 b8 00 00 00 00 00 movabs $0x0,%rax
40070e: 00 00 00
400711: c9 leaveq
400712: c3 retq
====
Output from gcc for function "f":
====
0000000000000755 <f>:
755: 55 push %rbp
756: 48 89 e5 mov %rsp,%rbp
759: 48 83 ec 30 sub $0x30,%rsp
75d: 48 89 7d d8 mov %rdi,-0x28(%rbp)
761: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
768: 00 00
76a: 48 89 45 f8 mov %rax,-0x8(%rbp)
76e: 31 c0 xor %eax,%eax
770: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%rbp)
777: eb 2e jmp 7a7 <f+0x52>
779: 8b 05 99 08 20 00 mov 0x200899(%rip),%eax #
201018 <cnt>
77f: 83 c0 01 add $0x1,%eax
782: 89 05 90 08 20 00 mov %eax,0x200890(%rip) #
201018 <cnt>
788: c7 45 ec 01 00 00 00 movl $0x1,-0x14(%rbp)
78f: 8b 45 ec mov -0x14(%rbp),%eax
792: 89 c2 mov %eax,%edx
794: 89 d0 mov %edx,%eax
796: f0 0f c1 05 76 08 20 lock xadd %eax,0x200876(%rip)
# 201014 <acnt>
79d: 00
79e: 01 d0 add %edx,%eax
7a0: 89 45 f0 mov %eax,-0x10(%rbp)
7a3: 83 45 f4 01 addl $0x1,-0xc(%rbp)
7a7: 81 7d f4 e7 03 00 00 cmpl $0x3e7,-0xc(%rbp)
7ae: 7e c9 jle 779 <f+0x24>
7b0: b8 00 00 00 00 mov $0x0,%eax
7b5: 48 8b 4d f8 mov -0x8(%rbp),%rcx
7b9: 64 48 33 0c 25 28 00 xor %fs:0x28,%rcx
7c0: 00 00
7c2: 74 05 je 7c9 <f+0x74>
7c4: e8 67 fe ff ff callq 630 <__stack_chk_fail@plt>
7c9: c9 leaveq
7ca: c3 retq
====
Cheers !
On 6/4/22 22:00, Davidson Francis wrote:
Hi,
I was checking the Atomics support in the TCC (mob) and realized that
while atomic functions work fine, they don't get generated if I use
'implicitly' like in:
atomic_int foo;
foo += 5;
no errors are generated either. Is this some sort of bug, or is the
Atomics support in TCC not complete yet?
A complete example (which works in GCC and Clang) taken from [1]:
#include <stdio.h>
#include <threads.h>
#include <stdatomic.h>
atomic_int acnt;
int cnt;
int f(void* thr_data) {
for (int n = 0; n < 1000; ++n) {
++cnt;
++acnt;
}
return 0;
}
int main(void) {
thrd_t thr[10];
for(int n = 0; n < 10; ++n)
thrd_create(&thr[n], f, NULL);
for(int n = 0; n < 10; ++n)
thrd_join(thr[n], NULL);
printf("The atomic counter is %u\n", acnt);
printf("The non-atomic counter is %u\n", cnt);
return 0;
}
Output:
The atomic counter is 9889
The non-atomic counter is 9897
Ref:
[1]: https://en.cppreference.com/w/c/language/atomic
Kinds regards,
Davidson Francis
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel