Quantcast
Viewing all articles
Browse latest Browse all 3

Answer by Nick for Do I use atomic over shared memory correctly here

Because C++atomic are not very "clear" to use, you can use stdatomic.h.

https://en.cppreference.com/w/c/atomic/atomic_load

However I failed to compile example with these on gcc.

This is why I decided to use gcc builtin atomics:

https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html

These works on both gcc and clang on Linux. Did not checked on MacOS yes.

Here is the code, almost similar to what I posted before. Once again excuse C style code.

In order code to be similar to what stdatomic.h offers, I did two functions that call the builtin(s):

template<typename T>void atomic_store(T *a, T val){    return __atomic_store_n(a, val, __ATOMIC_RELAXED);}template<typename T>void atomic_store(T &a, T val){    return atomic_store(& a, val);}template<typename T>T atomic_load(T *a){    return __atomic_load_n(a, __ATOMIC_RELAXED);}template<typename T>T atomic_load(T &a){    return atomic_load(& a);}

Those suppose to be good with all integral types such int, short, char, unsigned etc.

Here is the full code in case you decide to "dig" future.

#include <cstdio>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h> // sleep#include <cstdlib>  // exit#include <time.h>using MyAtomicInt = int;constexpr size_t SIZE = sizeof(MyAtomicInt);constexpr const char *NAME = "nmmm";constexpr MyAtomicInt STOP = 12345;void error(const char *msg){    printf("%s\n", msg);    exit(10);}template<typename T>void atomic_store(T *a, T val){    return __atomic_store_n(a, val, __ATOMIC_RELAXED);}template<typename T>void atomic_store(T &a, T val){    return atomic_store(& a, val);}template<typename T>T atomic_load(T *a){    return __atomic_load_n(a, __ATOMIC_RELAXED);}template<typename T>T atomic_load(T &a){    return atomic_load(& a);}int main(int argc, const char **argv){    int fd = shm_open(NAME,  O_RDWR | O_CREAT, 0644);    if (fd < 0)        error("shm_open");    int t = ftruncate(fd, SIZE);    if (t < 0)        error("ftruncate");    void *vmem = mmap(nullptr, SIZE, PROT_WRITE, MAP_SHARED, fd, 0);    if (vmem == MAP_FAILED)        error("mmap");    printf("All set up! %p\n", vmem);    MyAtomicInt *ai = reinterpret_cast<MyAtomicInt *>(vmem);    if (argc > 1){        switch(argv[1][0]){        case 'g':        case 'G':            atomic_store(ai, 0);            while(true){                auto x = atomic_load(ai);                printf("%d\n", x);                if (x == STOP)                    break;                sleep(1);            }        case 's':        case 'S':            atomic_store(ai, STOP);            break;        default:            {                srand(time(nullptr));                MyAtomicInt const x = rand() & 0xFFFF;                printf("set val to %d\n", x);                atomic_store(ai, x);            }            break;        }    }    munmap(vmem, SIZE);//  shm_unlink(NAME);}

Viewing all articles
Browse latest Browse all 3

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>