Barriers and synchronization points with non-atomic variables - data race?











up vote
6
down vote

favorite
2












Consider the following program:



int                        i{0};
std::experimental::barrier b{2};

int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};

std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};

t0.join();
t1.join();
}


Is this program guaranteed to print out 2, even though i is not an atomic variable?



According to cppreference:




Calls to arrive_and_wait synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.



Calls to arrive_and_drop and arrive_and_wait never introduce data races with themselves or each other.




This suggests that there is a synchronization point on each arrive_and_wait call. However I am not sure if the compiler is allowed to reorder the read/write operations on i, since it is non-atomic.










share|improve this question


















  • 4




    Bartop is right.. "Calls to arrive_and_wait() synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2) inter-thead happen before statements that are sequenced after B (cout << i). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
    – LWimsey
    Nov 21 at 7:55















up vote
6
down vote

favorite
2












Consider the following program:



int                        i{0};
std::experimental::barrier b{2};

int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};

std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};

t0.join();
t1.join();
}


Is this program guaranteed to print out 2, even though i is not an atomic variable?



According to cppreference:




Calls to arrive_and_wait synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.



Calls to arrive_and_drop and arrive_and_wait never introduce data races with themselves or each other.




This suggests that there is a synchronization point on each arrive_and_wait call. However I am not sure if the compiler is allowed to reorder the read/write operations on i, since it is non-atomic.










share|improve this question


















  • 4




    Bartop is right.. "Calls to arrive_and_wait() synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2) inter-thead happen before statements that are sequenced after B (cout << i). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
    – LWimsey
    Nov 21 at 7:55













up vote
6
down vote

favorite
2









up vote
6
down vote

favorite
2






2





Consider the following program:



int                        i{0};
std::experimental::barrier b{2};

int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};

std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};

t0.join();
t1.join();
}


Is this program guaranteed to print out 2, even though i is not an atomic variable?



According to cppreference:




Calls to arrive_and_wait synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.



Calls to arrive_and_drop and arrive_and_wait never introduce data races with themselves or each other.




This suggests that there is a synchronization point on each arrive_and_wait call. However I am not sure if the compiler is allowed to reorder the read/write operations on i, since it is non-atomic.










share|improve this question













Consider the following program:



int                        i{0};
std::experimental::barrier b{2};

int main()
{
std::thread t0{ {
b.arrive_and_wait();
std::cout << i << 'n';
}};

std::thread t1{ {
i = 2;
b.arrive_and_wait();
}};

t0.join();
t1.join();
}


Is this program guaranteed to print out 2, even though i is not an atomic variable?



According to cppreference:




Calls to arrive_and_wait synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.



Calls to arrive_and_drop and arrive_and_wait never introduce data races with themselves or each other.




This suggests that there is a synchronization point on each arrive_and_wait call. However I am not sure if the compiler is allowed to reorder the read/write operations on i, since it is non-atomic.







c++ multithreading concurrency language-lawyer barrier






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 at 11:06









Vittorio Romeo

56.1k17149289




56.1k17149289








  • 4




    Bartop is right.. "Calls to arrive_and_wait() synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2) inter-thead happen before statements that are sequenced after B (cout << i). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
    – LWimsey
    Nov 21 at 7:55














  • 4




    Bartop is right.. "Calls to arrive_and_wait() synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2) inter-thead happen before statements that are sequenced after B (cout << i). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
    – LWimsey
    Nov 21 at 7:55








4




4




Bartop is right.. "Calls to arrive_and_wait() synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2) inter-thead happen before statements that are sequenced after B (cout << i). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
– LWimsey
Nov 21 at 7:55




Bartop is right.. "Calls to arrive_and_wait() synchronize with the return from the call". Therein lies your answer.. If A synchronizes with B, statements sequenced before A (i = 2) inter-thead happen before statements that are sequenced after B (cout << i). Whether or not those statements are atomic is not relevant; It is the exact same mechanism that a mutex uses to synchronize non-atomic data between threads.
– LWimsey
Nov 21 at 7:55












1 Answer
1






active

oldest

votes

















up vote
3
down vote













From what I understand from std::barrier reference(my emphasis) :




A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.




you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):




Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true



1) A synchronizes-with B



2) A is dependency-ordered before B



3) A synchronizes-with some evaluation X, and X is sequenced-before B



4) A is sequenced-before some evaluation X, and X inter-thread happens-before B



5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B







share|improve this answer





















    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',
    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%2f53391637%2fbarriers-and-synchronization-points-with-non-atomic-variables-data-race%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote













    From what I understand from std::barrier reference(my emphasis) :




    A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.




    you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):




    Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true



    1) A synchronizes-with B



    2) A is dependency-ordered before B



    3) A synchronizes-with some evaluation X, and X is sequenced-before B



    4) A is sequenced-before some evaluation X, and X inter-thread happens-before B



    5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B







    share|improve this answer

























      up vote
      3
      down vote













      From what I understand from std::barrier reference(my emphasis) :




      A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.




      you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):




      Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true



      1) A synchronizes-with B



      2) A is dependency-ordered before B



      3) A synchronizes-with some evaluation X, and X is sequenced-before B



      4) A is sequenced-before some evaluation X, and X inter-thread happens-before B



      5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B







      share|improve this answer























        up vote
        3
        down vote










        up vote
        3
        down vote









        From what I understand from std::barrier reference(my emphasis) :




        A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.




        you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):




        Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true



        1) A synchronizes-with B



        2) A is dependency-ordered before B



        3) A synchronizes-with some evaluation X, and X is sequenced-before B



        4) A is sequenced-before some evaluation X, and X inter-thread happens-before B



        5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B







        share|improve this answer












        From what I understand from std::barrier reference(my emphasis) :




        A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.




        you can assume that all changes made before barrier in different threads are visible in other threads, even if they are not not atomic. As this reference points out (my emphasis):




        Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true



        1) A synchronizes-with B



        2) A is dependency-ordered before B



        3) A synchronizes-with some evaluation X, and X is sequenced-before B



        4) A is sequenced-before some evaluation X, and X inter-thread happens-before B



        5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B








        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 at 11:31









        bartop

        2,526825




        2,526825






























            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%2f53391637%2fbarriers-and-synchronization-points-with-non-atomic-variables-data-race%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

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            Refactoring coordinates for Minecraft Pi buildings written in Python