[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Tinycc-devel] Question about Atomics support in TCC
From: |
Davidson Francis |
Subject: |
Re: [Tinycc-devel] Question about Atomics support in TCC |
Date: |
Fri, 8 Apr 2022 05:23:06 -0300 |
Hi Domingo, thanks for the additional data. That's exactly what I've
observed here: no type of lock or special instruction is generated,
nor is a function call generated either.
I'm not well-versed with compilers, but looking through the source
code (tccgen.c) it looks like atomic types are just handled like
their non-atomic counterparts, and that's why the generated code is
non-atomic, like any other primitive type .
So it seems to me that atomic support is still incomplete, unless
that's not exactly required by the standard, I'm not sure.
--
Kind regards,
Davidson Francis.
On Thu, Apr 07, 2022 at 11:30:07AM +0200, Domingo Alvarez Duarte wrote:
> 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
>
> _______________________________________________
> Tinycc-devel mailing list
> Tinycc-devel@nongnu.org
> https://lists.nongnu.org/mailman/listinfo/tinycc-devel