Interoperabilty between C and C++ atomics












8














Suppose, I have a task that might be cancelled from another thread. The task is performed in a C function, another thread runs C++ code. How do I do that?



Rough example.



C:



void do_task(atomic_bool const *cancelled);


C++:



std::atomic_bool cancelled;

do_task(&cancelled);


For now, I created a file atomics.h with the following content:



#ifdef __cplusplus
#include <atomic>
using std::atomic_bool;
#else
#include <stdatomic.h>
#endif


It appears to work, but I don't see any guarantees for that. I wonder, if there is a better (correct) way.










share|improve this question






















  • for what you here need atomic ? which operation need to be atomic ? nothing. you here need volatile by sense, but not atomic - void do_task(volatile bool *cancelled);
    – RbMm
    3 hours ago












  • really in most case you even not need volatile if inside loop do { * } while (!*cancelled); you call some external function, for which compiler can not know - are it modify *cancelled
    – RbMm
    3 hours ago


















8














Suppose, I have a task that might be cancelled from another thread. The task is performed in a C function, another thread runs C++ code. How do I do that?



Rough example.



C:



void do_task(atomic_bool const *cancelled);


C++:



std::atomic_bool cancelled;

do_task(&cancelled);


For now, I created a file atomics.h with the following content:



#ifdef __cplusplus
#include <atomic>
using std::atomic_bool;
#else
#include <stdatomic.h>
#endif


It appears to work, but I don't see any guarantees for that. I wonder, if there is a better (correct) way.










share|improve this question






















  • for what you here need atomic ? which operation need to be atomic ? nothing. you here need volatile by sense, but not atomic - void do_task(volatile bool *cancelled);
    – RbMm
    3 hours ago












  • really in most case you even not need volatile if inside loop do { * } while (!*cancelled); you call some external function, for which compiler can not know - are it modify *cancelled
    – RbMm
    3 hours ago
















8












8








8







Suppose, I have a task that might be cancelled from another thread. The task is performed in a C function, another thread runs C++ code. How do I do that?



Rough example.



C:



void do_task(atomic_bool const *cancelled);


C++:



std::atomic_bool cancelled;

do_task(&cancelled);


For now, I created a file atomics.h with the following content:



#ifdef __cplusplus
#include <atomic>
using std::atomic_bool;
#else
#include <stdatomic.h>
#endif


It appears to work, but I don't see any guarantees for that. I wonder, if there is a better (correct) way.










share|improve this question













Suppose, I have a task that might be cancelled from another thread. The task is performed in a C function, another thread runs C++ code. How do I do that?



Rough example.



C:



void do_task(atomic_bool const *cancelled);


C++:



std::atomic_bool cancelled;

do_task(&cancelled);


For now, I created a file atomics.h with the following content:



#ifdef __cplusplus
#include <atomic>
using std::atomic_bool;
#else
#include <stdatomic.h>
#endif


It appears to work, but I don't see any guarantees for that. I wonder, if there is a better (correct) way.







c++ c atomic






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 6 hours ago









grepcake

644518




644518












  • for what you here need atomic ? which operation need to be atomic ? nothing. you here need volatile by sense, but not atomic - void do_task(volatile bool *cancelled);
    – RbMm
    3 hours ago












  • really in most case you even not need volatile if inside loop do { * } while (!*cancelled); you call some external function, for which compiler can not know - are it modify *cancelled
    – RbMm
    3 hours ago




















  • for what you here need atomic ? which operation need to be atomic ? nothing. you here need volatile by sense, but not atomic - void do_task(volatile bool *cancelled);
    – RbMm
    3 hours ago












  • really in most case you even not need volatile if inside loop do { * } while (!*cancelled); you call some external function, for which compiler can not know - are it modify *cancelled
    – RbMm
    3 hours ago


















for what you here need atomic ? which operation need to be atomic ? nothing. you here need volatile by sense, but not atomic - void do_task(volatile bool *cancelled);
– RbMm
3 hours ago






for what you here need atomic ? which operation need to be atomic ? nothing. you here need volatile by sense, but not atomic - void do_task(volatile bool *cancelled);
– RbMm
3 hours ago














really in most case you even not need volatile if inside loop do { * } while (!*cancelled); you call some external function, for which compiler can not know - are it modify *cancelled
– RbMm
3 hours ago






really in most case you even not need volatile if inside loop do { * } while (!*cancelled); you call some external function, for which compiler can not know - are it modify *cancelled
– RbMm
3 hours ago














5 Answers
5






active

oldest

votes


















4














The atomic_bool type in C and the std::atomic<bool> type in C++ (typedefed as std::atomic_bool) are two different types that are unrelated. Passing a std::atomic_bool to a C function expecting C's atomic_bool is Undefined Behavior. That it works at all is a combination of luck and the simple definitions of these types being compatible.



If the C++ code needs to call a C function that expects C's atomic_bool, then that is what it must use. However, the <stdatomic.h> header does not exist in C++. You'll have to provide a way for the C++ code to call C code to get a pointer to the atomic variable you need in a way that hides the type. (Possibly declare a struct that holds the atomic bool, that C++ would only know that the type exists and only know about pointers to it.)






share|improve this answer





















  • It doesn't matter that they are different types. They basically synchronize the same byte of memory via same memory operations. struct A{int x; int y; int z}; and struct B{int a[3];}; are different but there is no problem when converting one from the other via brute-force conversions. There is no undefined behavior. Same with atomic_bool and std::atomic<bool>.
    – ALX23z
    4 hours ago






  • 1




    from developers.redhat.com/blog/2016/01/14/… "The atomic types are fully interoperable between the two languages so that programs can be developed that share objects of atomic types across the language boundary."
    – Manny_Mar
    1 hour ago





















3














To side-step all ABI issues you may like to implement a C function that is called from C++ and operates on that atomic_bool. This way your C++ code doesn't need to know anything about that global variable and its type:



In an .hfile:



#ifdef __cplusplus
extern "C" {
#endif

void cancel_my_thread(void);
int is_my_thread_cancelled(void);

#ifdef __cplusplus
}
#endif


And then in a .c file:



#include <stdatomic.h>

static atomic_bool cancelled = 0;

void cancel_my_thread(void) {
atomic_store_explicit(&cancelled, 1, memory_order_relaxed);
}
int is_my_thread_cancelled(void) {
return atomic_load_explicit(&cancelled, memory_order_relaxed);
}


The C++ code would include that headed and call cancel_my_thread.






