27.2.2.1. atomic.c
  • userland/c/atomic.c

  • userland/c/atomic/: files in this directory use the same technique as atomic.cpp, i.e. with one special case per file.

    Maybe userland/c/atomic.c should be deprecated in favor of those more minimal ones.

    This was added because C++-pre main is too bloated, especially when we turn one a gazillion gem5 logs, it makes me want to cry.

    And we want a single operation per test rather than to as in atomic.c because when using gem5 we want absolute control over the microbenchmark.

Demonstrates atomic_int and thrd_create.

Disassembly with GDB at LKMC 619fef4b04bddc4a5a38aec5e207dd4d5a25d206 + 1:

./disas --arch aarch64 --userland userland/c/atomic.c my_thread_main

shows on ARM:

16              ++cnt;
   0x00000000004008cc <+28>:    80 00 00 b0     adrp    x0, 0x411000 <malloc@got.plt>
   0x00000000004008d0 <+32>:    00 80 01 91     add     x0, x0, #0x60
   0x00000000004008d4 <+36>:    00 00 40 b9     ldr     w0, [x0]
   0x00000000004008d8 <+40>:    01 04 00 11     add     w1, w0, #0x1
   0x00000000004008dc <+44>:    80 00 00 b0     adrp    x0, 0x411000 <malloc@got.plt>
   0x00000000004008e0 <+48>:    00 80 01 91     add     x0, x0, #0x60
   0x00000000004008e4 <+52>:    01 00 00 b9     str     w1, [x0]

17              ++acnt;
   0x00000000004008e8 <+56>:    20 00 80 52     mov     w0, #0x1                        // #1
   0x00000000004008ec <+60>:    e0 1b 00 b9     str     w0, [sp, #24]
   0x00000000004008f0 <+64>:    e0 1b 40 b9     ldr     w0, [sp, #24]
   0x00000000004008f4 <+68>:    e2 03 00 2a     mov     w2, w0
   0x00000000004008f8 <+72>:    80 00 00 b0     adrp    x0, 0x411000 <malloc@got.plt>
   0x00000000004008fc <+76>:    00 70 01 91     add     x0, x0, #0x5c
   0x0000000000400900 <+80>:    03 00 e2 b8     ldaddal w2, w3, [x0]
   0x0000000000400904 <+84>:    61 00 02 0b     add     w1, w3, w2
   0x0000000000400908 <+88>:    e0 03 01 2a     mov     w0, w1
   0x000000000040090c <+92>:    e0 1f 00 b9     str     w0, [sp, #28]

so:

  • the atomic increment uses ldadd

  • the non-atomic increment just does LDR, ADD, STR: ldadd

With -O3:

16              ++cnt;
   0x0000000000400a00 <+32>:    60 00 40 b9     ldr     w0, [x3]
   0x0000000000400a04 <+36>:    00 04 00 11     add     w0, w0, #0x1
   0x0000000000400a08 <+40>:    60 00 00 b9     str     w0, [x3]

17              ++acnt;
   0x0000000000400a0c <+44>:    20 00 80 52     mov     w0, #0x1                        // #1
   0x0000000000400a10 <+48>:    40 00 e0 b8     ldaddal w0, w0, [x2]

so the situation is the same but without all the horrible stack noise.