tinycc-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]