share|improve this answer































    2














    I found this on a net search https://developers.redhat.com/blog/2016/01/14/toward-a-better-use-of-c11-atomics-part-1/




    Following the lead of C++, along with a memory model describing the
    requirements and semantics of multithreaded programs, the C11 standard
    adopted a proposal for a set of atomic types and operations into the
    language. This change has made it possible to write portable
    multi-threaded software that efficiently manipulates objects
    indivisibly and without data races. The atomic types are fully
    interoperable between the two languages so that programs can be
    developed that share objects of atomic types across the language
    boundary. This paper examines some of the trade-offs of the design,
    points out some of its shortcomings, and outlines solutions that
    simplify the use of atomic objects in both languages.




    I am just learning about atomics now, but it looks like its compatible between C and CPP.






    share|improve this answer































      0














      how i understand your code in general is (must be) next



      // c code

      void _do_task();

      void do_task(volatile bool *cancelled)
      {
      do {
      _do_task();
      } while (!*cancelled);
      }

      // c++ code

      volatile bool g_cancelled;// can be modify by another thread
      do_task(&cancelled);

      void some_proc()
      {
      //...
      g_cancelled = true;
      }


      i be ask question - are here we need declare cancelled as atomic ? are we need atomic here ?



      atomic need in 3 case:





      • we do Read-Modify-Write operation. say if we need set
        cancelled to true and check are it was already true



        if (cancelled.exchange(true)) { /**/} else {/**/}



        but i doubt that here we need RMW operation on canceled



      • the read or write operation for type need to be atomic. of course on
        all current and all possible future implementations this is true for
        bool type (despite formal not defined). but even this is not
        important. we here check cancelled only for 2 values - 0 (false) and
        all another. so even if both write and read operation on
        cancelled assume not atomic, after one thread write non-zero to
        canceled, another thread sooner or later will read modified non-zero value
        from canceled . even if it will be another value, not the same
        first thread write: for example if cancelled = true translated to
        mov cancelled, -1; mov cancelled, 1 - two hardware, not atomic
        operation - second thread can read -1 instead final 1 (true)
        from canceled, but this not play role if we check only for non-zero - all
        another values break loop - while (!*cancelled); if we use here atomic operation for write/read cancelled - nothing change here - after one thread atomic write to it another thread sooner or later will read modified non-zero value from canceled - atomic operation or not - memory is common - if one thread write to memory (atomic or no) another threads sooner or later will view this memory modification.

      • we need synchronize another read/writes with cancelled. so we need
        synchronization point between 2 threads around canceled with memory
        order other than memory_order_relaxed say for example next code:


      //



      void _do_task();

      int result;

      void do_task(atomic_bool *cancelled)
      {
      do {
      _do_task();
      } while (!g_cancelled.load(memory_order_acquire));

      switch(result)
      {
      case 1:
      //...
      break;
      }
      }

      void some_proc()
      {
      result = 1;
      g_cancelled.store(true, memory_order_release);
      }


      so we not simply set g_cancelled to true here, but before this

      write some shared data (result) and want that another thread after
      view modification of g_cancelled, will be also view modification of

      shared data (result). but i doubt that you actually use/need this

      scenario



      if none of this 3 things is need- you not need atomic here. what you really need - that one thread just write true to cancelled and another thread all time read value of cancelled (instead do this once and cache result). usual in most case of code this will be done auto, but for be exactly you need declare canceled as volatile



      if however you by some reason need exactly atomic (atomic_bool), because you here cross the border of languages, you need understand concrete implementation of atomic_bool in both languages and are it the same (type declaration, operations (load, store, etc)). by fact atomic_bool is the same for c and c++.



      or (better) instead of make visible and share type atomic_bool use interface functions like



      bool is_canceled(void* cancelled);



      so code can be next



      // c code
      void _do_task();

      bool is_canceled(void* cancelled);

      void do_task(void *cancelled)
      {
      do {
      _do_task();
      } while (!is_canceled(cancelled));
      }

      // c++ code

      atomic_bool g_cancelled;// can be modify by another thread

      bool is_canceled(void* cancelled)
      {
      return *reinterpret_cast<atomic_bool*>(cancelled);
      }

      void some_proc()
      {
      //...
      g_cancelled = true;
      }

      do_task(&g_cancelled);


      but again i doubt that in your task you need atomic_bool by semantic. you need volatile bool






      share|improve this answer





























        -2














        Atomicity of operations is caused by hardware, not software (well, in C++ there are also "atomic" variables that are atomic in name only, those are implemented via mutexes and locks). So, basically, C++ atomics and C atomics do the very same thing. Hence as long as the types are compatible there won't be issues. And C++11 and C11 atomic classes were made to be compatible.





        Apparently, people do not understand how atomics and locks work and require further explanation. Check out current memory models for more information.



        1) We will start with basics. What and why are atomics? How does memory works?



        Memory Model: think of processor as several independent cores and each has its own memory (cashes L1, L2, and L3; and in fact, L3 cash is common but it isn't really important).



        Why do we need atomic operation?



        If you don't use atomics, then each processor might have its own version of the variable 'x' and they are in general not synchronized. There is no telling when they will perform synchronizations with RAM/L3 cash.



        When atomic operations are used, such memory operations are used that ensure synchronization with RAM/L3 cash (or whatever is needed) - ensuring that different cores have access to the same variable and not have variety of different versions of it.



        Nobody cares if it is C, C++, or whatever language you use - as long as one ensures memory synchronization (both read, write, and modify) there will never be no issues.



        2) OK, what about locks and mutexes?



        Mutexes tend to work with OS and have queue over which thread should be allowed next to perform. And they enforce stricter memory synchronization than atomics do. With atomics one can syhchronize just the variable itself or more depending on the request / which function you call.



        3) Say I have atomic_bool, can it work in interchangeably on different languages (C/C++11)?



        Normally a boolean can be sychronized via memory operations (you're just synchronizing a single byte of memory from their perspective).
        If the compilers are aware that the hardware can perform such operations then they surely will use them as long as you use the standard.



        Logical atomics (any std::atomic< T > with T having wrong size/alignment) are synchronized via locks. In this case it is unlikely that different languages can use them interchangeably - if they have different methods of usage of these locks, or for some reason one decided to use a lock and the other one came to conclusion that it can work with atomic hardware memory synchronizations... then there will be issues.



        If you use atomic_bool on any modern machine with C/C++, it will surely be able to synchronize without locks.






        share|improve this answer










        New contributor




        ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.














        • 5




          "And C++11 and C11 atomic classes were made to be compatible" Can you cite any source for this claim? Moreover, std::atomic_bool is not guaranteed to be lock free as opposed to std::atomic_flag.
          – idmean
          6 hours ago










        • @idmean atomic_bool is not guaranteed to be lock free by the standart, as it doesn't require it to be. Whether it is lock free or not is something you ought to ask hardware whether it supports atomic operations. Locks are also in sense atomics, as they force more strict memory syncronization, while atomics allow way more relaxed memory sync.
          – ALX23z
          5 hours ago








        • 5




          Recommend tightening up the focus and better explaining this answer. Right now it reads like a short answer question on a test where the student is throwing down whatever buzzwords they think will give them the most marks.
          – user4581301
          5 hours ago











        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53898429%2finteroperabilty-between-c-and-c-atomics%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        4














        The atomic_bool type in C and the std::atomic<bool> type in C++ (typedefed as std::atomic_bool) are two different types that are unrelated. Passing a std::atomic_bool to a C function expecting C's atomic_bool is Undefined Behavior. That it works at all is a combination of luck and the simple definitions of these types being compatible.



        If the C++ code needs to call a C function that expects C's atomic_bool, then that is what it must use. However, the <stdatomic.h> header does not exist in C++. You'll have to provide a way for the C++ code to call C code to get a pointer to the atomic variable you need in a way that hides the type. (Possibly declare a struct that holds the atomic bool, that C++ would only know that the type exists and only know about pointers to it.)






        share|improve this answer





















        • It doesn't matter that they are different types. They basically synchronize the same byte of memory via same memory operations. struct A{int x; int y; int z}; and struct B{int a[3];}; are different but there is no problem when converting one from the other via brute-force conversions. There is no undefined behavior. Same with atomic_bool and std::atomic<bool>.
          – ALX23z
          4 hours ago






        • 1




          from developers.redhat.com/blog/2016/01/14/… "The atomic types are fully interoperable between the two languages so that programs can be developed that share objects of atomic types across the language boundary."
          – Manny_Mar
          1 hour ago


















        4














        The atomic_bool type in C and the std::atomic<bool> type in C++ (typedefed as std::atomic_bool) are two different types that are unrelated. Passing a std::atomic_bool to a C function expecting C's atomic_bool is Undefined Behavior. That it works at all is a combination of luck and the simple definitions of these types being compatible.



        If the C++ code needs to call a C function that expects C's atomic_bool, then that is what it must use. However, the <stdatomic.h> header does not exist in C++. You'll have to provide a way for the C++ code to call C code to get a pointer to the atomic variable you need in a way that hides the type. (Possibly declare a struct that holds the atomic bool, that C++ would only know that the type exists and only know about pointers to it.)






        share|improve this answer





















        • It doesn't matter that they are different types. They basically synchronize the same byte of memory via same memory operations. struct A{int x; int y; int z}; and struct B{int a[3];}; are different but there is no problem when converting one from the other via brute-force conversions. There is no undefined behavior. Same with atomic_bool and std::atomic<bool>.
          – ALX23z
          4 hours ago






        • 1




          from developers.redhat.com/blog/2016/01/14/… "The atomic types are fully interoperable between the two languages so that programs can be developed that share objects of atomic types across the language boundary."
          – Manny_Mar
          1 hour ago
















        4












        4








        4






        The atomic_bool type in C and the std::atomic<bool> type in C++ (typedefed as std::atomic_bool) are two different types that are unrelated. Passing a std::atomic_bool to a C function expecting C's atomic_bool is Undefined Behavior. That it works at all is a combination of luck and the simple definitions of these types being compatible.



        If the C++ code needs to call a C function that expects C's atomic_bool, then that is what it must use. However, the <stdatomic.h> header does not exist in C++. You'll have to provide a way for the C++ code to call C code to get a pointer to the atomic variable you need in a way that hides the type. (Possibly declare a struct that holds the atomic bool, that C++ would only know that the type exists and only know about pointers to it.)






        share|improve this answer












        The atomic_bool type in C and the std::atomic<bool> type in C++ (typedefed as std::atomic_bool) are two different types that are unrelated. Passing a std::atomic_bool to a C function expecting C's atomic_bool is Undefined Behavior. That it works at all is a combination of luck and the simple definitions of these types being compatible.



        If the C++ code needs to call a C function that expects C's atomic_bool, then that is what it must use. However, the <stdatomic.h> header does not exist in C++. You'll have to provide a way for the C++ code to call C code to get a pointer to the atomic variable you need in a way that hides the type. (Possibly declare a struct that holds the atomic bool, that C++ would only know that the type exists and only know about pointers to it.)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 5 hours ago









        1201ProgramAlarm

        16.3k42439




        16.3k42439












        • It doesn't matter that they are different types. They basically synchronize the same byte of memory via same memory operations. struct A{int x; int y; int z}; and struct B{int a[3];}; are different but there is no problem when converting one from the other via brute-force conversions. There is no undefined behavior. Same with atomic_bool and std::atomic<bool>.
          – ALX23z
          4 hours ago






        • 1




          from developers.redhat.com/blog/2016/01/14/… "The atomic types are fully interoperable between the two languages so that programs can be developed that share objects of atomic types across the language boundary."
          – Manny_Mar
          1 hour ago




















        • It doesn't matter that they are different types. They basically synchronize the same byte of memory via same memory operations. struct A{int x; int y; int z}; and struct B{int a[3];}; are different but there is no problem when converting one from the other via brute-force conversions. There is no undefined behavior. Same with atomic_bool and std::atomic<bool>.
          – ALX23z
          4 hours ago






        • 1




          from developers.redhat.com/blog/2016/01/14/… "The atomic types are fully interoperable between the two languages so that programs can be developed that share objects of atomic types across the language boundary."
          – Manny_Mar
          1 hour ago


















        It doesn't matter that they are different types. They basically synchronize the same byte of memory via same memory operations. struct A{int x; int y; int z}; and struct B{int a[3];}; are different but there is no problem when converting one from the other via brute-force conversions. There is no undefined behavior. Same with atomic_bool and std::atomic<bool>.
        – ALX23z
        4 hours ago




        It doesn't matter that they are different types. They basically synchronize the same byte of memory via same memory operations. struct A{int x; int y; int z}; and struct B{int a[3];}; are different but there is no problem when converting one from the other via brute-force conversions. There is no undefined behavior. Same with atomic_bool and std::atomic<bool>.
        – ALX23z
        4 hours ago




        1




        1




        from developers.redhat.com/blog/2016/01/14/… "The atomic types are fully interoperable between the two languages so that programs can be developed that share objects of atomic types across the language boundary."
        – Manny_Mar
        1 hour ago






        from developers.redhat.com/blog/2016/01/14/… "The atomic types are fully interoperable between the two languages so that programs can be developed that share objects of atomic types across the language boundary."
        – Manny_Mar
        1 hour ago















        3














        To side-step all ABI issues you may like to implement a C function that is called from C++ and operates on that atomic_bool. This way your C++ code doesn't need to know anything about that global variable and its type:



        In an .hfile:



        #ifdef __cplusplus
        extern "C" {
        #endif

        void cancel_my_thread(void);
        int is_my_thread_cancelled(void);

        #ifdef __cplusplus
        }
        #endif


        And then in a .c file:



        #include <stdatomic.h>

        static atomic_bool cancelled = 0;

        void cancel_my_thread(void) {
        atomic_store_explicit(&cancelled, 1, memory_order_relaxed);
        }
        int is_my_thread_cancelled(void) {
        return atomic_load_explicit(&cancelled, memory_order_relaxed);
        }


        The C++ code would include that headed and call cancel_my_thread.






        share|improve this answer




























          3














          To side-step all ABI issues you may like to implement a C function that is called from C++ and operates on that atomic_bool. This way your C++ code doesn't need to know anything about that global variable and its type:



          In an .hfile:



          #ifdef __cplusplus
          extern "C" {
          #endif

          void cancel_my_thread(void);
          int is_my_thread_cancelled(void);

          #ifdef __cplusplus
          }
          #endif


          And then in a .c file:



          #include <stdatomic.h>

          static atomic_bool cancelled = 0;

          void cancel_my_thread(void) {
          atomic_store_explicit(&cancelled, 1, memory_order_relaxed);
          }
          int is_my_thread_cancelled(void) {
          return atomic_load_explicit(&cancelled, memory_order_relaxed);
          }


          The C++ code would include that headed and call cancel_my_thread.






          share|improve this answer


























            3












            3








            3






            To side-step all ABI issues you may like to implement a C function that is called from C++ and operates on that atomic_bool. This way your C++ code doesn't need to know anything about that global variable and its type:



            In an .hfile:



            #ifdef __cplusplus
            extern "C" {
            #endif

            void cancel_my_thread(void);
            int is_my_thread_cancelled(void);

            #ifdef __cplusplus
            }
            #endif


            And then in a .c file:



            #include <stdatomic.h>

            static atomic_bool cancelled = 0;

            void cancel_my_thread(void) {
            atomic_store_explicit(&cancelled, 1, memory_order_relaxed);
            }
            int is_my_thread_cancelled(void) {
            return atomic_load_explicit(&cancelled, memory_order_relaxed);
            }


            The C++ code would include that headed and call cancel_my_thread.






            share|improve this answer














            To side-step all ABI issues you may like to implement a C function that is called from C++ and operates on that atomic_bool. This way your C++ code doesn't need to know anything about that global variable and its type:



            In an .hfile:



            #ifdef __cplusplus
            extern "C" {
            #endif

            void cancel_my_thread(void);
            int is_my_thread_cancelled(void);

            #ifdef __cplusplus
            }
            #endif


            And then in a .c file:



            #include <stdatomic.h>

            static atomic_bool cancelled = 0;

            void cancel_my_thread(void) {
            atomic_store_explicit(&cancelled, 1, memory_order_relaxed);
            }
            int is_my_thread_cancelled(void) {
            return atomic_load_explicit(&cancelled, memory_order_relaxed);
            }


            The C++ code would include that headed and call cancel_my_thread.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago

























            answered 1 hour ago









            Maxim Egorushkin

            84.9k1199180




            84.9k1199180























                2














                I found this on a net search https://developers.redhat.com/blog/2016/01/14/toward-a-better-use-of-c11-atomics-part-1/




                Following the lead of C++, along with a memory model describing the
                requirements and semantics of multithreaded programs, the C11 standard
                adopted a proposal for a set of atomic types and operations into the
                language. This change has made it possible to write portable
                multi-threaded software that efficiently manipulates objects
                indivisibly and without data races. The atomic types are fully
                interoperable between the two languages so that programs can be
                developed that share objects of atomic types across the language
                boundary. This paper examines some of the trade-offs of the design,
                points out some of its shortcomings, and outlines solutions that
                simplify the use of atomic objects in both languages.




                I am just learning about atomics now, but it looks like its compatible between C and CPP.






                share|improve this answer




























                  2














                  I found this on a net search https://developers.redhat.com/blog/2016/01/14/toward-a-better-use-of-c11-atomics-part-1/




                  Following the lead of C++, along with a memory model describing the
                  requirements and semantics of multithreaded programs, the C11 standard
                  adopted a proposal for a set of atomic types and operations into the
                  language. This change has made it possible to write portable
                  multi-threaded software that efficiently manipulates objects
                  indivisibly and without data races. The atomic types are fully
                  interoperable between the two languages so that programs can be
                  developed that share objects of atomic types across the language
                  boundary. This paper examines some of the trade-offs of the design,
                  points out some of its shortcomings, and outlines solutions that
                  simplify the use of atomic objects in both languages.




                  I am just learning about atomics now, but it looks like its compatible between C and CPP.






                  share|improve this answer


























                    2












                    2








                    2






                    I found this on a net search https://developers.redhat.com/blog/2016/01/14/toward-a-better-use-of-c11-atomics-part-1/




                    Following the lead of C++, along with a memory model describing the
                    requirements and semantics of multithreaded programs, the C11 standard
                    adopted a proposal for a set of atomic types and operations into the
                    language. This change has made it possible to write portable
                    multi-threaded software that efficiently manipulates objects
                    indivisibly and without data races. The atomic types are fully
                    interoperable between the two languages so that programs can be
                    developed that share objects of atomic types across the language
                    boundary. This paper examines some of the trade-offs of the design,
                    points out some of its shortcomings, and outlines solutions that
                    simplify the use of atomic objects in both languages.




                    I am just learning about atomics now, but it looks like its compatible between C and CPP.






                    share|improve this answer














                    I found this on a net search https://developers.redhat.com/blog/2016/01/14/toward-a-better-use-of-c11-atomics-part-1/




                    Following the lead of C++, along with a memory model describing the
                    requirements and semantics of multithreaded programs, the C11 standard
                    adopted a proposal for a set of atomic types and operations into the
                    language. This change has made it possible to write portable
                    multi-threaded software that efficiently manipulates objects
                    indivisibly and without data races. The atomic types are fully
                    interoperable between the two languages so that programs can be
                    developed that share objects of atomic types across the language
                    boundary. This paper examines some of the trade-offs of the design,
                    points out some of its shortcomings, and outlines solutions that
                    simplify the use of atomic objects in both languages.




                    I am just learning about atomics now, but it looks like its compatible between C and CPP.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 1 hour ago

























                    answered 1 hour ago









                    Manny_Mar

                    1138




                    1138























                        0














                        how i understand your code in general is (must be) next



                        // c code

                        void _do_task();

                        void do_task(volatile bool *cancelled)
                        {
                        do {
                        _do_task();
                        } while (!*cancelled);
                        }

                        // c++ code

                        volatile bool g_cancelled;// can be modify by another thread
                        do_task(&cancelled);

                        void some_proc()
                        {
                        //...
                        g_cancelled = true;
                        }


                        i be ask question - are here we need declare cancelled as atomic ? are we need atomic here ?



                        atomic need in 3 case:





                        • we do Read-Modify-Write operation. say if we need set
                          cancelled to true and check are it was already true



                          if (cancelled.exchange(true)) { /**/} else {/**/}



                          but i doubt that here we need RMW operation on canceled



                        • the read or write operation for type need to be atomic. of course on
                          all current and all possible future implementations this is true for
                          bool type (despite formal not defined). but even this is not
                          important. we here check cancelled only for 2 values - 0 (false) and
                          all another. so even if both write and read operation on
                          cancelled assume not atomic, after one thread write non-zero to
                          canceled, another thread sooner or later will read modified non-zero value
                          from canceled . even if it will be another value, not the same
                          first thread write: for example if cancelled = true translated to
                          mov cancelled, -1; mov cancelled, 1 - two hardware, not atomic
                          operation - second thread can read -1 instead final 1 (true)
                          from canceled, but this not play role if we check only for non-zero - all
                          another values break loop - while (!*cancelled); if we use here atomic operation for write/read cancelled - nothing change here - after one thread atomic write to it another thread sooner or later will read modified non-zero value from canceled - atomic operation or not - memory is common - if one thread write to memory (atomic or no) another threads sooner or later will view this memory modification.

                        • we need synchronize another read/writes with cancelled. so we need
                          synchronization point between 2 threads around canceled with memory
                          order other than memory_order_relaxed say for example next code:


                        //



                        void _do_task();

                        int result;

                        void do_task(atomic_bool *cancelled)
                        {
                        do {
                        _do_task();
                        } while (!g_cancelled.load(memory_order_acquire));

                        switch(result)
                        {
                        case 1:
                        //...
                        break;
                        }
                        }

                        void some_proc()
                        {
                        result = 1;
                        g_cancelled.store(true, memory_order_release);
                        }


                        so we not simply set g_cancelled to true here, but before this

                        write some shared data (result) and want that another thread after
                        view modification of g_cancelled, will be also view modification of

                        shared data (result). but i doubt that you actually use/need this

                        scenario



                        if none of this 3 things is need- you not need atomic here. what you really need - that one thread just write true to cancelled and another thread all time read value of cancelled (instead do this once and cache result). usual in most case of code this will be done auto, but for be exactly you need declare canceled as volatile



                        if however you by some reason need exactly atomic (atomic_bool), because you here cross the border of languages, you need understand concrete implementation of atomic_bool in both languages and are it the same (type declaration, operations (load, store, etc)). by fact atomic_bool is the same for c and c++.



                        or (better) instead of make visible and share type atomic_bool use interface functions like



                        bool is_canceled(void* cancelled);



                        so code can be next



                        // c code
                        void _do_task();

                        bool is_canceled(void* cancelled);

                        void do_task(void *cancelled)
                        {
                        do {
                        _do_task();
                        } while (!is_canceled(cancelled));
                        }

                        // c++ code

                        atomic_bool g_cancelled;// can be modify by another thread

                        bool is_canceled(void* cancelled)
                        {
                        return *reinterpret_cast<atomic_bool*>(cancelled);
                        }

                        void some_proc()
                        {
                        //...
                        g_cancelled = true;
                        }

                        do_task(&g_cancelled);


                        but again i doubt that in your task you need atomic_bool by semantic. you need volatile bool






                        share|improve this answer


























                          0














                          how i understand your code in general is (must be) next



                          // c code

                          void _do_task();

                          void do_task(volatile bool *cancelled)
                          {
                          do {
                          _do_task();
                          } while (!*cancelled);
                          }

                          // c++ code

                          volatile bool g_cancelled;// can be modify by another thread
                          do_task(&cancelled);

                          void some_proc()
                          {
                          //...
                          g_cancelled = true;
                          }


                          i be ask question - are here we need declare cancelled as atomic ? are we need atomic here ?



                          atomic need in 3 case:





                          • we do Read-Modify-Write operation. say if we need set
                            cancelled to true and check are it was already true



                            if (cancelled.exchange(true)) { /**/} else {/**/}



                            but i doubt that here we need RMW operation on canceled



                          • the read or write operation for type need to be atomic. of course on
                            all current and all possible future implementations this is true for
                            bool type (despite formal not defined). but even this is not
                            important. we here check cancelled only for 2 values - 0 (false) and
                            all another. so even if both write and read operation on
                            cancelled assume not atomic, after one thread write non-zero to
                            canceled, another thread sooner or later will read modified non-zero value
                            from canceled . even if it will be another value, not the same
                            first thread write: for example if cancelled = true translated to
                            mov cancelled, -1; mov cancelled, 1 - two hardware, not atomic
                            operation - second thread can read -1 instead final 1 (true)
                            from canceled, but this not play role if we check only for non-zero - all
                            another values break loop - while (!*cancelled); if we use here atomic operation for write/read cancelled - nothing change here - after one thread atomic write to it another thread sooner or later will read modified non-zero value from canceled - atomic operation or not - memory is common - if one thread write to memory (atomic or no) another threads sooner or later will view this memory modification.

                          • we need synchronize another read/writes with cancelled. so we need
                            synchronization point between 2 threads around canceled with memory
                            order other than memory_order_relaxed say for example next code:


                          //



                          void _do_task();

                          int result;

                          void do_task(atomic_bool *cancelled)
                          {
                          do {
                          _do_task();
                          } while (!g_cancelled.load(memory_order_acquire));

                          switch(result)
                          {
                          case 1:
                          //...
                          break;
                          }
                          }

                          void some_proc()
                          {
                          result = 1;
                          g_cancelled.store(true, memory_order_release);
                          }


                          so we not simply set g_cancelled to true here, but before this

                          write some shared data (result) and want that another thread after
                          view modification of g_cancelled, will be also view modification of

                          shared data (result). but i doubt that you actually use/need this

                          scenario



                          if none of this 3 things is need- you not need atomic here. what you really need - that one thread just write true to cancelled and another thread all time read value of cancelled (instead do this once and cache result). usual in most case of code this will be done auto, but for be exactly you need declare canceled as volatile



                          if however you by some reason need exactly atomic (atomic_bool), because you here cross the border of languages, you need understand concrete implementation of atomic_bool in both languages and are it the same (type declaration, operations (load, store, etc)). by fact atomic_bool is the same for c and c++.



                          or (better) instead of make visible and share type atomic_bool use interface functions like



                          bool is_canceled(void* cancelled);



                          so code can be next



                          // c code
                          void _do_task();

                          bool is_canceled(void* cancelled);

                          void do_task(void *cancelled)
                          {
                          do {
                          _do_task();
                          } while (!is_canceled(cancelled));
                          }

                          // c++ code

                          atomic_bool g_cancelled;// can be modify by another thread

                          bool is_canceled(void* cancelled)
                          {
                          return *reinterpret_cast<atomic_bool*>(cancelled);
                          }

                          void some_proc()
                          {
                          //...
                          g_cancelled = true;
                          }

                          do_task(&g_cancelled);


                          but again i doubt that in your task you need atomic_bool by semantic. you need volatile bool






                          share|improve this answer
























                            0












                            0








                            0






                            how i understand your code in general is (must be) next



                            // c code

                            void _do_task();

                            void do_task(volatile bool *cancelled)
                            {
                            do {
                            _do_task();
                            } while (!*cancelled);
                            }

                            // c++ code

                            volatile bool g_cancelled;// can be modify by another thread
                            do_task(&cancelled);

                            void some_proc()
                            {
                            //...
                            g_cancelled = true;
                            }


                            i be ask question - are here we need declare cancelled as atomic ? are we need atomic here ?



                            atomic need in 3 case:





                            • we do Read-Modify-Write operation. say if we need set
                              cancelled to true and check are it was already true



                              if (cancelled.exchange(true)) { /**/} else {/**/}



                              but i doubt that here we need RMW operation on canceled



                            • the read or write operation for type need to be atomic. of course on
                              all current and all possible future implementations this is true for
                              bool type (despite formal not defined). but even this is not
                              important. we here check cancelled only for 2 values - 0 (false) and
                              all another. so even if both write and read operation on
                              cancelled assume not atomic, after one thread write non-zero to
                              canceled, another thread sooner or later will read modified non-zero value
                              from canceled . even if it will be another value, not the same
                              first thread write: for example if cancelled = true translated to
                              mov cancelled, -1; mov cancelled, 1 - two hardware, not atomic
                              operation - second thread can read -1 instead final 1 (true)
                              from canceled, but this not play role if we check only for non-zero - all
                              another values break loop - while (!*cancelled); if we use here atomic operation for write/read cancelled - nothing change here - after one thread atomic write to it another thread sooner or later will read modified non-zero value from canceled - atomic operation or not - memory is common - if one thread write to memory (atomic or no) another threads sooner or later will view this memory modification.

                            • we need synchronize another read/writes with cancelled. so we need
                              synchronization point between 2 threads around canceled with memory
                              order other than memory_order_relaxed say for example next code:


                            //



                            void _do_task();

                            int result;

                            void do_task(atomic_bool *cancelled)
                            {
                            do {
                            _do_task();
                            } while (!g_cancelled.load(memory_order_acquire));

                            switch(result)
                            {
                            case 1:
                            //...
                            break;
                            }
                            }

                            void some_proc()
                            {
                            result = 1;
                            g_cancelled.store(true, memory_order_release);
                            }


                            so we not simply set g_cancelled to true here, but before this

                            write some shared data (result) and want that another thread after
                            view modification of g_cancelled, will be also view modification of

                            shared data (result). but i doubt that you actually use/need this

                            scenario



                            if none of this 3 things is need- you not need atomic here. what you really need - that one thread just write true to cancelled and another thread all time read value of cancelled (instead do this once and cache result). usual in most case of code this will be done auto, but for be exactly you need declare canceled as volatile



                            if however you by some reason need exactly atomic (atomic_bool), because you here cross the border of languages, you need understand concrete implementation of atomic_bool in both languages and are it the same (type declaration, operations (load, store, etc)). by fact atomic_bool is the same for c and c++.



                            or (better) instead of make visible and share type atomic_bool use interface functions like



                            bool is_canceled(void* cancelled);



                            so code can be next



                            // c code
                            void _do_task();

                            bool is_canceled(void* cancelled);

                            void do_task(void *cancelled)
                            {
                            do {
                            _do_task();
                            } while (!is_canceled(cancelled));
                            }

                            // c++ code

                            atomic_bool g_cancelled;// can be modify by another thread

                            bool is_canceled(void* cancelled)
                            {
                            return *reinterpret_cast<atomic_bool*>(cancelled);
                            }

                            void some_proc()
                            {
                            //...
                            g_cancelled = true;
                            }

                            do_task(&g_cancelled);


                            but again i doubt that in your task you need atomic_bool by semantic. you need volatile bool






                            share|improve this answer












                            how i understand your code in general is (must be) next



                            // c code

                            void _do_task();

                            void do_task(volatile bool *cancelled)
                            {
                            do {
                            _do_task();
                            } while (!*cancelled);
                            }

                            // c++ code

                            volatile bool g_cancelled;// can be modify by another thread
                            do_task(&cancelled);

                            void some_proc()
                            {
                            //...
                            g_cancelled = true;
                            }


                            i be ask question - are here we need declare cancelled as atomic ? are we need atomic here ?



                            atomic need in 3 case:





                            • we do Read-Modify-Write operation. say if we need set
                              cancelled to true and check are it was already true



                              if (cancelled.exchange(true)) { /**/} else {/**/}



                              but i doubt that here we need RMW operation on canceled



                            • the read or write operation for type need to be atomic. of course on
                              all current and all possible future implementations this is true for
                              bool type (despite formal not defined). but even this is not
                              important. we here check cancelled only for 2 values - 0 (false) and
                              all another. so even if both write and read operation on
                              cancelled assume not atomic, after one thread write non-zero to
                              canceled, another thread sooner or later will read modified non-zero value
                              from canceled . even if it will be another value, not the same
                              first thread write: for example if cancelled = true translated to
                              mov cancelled, -1; mov cancelled, 1 - two hardware, not atomic
                              operation - second thread can read -1 instead final 1 (true)
                              from canceled, but this not play role if we check only for non-zero - all
                              another values break loop - while (!*cancelled); if we use here atomic operation for write/read cancelled - nothing change here - after one thread atomic write to it another thread sooner or later will read modified non-zero value from canceled - atomic operation or not - memory is common - if one thread write to memory (atomic or no) another threads sooner or later will view this memory modification.

                            • we need synchronize another read/writes with cancelled. so we need
                              synchronization point between 2 threads around canceled with memory
                              order other than memory_order_relaxed say for example next code:


                            //



                            void _do_task();

                            int result;

                            void do_task(atomic_bool *cancelled)
                            {
                            do {
                            _do_task();
                            } while (!g_cancelled.load(memory_order_acquire));

                            switch(result)
                            {
                            case 1:
                            //...
                            break;
                            }
                            }

                            void some_proc()
                            {
                            result = 1;
                            g_cancelled.store(true, memory_order_release);
                            }


                            so we not simply set g_cancelled to true here, but before this

                            write some shared data (result) and want that another thread after
                            view modification of g_cancelled, will be also view modification of

                            shared data (result). but i doubt that you actually use/need this

                            scenario



                            if none of this 3 things is need- you not need atomic here. what you really need - that one thread just write true to cancelled and another thread all time read value of cancelled (instead do this once and cache result). usual in most case of code this will be done auto, but for be exactly you need declare canceled as volatile



                            if however you by some reason need exactly atomic (atomic_bool), because you here cross the border of languages, you need understand concrete implementation of atomic_bool in both languages and are it the same (type declaration, operations (load, store, etc)). by fact atomic_bool is the same for c and c++.



                            or (better) instead of make visible and share type atomic_bool use interface functions like



                            bool is_canceled(void* cancelled);



                            so code can be next



                            // c code
                            void _do_task();

                            bool is_canceled(void* cancelled);

                            void do_task(void *cancelled)
                            {
                            do {
                            _do_task();
                            } while (!is_canceled(cancelled));
                            }

                            // c++ code

                            atomic_bool g_cancelled;// can be modify by another thread

                            bool is_canceled(void* cancelled)
                            {
                            return *reinterpret_cast<atomic_bool*>(cancelled);
                            }

                            void some_proc()
                            {
                            //...
                            g_cancelled = true;
                            }

                            do_task(&g_cancelled);


                            but again i doubt that in your task you need atomic_bool by semantic. you need volatile bool







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered 58 mins ago









                            RbMm

                            17k11224




                            17k11224























                                -2














                                Atomicity of operations is caused by hardware, not software (well, in C++ there are also "atomic" variables that are atomic in name only, those are implemented via mutexes and locks). So, basically, C++ atomics and C atomics do the very same thing. Hence as long as the types are compatible there won't be issues. And C++11 and C11 atomic classes were made to be compatible.





                                Apparently, people do not understand how atomics and locks work and require further explanation. Check out current memory models for more information.



                                1) We will start with basics. What and why are atomics? How does memory works?



                                Memory Model: think of processor as several independent cores and each has its own memory (cashes L1, L2, and L3; and in fact, L3 cash is common but it isn't really important).



                                Why do we need atomic operation?



                                If you don't use atomics, then each processor might have its own version of the variable 'x' and they are in general not synchronized. There is no telling when they will perform synchronizations with RAM/L3 cash.



                                When atomic operations are used, such memory operations are used that ensure synchronization with RAM/L3 cash (or whatever is needed) - ensuring that different cores have access to the same variable and not have variety of different versions of it.



                                Nobody cares if it is C, C++, or whatever language you use - as long as one ensures memory synchronization (both read, write, and modify) there will never be no issues.



                                2) OK, what about locks and mutexes?



                                Mutexes tend to work with OS and have queue over which thread should be allowed next to perform. And they enforce stricter memory synchronization than atomics do. With atomics one can syhchronize just the variable itself or more depending on the request / which function you call.



                                3) Say I have atomic_bool, can it work in interchangeably on different languages (C/C++11)?



                                Normally a boolean can be sychronized via memory operations (you're just synchronizing a single byte of memory from their perspective).
                                If the compilers are aware that the hardware can perform such operations then they surely will use them as long as you use the standard.



                                Logical atomics (any std::atomic< T > with T having wrong size/alignment) are synchronized via locks. In this case it is unlikely that different languages can use them interchangeably - if they have different methods of usage of these locks, or for some reason one decided to use a lock and the other one came to conclusion that it can work with atomic hardware memory synchronizations... then there will be issues.



                                If you use atomic_bool on any modern machine with C/C++, it will surely be able to synchronize without locks.






                                share|improve this answer










                                New contributor




                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.














                                • 5




                                  "And C++11 and C11 atomic classes were made to be compatible" Can you cite any source for this claim? Moreover, std::atomic_bool is not guaranteed to be lock free as opposed to std::atomic_flag.
                                  – idmean
                                  6 hours ago










                                • @idmean atomic_bool is not guaranteed to be lock free by the standart, as it doesn't require it to be. Whether it is lock free or not is something you ought to ask hardware whether it supports atomic operations. Locks are also in sense atomics, as they force more strict memory syncronization, while atomics allow way more relaxed memory sync.
                                  – ALX23z
                                  5 hours ago








                                • 5




                                  Recommend tightening up the focus and better explaining this answer. Right now it reads like a short answer question on a test where the student is throwing down whatever buzzwords they think will give them the most marks.
                                  – user4581301
                                  5 hours ago
















                                -2














                                Atomicity of operations is caused by hardware, not software (well, in C++ there are also "atomic" variables that are atomic in name only, those are implemented via mutexes and locks). So, basically, C++ atomics and C atomics do the very same thing. Hence as long as the types are compatible there won't be issues. And C++11 and C11 atomic classes were made to be compatible.





                                Apparently, people do not understand how atomics and locks work and require further explanation. Check out current memory models for more information.



                                1) We will start with basics. What and why are atomics? How does memory works?



                                Memory Model: think of processor as several independent cores and each has its own memory (cashes L1, L2, and L3; and in fact, L3 cash is common but it isn't really important).



                                Why do we need atomic operation?



                                If you don't use atomics, then each processor might have its own version of the variable 'x' and they are in general not synchronized. There is no telling when they will perform synchronizations with RAM/L3 cash.



                                When atomic operations are used, such memory operations are used that ensure synchronization with RAM/L3 cash (or whatever is needed) - ensuring that different cores have access to the same variable and not have variety of different versions of it.



                                Nobody cares if it is C, C++, or whatever language you use - as long as one ensures memory synchronization (both read, write, and modify) there will never be no issues.



                                2) OK, what about locks and mutexes?



                                Mutexes tend to work with OS and have queue over which thread should be allowed next to perform. And they enforce stricter memory synchronization than atomics do. With atomics one can syhchronize just the variable itself or more depending on the request / which function you call.



                                3) Say I have atomic_bool, can it work in interchangeably on different languages (C/C++11)?



                                Normally a boolean can be sychronized via memory operations (you're just synchronizing a single byte of memory from their perspective).
                                If the compilers are aware that the hardware can perform such operations then they surely will use them as long as you use the standard.



                                Logical atomics (any std::atomic< T > with T having wrong size/alignment) are synchronized via locks. In this case it is unlikely that different languages can use them interchangeably - if they have different methods of usage of these locks, or for some reason one decided to use a lock and the other one came to conclusion that it can work with atomic hardware memory synchronizations... then there will be issues.



                                If you use atomic_bool on any modern machine with C/C++, it will surely be able to synchronize without locks.






                                share|improve this answer










                                New contributor




                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.














                                • 5




                                  "And C++11 and C11 atomic classes were made to be compatible" Can you cite any source for this claim? Moreover, std::atomic_bool is not guaranteed to be lock free as opposed to std::atomic_flag.
                                  – idmean
                                  6 hours ago










                                • @idmean atomic_bool is not guaranteed to be lock free by the standart, as it doesn't require it to be. Whether it is lock free or not is something you ought to ask hardware whether it supports atomic operations. Locks are also in sense atomics, as they force more strict memory syncronization, while atomics allow way more relaxed memory sync.
                                  – ALX23z
                                  5 hours ago








                                • 5




                                  Recommend tightening up the focus and better explaining this answer. Right now it reads like a short answer question on a test where the student is throwing down whatever buzzwords they think will give them the most marks.
                                  – user4581301
                                  5 hours ago














                                -2












                                -2








                                -2






                                Atomicity of operations is caused by hardware, not software (well, in C++ there are also "atomic" variables that are atomic in name only, those are implemented via mutexes and locks). So, basically, C++ atomics and C atomics do the very same thing. Hence as long as the types are compatible there won't be issues. And C++11 and C11 atomic classes were made to be compatible.





                                Apparently, people do not understand how atomics and locks work and require further explanation. Check out current memory models for more information.



                                1) We will start with basics. What and why are atomics? How does memory works?



                                Memory Model: think of processor as several independent cores and each has its own memory (cashes L1, L2, and L3; and in fact, L3 cash is common but it isn't really important).



                                Why do we need atomic operation?



                                If you don't use atomics, then each processor might have its own version of the variable 'x' and they are in general not synchronized. There is no telling when they will perform synchronizations with RAM/L3 cash.



                                When atomic operations are used, such memory operations are used that ensure synchronization with RAM/L3 cash (or whatever is needed) - ensuring that different cores have access to the same variable and not have variety of different versions of it.



                                Nobody cares if it is C, C++, or whatever language you use - as long as one ensures memory synchronization (both read, write, and modify) there will never be no issues.



                                2) OK, what about locks and mutexes?



                                Mutexes tend to work with OS and have queue over which thread should be allowed next to perform. And they enforce stricter memory synchronization than atomics do. With atomics one can syhchronize just the variable itself or more depending on the request / which function you call.



                                3) Say I have atomic_bool, can it work in interchangeably on different languages (C/C++11)?



                                Normally a boolean can be sychronized via memory operations (you're just synchronizing a single byte of memory from their perspective).
                                If the compilers are aware that the hardware can perform such operations then they surely will use them as long as you use the standard.



                                Logical atomics (any std::atomic< T > with T having wrong size/alignment) are synchronized via locks. In this case it is unlikely that different languages can use them interchangeably - if they have different methods of usage of these locks, or for some reason one decided to use a lock and the other one came to conclusion that it can work with atomic hardware memory synchronizations... then there will be issues.



                                If you use atomic_bool on any modern machine with C/C++, it will surely be able to synchronize without locks.






                                share|improve this answer










                                New contributor




                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.









                                Atomicity of operations is caused by hardware, not software (well, in C++ there are also "atomic" variables that are atomic in name only, those are implemented via mutexes and locks). So, basically, C++ atomics and C atomics do the very same thing. Hence as long as the types are compatible there won't be issues. And C++11 and C11 atomic classes were made to be compatible.





                                Apparently, people do not understand how atomics and locks work and require further explanation. Check out current memory models for more information.



                                1) We will start with basics. What and why are atomics? How does memory works?



                                Memory Model: think of processor as several independent cores and each has its own memory (cashes L1, L2, and L3; and in fact, L3 cash is common but it isn't really important).



                                Why do we need atomic operation?



                                If you don't use atomics, then each processor might have its own version of the variable 'x' and they are in general not synchronized. There is no telling when they will perform synchronizations with RAM/L3 cash.



                                When atomic operations are used, such memory operations are used that ensure synchronization with RAM/L3 cash (or whatever is needed) - ensuring that different cores have access to the same variable and not have variety of different versions of it.



                                Nobody cares if it is C, C++, or whatever language you use - as long as one ensures memory synchronization (both read, write, and modify) there will never be no issues.



                                2) OK, what about locks and mutexes?



                                Mutexes tend to work with OS and have queue over which thread should be allowed next to perform. And they enforce stricter memory synchronization than atomics do. With atomics one can syhchronize just the variable itself or more depending on the request / which function you call.



                                3) Say I have atomic_bool, can it work in interchangeably on different languages (C/C++11)?



                                Normally a boolean can be sychronized via memory operations (you're just synchronizing a single byte of memory from their perspective).
                                If the compilers are aware that the hardware can perform such operations then they surely will use them as long as you use the standard.



                                Logical atomics (any std::atomic< T > with T having wrong size/alignment) are synchronized via locks. In this case it is unlikely that different languages can use them interchangeably - if they have different methods of usage of these locks, or for some reason one decided to use a lock and the other one came to conclusion that it can work with atomic hardware memory synchronizations... then there will be issues.



                                If you use atomic_bool on any modern machine with C/C++, it will surely be able to synchronize without locks.







                                share|improve this answer










                                New contributor




                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.









                                share|improve this answer



                                share|improve this answer








                                edited 3 hours ago





















                                New contributor




                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.









                                answered 6 hours ago









                                ALX23z

                                1165




                                1165




                                New contributor




                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.





                                New contributor





                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.






                                ALX23z is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                                Check out our Code of Conduct.








                                • 5




                                  "And C++11 and C11 atomic classes were made to be compatible" Can you cite any source for this claim? Moreover, std::atomic_bool is not guaranteed to be lock free as opposed to std::atomic_flag.
                                  – idmean
                                  6 hours ago










                                • @idmean atomic_bool is not guaranteed to be lock free by the standart, as it doesn't require it to be. Whether it is lock free or not is something you ought to ask hardware whether it supports atomic operations. Locks are also in sense atomics, as they force more strict memory syncronization, while atomics allow way more relaxed memory sync.
                                  – ALX23z
                                  5 hours ago








                                • 5




                                  Recommend tightening up the focus and better explaining this answer. Right now it reads like a short answer question on a test where the student is throwing down whatever buzzwords they think will give them the most marks.
                                  – user4581301
                                  5 hours ago














                                • 5




                                  "And C++11 and C11 atomic classes were made to be compatible" Can you cite any source for this claim? Moreover, std::atomic_bool is not guaranteed to be lock free as opposed to std::atomic_flag.
                                  – idmean
                                  6 hours ago










                                • @idmean atomic_bool is not guaranteed to be lock free by the standart, as it doesn't require it to be. Whether it is lock free or not is something you ought to ask hardware whether it supports atomic operations. Locks are also in sense atomics, as they force more strict memory syncronization, while atomics allow way more relaxed memory sync.
                                  – ALX23z
                                  5 hours ago








                                • 5




                                  Recommend tightening up the focus and better explaining this answer. Right now it reads like a short answer question on a test where the student is throwing down whatever buzzwords they think will give them the most marks.
                                  – user4581301
                                  5 hours ago








                                5




                                5




                                "And C++11 and C11 atomic classes were made to be compatible" Can you cite any source for this claim? Moreover, std::atomic_bool is not guaranteed to be lock free as opposed to std::atomic_flag.
                                – idmean
                                6 hours ago




                                "And C++11 and C11 atomic classes were made to be compatible" Can you cite any source for this claim? Moreover, std::atomic_bool is not guaranteed to be lock free as opposed to std::atomic_flag.
                                – idmean
                                6 hours ago












                                @idmean atomic_bool is not guaranteed to be lock free by the standart, as it doesn't require it to be. Whether it is lock free or not is something you ought to ask hardware whether it supports atomic operations. Locks are also in sense atomics, as they force more strict memory syncronization, while atomics allow way more relaxed memory sync.
                                – ALX23z
                                5 hours ago






                                @idmean atomic_bool is not guaranteed to be lock free by the standart, as it doesn't require it to be. Whether it is lock free or not is something you ought to ask hardware whether it supports atomic operations. Locks are also in sense atomics, as they force more strict memory syncronization, while atomics allow way more relaxed memory sync.
                                – ALX23z
                                5 hours ago






                                5




                                5




                                Recommend tightening up the focus and better explaining this answer. Right now it reads like a short answer question on a test where the student is throwing down whatever buzzwords they think will give them the most marks.
                                – user4581301
                                5 hours ago




                                Recommend tightening up the focus and better explaining this answer. Right now it reads like a short answer question on a test where the student is throwing down whatever buzzwords they think will give them the most marks.
                                – user4581301
                                5 hours ago


















                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53898429%2finteroperabilty-between-c-and-c-atomics%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                List directoties down one level, excluding some named directories and files

                                list processes belonging to a network namespace

                                list systemd RuntimeDirectory mounts