[riot-notifications] [RIOT-OS/RIOT] sys: Added simple memory barrier API (#11438)

Marian Buschsieweke notifications at github.com
Wed Apr 24 16:19:13 CEST 2019


### Contribution description
- Added an easy to use function to provide a (strict) memory barrier using a portable API
    - The current implementation will work on any but ancient versions of GCC and clang
    - Platform-specific implementations can easily be added if the need arise, as the API is generic
- Added some descriptive documentation that should help RIOT developers to identify when memory barriers are required and how to use them

### Testing procedure
- Regarding the documentation
    - Please carefully review the documentation. This is a complex topic that confuses a lot of C developers and incorrect documentation is often more harmful than no documentation at all.
- Regarding the code
    - Review the two lines of code
        - For `compiler_barrier()` check https://en.wikipedia.org/wiki/Memory_ordering#Compiler_memory_barrier
        - For `memory_barrier()` check https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html and https://llvm.org/docs/Atomics.html
    -  Test compilation of the following C code (e.g. by pasting into `examples/hello-world/main.c`)
        - Without the memory barrier the writes to `a` and `b` will be reordered and combined to two 32 bit writes on 32-bit platforms.
        - With the memory barrier only writes prior the barrier will be completed before the writes after the barrier take place. (Note that e.g. writes to `a` can still be merged and reordered in regard to the write to `b.u8[0]`, but not in regard to any other write to `b` - which take place after the barrier.)
        - With the memory barriers on sophisticated platforms (e.g. `nucleo-f767zi`) actual memory barrier instructions are emitted by the compiler (e.g. `dmb` (data memory barrier)); On in-order CPUs those instructions are neither supported nor needed

```C
#include <stdint.h>
#include "barriers.h"

typedef union {
    uint32_t u32;
    uint8_t u8[4];
} foo_t;

foo_t a, b;

void bar(void) {
    a.u8[0] = 0xa0;
    a.u8[1] = 0xa1;
    b.u8[0] = 0xb0;
    a.u8[2] = 0xa2;
    a.u8[3] = 0xa3;
    /* Add memory_barrier() here */
    b.u8[1] = 0xb1;
    b.u8[2] = 0xb2;
    b.u8[3] = 0xb3;
}
```

### Issues/PRs references
Potential users of this API: https://github.com/RIOT-OS/RIOT/pull/11073, https://github.com/RIOT-OS/RIOT/pull/8842
You can view, comment on, or merge this pull request online at:

  https://github.com/RIOT-OS/RIOT/pull/11438

-- Commit Summary --

  * sys: Added simple memory barrier API

-- File Changes --

    A sys/include/barriers.h (298)

-- Patch Links --

https://github.com/RIOT-OS/RIOT/pull/11438.patch
https://github.com/RIOT-OS/RIOT/pull/11438.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/11438
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20190424/9ee8bc55/attachment.html>


More information about the notifications mailing list