# Linux Kernel Module Cheat

##### 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.