Can two sequential assignment statements in C be executed on hardware out of order?












5















Given the following C program:



static char vals[ 2 ] = {0, 0};

int main() {

char *a = &vals[0];
char *b = &vals[1];

while( 1 ) {

SOME_STUFF()

// non-atomic operations in critical section
if( SOME_CONDITION() )
{
*a = 1;
*b = 2;
}
else
{
*a = 0;
*b = 0;
}


SOME_OTHER_STUFF()

}

return 0;
}

int async_interrupt( void ) {

PRINT( a );
PRINT( b );
}


Is it possible for the hardware to actually load the value 2 into the memory location &vals[1] first, such that an interrupt routine could execute and see vals[1] == 2 and vals[0] == 0?



If this is possible, any description of the load/store operations that would result in this scenario would be much appreciated.



EDIT 1: Added a little more context to the code section. Unfortunately, I don't have the machine code from the compiled source.










share|improve this question




















  • 6





    Yes; it's also possible for the program to be optimized to int main() { return 0; } since it has no observable behaviour

    – M.M
    Nov 19 '18 at 22:52






  • 1





    It would improve the question to post an example of the "interrupt routine" you ask about. It would be undefined behaviour if an interrupt routine tried to access a or b, generally speaking, so this question might be moot. Also, some platforms provide stronger guarantees for interrupt routines than Standard C does.

    – M.M
    Nov 19 '18 at 23:08








  • 1





    Also UB if the interrupt routine accessed vals[0] or vals[1]. (a and b are locals with automatic storage, so there's no good way for an interrupt to get them. Not sure what the point of them is.)

    – Peter Cordes
    Nov 19 '18 at 23:23
















5















Given the following C program:



static char vals[ 2 ] = {0, 0};

int main() {

char *a = &vals[0];
char *b = &vals[1];

while( 1 ) {

SOME_STUFF()

// non-atomic operations in critical section
if( SOME_CONDITION() )
{
*a = 1;
*b = 2;
}
else
{
*a = 0;
*b = 0;
}


SOME_OTHER_STUFF()

}

return 0;
}

int async_interrupt( void ) {

PRINT( a );
PRINT( b );
}


Is it possible for the hardware to actually load the value 2 into the memory location &vals[1] first, such that an interrupt routine could execute and see vals[1] == 2 and vals[0] == 0?



If this is possible, any description of the load/store operations that would result in this scenario would be much appreciated.



EDIT 1: Added a little more context to the code section. Unfortunately, I don't have the machine code from the compiled source.










share|improve this question




















  • 6





    Yes; it's also possible for the program to be optimized to int main() { return 0; } since it has no observable behaviour

    – M.M
    Nov 19 '18 at 22:52






  • 1





    It would improve the question to post an example of the "interrupt routine" you ask about. It would be undefined behaviour if an interrupt routine tried to access a or b, generally speaking, so this question might be moot. Also, some platforms provide stronger guarantees for interrupt routines than Standard C does.

    – M.M
    Nov 19 '18 at 23:08








  • 1





    Also UB if the interrupt routine accessed vals[0] or vals[1]. (a and b are locals with automatic storage, so there's no good way for an interrupt to get them. Not sure what the point of them is.)

    – Peter Cordes
    Nov 19 '18 at 23:23














5












5








5


1






Given the following C program:



static char vals[ 2 ] = {0, 0};

int main() {

char *a = &vals[0];
char *b = &vals[1];

while( 1 ) {

SOME_STUFF()

// non-atomic operations in critical section
if( SOME_CONDITION() )
{
*a = 1;
*b = 2;
}
else
{
*a = 0;
*b = 0;
}


SOME_OTHER_STUFF()

}

return 0;
}

int async_interrupt( void ) {

PRINT( a );
PRINT( b );
}


Is it possible for the hardware to actually load the value 2 into the memory location &vals[1] first, such that an interrupt routine could execute and see vals[1] == 2 and vals[0] == 0?



If this is possible, any description of the load/store operations that would result in this scenario would be much appreciated.



EDIT 1: Added a little more context to the code section. Unfortunately, I don't have the machine code from the compiled source.










share|improve this question
















Given the following C program:



static char vals[ 2 ] = {0, 0};

int main() {

char *a = &vals[0];
char *b = &vals[1];

while( 1 ) {

SOME_STUFF()

// non-atomic operations in critical section
if( SOME_CONDITION() )
{
*a = 1;
*b = 2;
}
else
{
*a = 0;
*b = 0;
}


SOME_OTHER_STUFF()

}

return 0;
}

int async_interrupt( void ) {

PRINT( a );
PRINT( b );
}


Is it possible for the hardware to actually load the value 2 into the memory location &vals[1] first, such that an interrupt routine could execute and see vals[1] == 2 and vals[0] == 0?



If this is possible, any description of the load/store operations that would result in this scenario would be much appreciated.



EDIT 1: Added a little more context to the code section. Unfortunately, I don't have the machine code from the compiled source.







c memory-model






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '18 at 14:28







leo1

















asked Nov 19 '18 at 22:50









leo1leo1

316




316








  • 6





    Yes; it's also possible for the program to be optimized to int main() { return 0; } since it has no observable behaviour

    – M.M
    Nov 19 '18 at 22:52






  • 1





    It would improve the question to post an example of the "interrupt routine" you ask about. It would be undefined behaviour if an interrupt routine tried to access a or b, generally speaking, so this question might be moot. Also, some platforms provide stronger guarantees for interrupt routines than Standard C does.

    – M.M
    Nov 19 '18 at 23:08








  • 1





    Also UB if the interrupt routine accessed vals[0] or vals[1]. (a and b are locals with automatic storage, so there's no good way for an interrupt to get them. Not sure what the point of them is.)

    – Peter Cordes
    Nov 19 '18 at 23:23














  • 6





    Yes; it's also possible for the program to be optimized to int main() { return 0; } since it has no observable behaviour

    – M.M
    Nov 19 '18 at 22:52






  • 1





    It would improve the question to post an example of the "interrupt routine" you ask about. It would be undefined behaviour if an interrupt routine tried to access a or b, generally speaking, so this question might be moot. Also, some platforms provide stronger guarantees for interrupt routines than Standard C does.

    – M.M
    Nov 19 '18 at 23:08








  • 1





    Also UB if the interrupt routine accessed vals[0] or vals[1]. (a and b are locals with automatic storage, so there's no good way for an interrupt to get them. Not sure what the point of them is.)

    – Peter Cordes
    Nov 19 '18 at 23:23








6




6





Yes; it's also possible for the program to be optimized to int main() { return 0; } since it has no observable behaviour

– M.M
Nov 19 '18 at 22:52





Yes; it's also possible for the program to be optimized to int main() { return 0; } since it has no observable behaviour

– M.M
Nov 19 '18 at 22:52




1




1





It would improve the question to post an example of the "interrupt routine" you ask about. It would be undefined behaviour if an interrupt routine tried to access a or b, generally speaking, so this question might be moot. Also, some platforms provide stronger guarantees for interrupt routines than Standard C does.

– M.M
Nov 19 '18 at 23:08







It would improve the question to post an example of the "interrupt routine" you ask about. It would be undefined behaviour if an interrupt routine tried to access a or b, generally speaking, so this question might be moot. Also, some platforms provide stronger guarantees for interrupt routines than Standard C does.

– M.M
Nov 19 '18 at 23:08






1




1





Also UB if the interrupt routine accessed vals[0] or vals[1]. (a and b are locals with automatic storage, so there's no good way for an interrupt to get them. Not sure what the point of them is.)

– Peter Cordes
Nov 19 '18 at 23:23





Also UB if the interrupt routine accessed vals[0] or vals[1]. (a and b are locals with automatic storage, so there's no good way for an interrupt to get them. Not sure what the point of them is.)

– Peter Cordes
Nov 19 '18 at 23:23












2 Answers
2






active

oldest

votes


















4














Yes, it is possible because the compiler might re-order those statements as described in Peter's answer.



However, you might still be wondering about the other half: what hardware can do. Under the assumption that your stores end up in the assembly in the order you show in your source1, if an interrupt occurs on the same CPU that is running this code, from within the interrupt you'll see everything in a consistent order. That is, from within the interrupt handler, you'll never see the second store having completed, but the first not. The only scenarios you'll see are both not having completed, both completed or the first having completed and the second not.



If multiple cores are involved, and the interrupt may run on a different core, then you simply the classic cross-thread sharing scenarios, whether it is an interrupt or not - and what the other core can observe depends on the hardware memory model. For example, on the relatively strongly ordered x86, you would always observe the stores in order, where as on the more weakly ordered ARM or POWER memory models you could see the stores out of order.



In general, however, the CPU may be doing all sorts of reordering: the ordering you see within an interrupt handler is a special case where the CPU will restore the appearance of sequential execution at the point of handling the interrupt. The same is true of any case where a thread observes its own stores. However, when stores are observed by a different thread - what happens then depends on the hardware memory model, which varies a lot between architectures.





1 Assuming also that they show up separately - there is nothing stopping a smart compiler from noticing you are assigning to adjacent values in memory and hence transforming the two stores into a single wider one. Most compilers can do this in at least some scenarios.






share|improve this answer


























  • I believe this is what I'm looking for "from within the interrupt handler, you'll never see the second store having completed, but the first not.". However, my limited understanding of architectures, I was thinking that second store could possibly happen first due to some hardware nuances. Maybe that isn't the case.

    – leo1
    Nov 23 '18 at 14:32






  • 1





    @leo - an interrupt that actually interrupts the code in question (running on the same CPU that the code in question was running on) will always see a consistent view of the stores, just like code running on the CPU will see it's stores in source order. If another CPU is involved, then interrupt code (or any code really) running on that second CPU concurrently with the code doing the stores may see them out of order, depending on the hardware memory model.

    – BeeOnRope
    Nov 23 '18 at 15:16











  • @curiousguy - I'm not quite sure what you are referring to. If multiple threads are used and there is more than one CPU, and interrupts are not involved, then sure you can also see an inconsistent store order, depending on the hardware. Maybe you could clarify your question or create a separate one.

    – BeeOnRope
    Nov 27 '18 at 17:38











  • @curiousguy - I'm considering the case where an interrupt occurs as specified by the OP and show in their main() method. So I assume there are two execution contexts: the normal user context (single thread) running the stores, and the interrupt context, which may occur on the same CPU or a different CPU as the other context. When you ask about multiple threads, do you mean multiple threads running the store method? Multiple overlapping interrupts? It is not clear to me, since the original question doens't obviously involve threads.

    – BeeOnRope
    Nov 27 '18 at 17:49








  • 1





    @curiousguy - no, I'm not trying to say that (systems that I'm aware of will deliver the signal to the only thread if there is only one). In fact, I'm trying to more or less sidestep the whole issue of signal handling semantics, and answer the question as asked, with any necessary caveats. Note that the OP didn't even talk about signals, but simply "interrupts". I don't know what type of system they are using, or how these interrupts are delivered. Originally I assumed the interrupt would actually interrupt the code in question, I wrote my answer that way (as in "you'll be fine").

    – BeeOnRope
    Nov 27 '18 at 20:55



















10














C doesn't run on hardware directly. It has to be compiled first.



The specifics of undefined behaviour (like unsynchronized reads of non-atomic variables) totally depend on the implementation (including compile-time reordering in the compiler, and depending on the target CPU architecture, the runtime reordering rules of the that ISA).



Reads/writes of non-atomic variables are not considered an observable side-effect in C or C++, so they can be optimized away and reordered up to the limit of preserving the behaviour of the program as a whole (except when the program has undefined behaviour- optimizations can do anything in that case even if the compiler can't "see" there will be UB when it's compiling.)



See also https://preshing.com/20120625/memory-ordering-at-compile-time/






share|improve this answer



















  • 2





    As I commented in the thread under your answer: C only guarantees that causality applies within a single thread. The OP wants to read vals[0] and vals[1] from an interrupt handler, which runs asynchronously from the main thread so C doesn't guarantee anything about what it will find if it reads vals[0..1] without synchronization, and without that array being _Atomic. The whole point of _Atomic is to guarantee causality in cases like this that aren't synchronous single-threaded execution. Your answer arguing based on causality for non-atomic C variables is misleading at best.

    – Peter Cordes
    Nov 19 '18 at 23:43













  • Fair point. Thanks for the clarification.

    – Edwin Buck
    Nov 19 '18 at 23:45











  • @EdwinBuck: Was about to reply in the thread under your answer- I think you missed that the OP really did say "such that an interrupt routine could ...". So yes, we are talking about a case that goes outside the bounds of what C's as-if rule requires any code-transformations to preserve. Since you deleted your answer, I'm guessing you noticed that in the question now :)

    – Peter Cordes
    Nov 19 '18 at 23:50













  • Peter, if we assume that the C is compiled and linked such that the machine code is not optimized, do you know of any hardware nuances that could have somehow reordered the loading/storing of those values, such that the interrupt sees the second assigned, but not the first?

    – leo1
    Nov 23 '18 at 14:36






  • 1





    @curiousguy: I assume he meant "basic blocks", or just "blocks"/chunks of asm, like the definition for a whole function. Note that Edwin's deleted his misleading answer after I replied (but not the comment), so I don't think we need to pick at it any farther.

    – Peter Cordes
    Nov 27 '18 at 20:19













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%2f53383781%2fcan-two-sequential-assignment-statements-in-c-be-executed-on-hardware-out-of-ord%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














Yes, it is possible because the compiler might re-order those statements as described in Peter's answer.



However, you might still be wondering about the other half: what hardware can do. Under the assumption that your stores end up in the assembly in the order you show in your source1, if an interrupt occurs on the same CPU that is running this code, from within the interrupt you'll see everything in a consistent order. That is, from within the interrupt handler, you'll never see the second store having completed, but the first not. The only scenarios you'll see are both not having completed, both completed or the first having completed and the second not.



If multiple cores are involved, and the interrupt may run on a different core, then you simply the classic cross-thread sharing scenarios, whether it is an interrupt or not - and what the other core can observe depends on the hardware memory model. For example, on the relatively strongly ordered x86, you would always observe the stores in order, where as on the more weakly ordered ARM or POWER memory models you could see the stores out of order.



In general, however, the CPU may be doing all sorts of reordering: the ordering you see within an interrupt handler is a special case where the CPU will restore the appearance of sequential execution at the point of handling the interrupt. The same is true of any case where a thread observes its own stores. However, when stores are observed by a different thread - what happens then depends on the hardware memory model, which varies a lot between architectures.





1 Assuming also that they show up separately - there is nothing stopping a smart compiler from noticing you are assigning to adjacent values in memory and hence transforming the two stores into a single wider one. Most compilers can do this in at least some scenarios.






share|improve this answer


























  • I believe this is what I'm looking for "from within the interrupt handler, you'll never see the second store having completed, but the first not.". However, my limited understanding of architectures, I was thinking that second store could possibly happen first due to some hardware nuances. Maybe that isn't the case.

    – leo1
    Nov 23 '18 at 14:32






  • 1





    @leo - an interrupt that actually interrupts the code in question (running on the same CPU that the code in question was running on) will always see a consistent view of the stores, just like code running on the CPU will see it's stores in source order. If another CPU is involved, then interrupt code (or any code really) running on that second CPU concurrently with the code doing the stores may see them out of order, depending on the hardware memory model.

    – BeeOnRope
    Nov 23 '18 at 15:16











  • @curiousguy - I'm not quite sure what you are referring to. If multiple threads are used and there is more than one CPU, and interrupts are not involved, then sure you can also see an inconsistent store order, depending on the hardware. Maybe you could clarify your question or create a separate one.

    – BeeOnRope
    Nov 27 '18 at 17:38











  • @curiousguy - I'm considering the case where an interrupt occurs as specified by the OP and show in their main() method. So I assume there are two execution contexts: the normal user context (single thread) running the stores, and the interrupt context, which may occur on the same CPU or a different CPU as the other context. When you ask about multiple threads, do you mean multiple threads running the store method? Multiple overlapping interrupts? It is not clear to me, since the original question doens't obviously involve threads.

    – BeeOnRope
    Nov 27 '18 at 17:49








  • 1





    @curiousguy - no, I'm not trying to say that (systems that I'm aware of will deliver the signal to the only thread if there is only one). In fact, I'm trying to more or less sidestep the whole issue of signal handling semantics, and answer the question as asked, with any necessary caveats. Note that the OP didn't even talk about signals, but simply "interrupts". I don't know what type of system they are using, or how these interrupts are delivered. Originally I assumed the interrupt would actually interrupt the code in question, I wrote my answer that way (as in "you'll be fine").

    – BeeOnRope
    Nov 27 '18 at 20:55
















4














Yes, it is possible because the compiler might re-order those statements as described in Peter's answer.



However, you might still be wondering about the other half: what hardware can do. Under the assumption that your stores end up in the assembly in the order you show in your source1, if an interrupt occurs on the same CPU that is running this code, from within the interrupt you'll see everything in a consistent order. That is, from within the interrupt handler, you'll never see the second store having completed, but the first not. The only scenarios you'll see are both not having completed, both completed or the first having completed and the second not.



If multiple cores are involved, and the interrupt may run on a different core, then you simply the classic cross-thread sharing scenarios, whether it is an interrupt or not - and what the other core can observe depends on the hardware memory model. For example, on the relatively strongly ordered x86, you would always observe the stores in order, where as on the more weakly ordered ARM or POWER memory models you could see the stores out of order.



In general, however, the CPU may be doing all sorts of reordering: the ordering you see within an interrupt handler is a special case where the CPU will restore the appearance of sequential execution at the point of handling the interrupt. The same is true of any case where a thread observes its own stores. However, when stores are observed by a different thread - what happens then depends on the hardware memory model, which varies a lot between architectures.





1 Assuming also that they show up separately - there is nothing stopping a smart compiler from noticing you are assigning to adjacent values in memory and hence transforming the two stores into a single wider one. Most compilers can do this in at least some scenarios.






share|improve this answer


























  • I believe this is what I'm looking for "from within the interrupt handler, you'll never see the second store having completed, but the first not.". However, my limited understanding of architectures, I was thinking that second store could possibly happen first due to some hardware nuances. Maybe that isn't the case.

    – leo1
    Nov 23 '18 at 14:32






  • 1





    @leo - an interrupt that actually interrupts the code in question (running on the same CPU that the code in question was running on) will always see a consistent view of the stores, just like code running on the CPU will see it's stores in source order. If another CPU is involved, then interrupt code (or any code really) running on that second CPU concurrently with the code doing the stores may see them out of order, depending on the hardware memory model.

    – BeeOnRope
    Nov 23 '18 at 15:16











  • @curiousguy - I'm not quite sure what you are referring to. If multiple threads are used and there is more than one CPU, and interrupts are not involved, then sure you can also see an inconsistent store order, depending on the hardware. Maybe you could clarify your question or create a separate one.

    – BeeOnRope
    Nov 27 '18 at 17:38











  • @curiousguy - I'm considering the case where an interrupt occurs as specified by the OP and show in their main() method. So I assume there are two execution contexts: the normal user context (single thread) running the stores, and the interrupt context, which may occur on the same CPU or a different CPU as the other context. When you ask about multiple threads, do you mean multiple threads running the store method? Multiple overlapping interrupts? It is not clear to me, since the original question doens't obviously involve threads.

    – BeeOnRope
    Nov 27 '18 at 17:49








  • 1





    @curiousguy - no, I'm not trying to say that (systems that I'm aware of will deliver the signal to the only thread if there is only one). In fact, I'm trying to more or less sidestep the whole issue of signal handling semantics, and answer the question as asked, with any necessary caveats. Note that the OP didn't even talk about signals, but simply "interrupts". I don't know what type of system they are using, or how these interrupts are delivered. Originally I assumed the interrupt would actually interrupt the code in question, I wrote my answer that way (as in "you'll be fine").

    – BeeOnRope
    Nov 27 '18 at 20:55














4












4








4







Yes, it is possible because the compiler might re-order those statements as described in Peter's answer.



However, you might still be wondering about the other half: what hardware can do. Under the assumption that your stores end up in the assembly in the order you show in your source1, if an interrupt occurs on the same CPU that is running this code, from within the interrupt you'll see everything in a consistent order. That is, from within the interrupt handler, you'll never see the second store having completed, but the first not. The only scenarios you'll see are both not having completed, both completed or the first having completed and the second not.



If multiple cores are involved, and the interrupt may run on a different core, then you simply the classic cross-thread sharing scenarios, whether it is an interrupt or not - and what the other core can observe depends on the hardware memory model. For example, on the relatively strongly ordered x86, you would always observe the stores in order, where as on the more weakly ordered ARM or POWER memory models you could see the stores out of order.



In general, however, the CPU may be doing all sorts of reordering: the ordering you see within an interrupt handler is a special case where the CPU will restore the appearance of sequential execution at the point of handling the interrupt. The same is true of any case where a thread observes its own stores. However, when stores are observed by a different thread - what happens then depends on the hardware memory model, which varies a lot between architectures.





1 Assuming also that they show up separately - there is nothing stopping a smart compiler from noticing you are assigning to adjacent values in memory and hence transforming the two stores into a single wider one. Most compilers can do this in at least some scenarios.






share|improve this answer















Yes, it is possible because the compiler might re-order those statements as described in Peter's answer.



However, you might still be wondering about the other half: what hardware can do. Under the assumption that your stores end up in the assembly in the order you show in your source1, if an interrupt occurs on the same CPU that is running this code, from within the interrupt you'll see everything in a consistent order. That is, from within the interrupt handler, you'll never see the second store having completed, but the first not. The only scenarios you'll see are both not having completed, both completed or the first having completed and the second not.



If multiple cores are involved, and the interrupt may run on a different core, then you simply the classic cross-thread sharing scenarios, whether it is an interrupt or not - and what the other core can observe depends on the hardware memory model. For example, on the relatively strongly ordered x86, you would always observe the stores in order, where as on the more weakly ordered ARM or POWER memory models you could see the stores out of order.



In general, however, the CPU may be doing all sorts of reordering: the ordering you see within an interrupt handler is a special case where the CPU will restore the appearance of sequential execution at the point of handling the interrupt. The same is true of any case where a thread observes its own stores. However, when stores are observed by a different thread - what happens then depends on the hardware memory model, which varies a lot between architectures.





1 Assuming also that they show up separately - there is nothing stopping a smart compiler from noticing you are assigning to adjacent values in memory and hence transforming the two stores into a single wider one. Most compilers can do this in at least some scenarios.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 23 '18 at 23:40

























answered Nov 20 '18 at 3:03









BeeOnRopeBeeOnRope

25.1k875172




25.1k875172













  • I believe this is what I'm looking for "from within the interrupt handler, you'll never see the second store having completed, but the first not.". However, my limited understanding of architectures, I was thinking that second store could possibly happen first due to some hardware nuances. Maybe that isn't the case.

    – leo1
    Nov 23 '18 at 14:32






  • 1





    @leo - an interrupt that actually interrupts the code in question (running on the same CPU that the code in question was running on) will always see a consistent view of the stores, just like code running on the CPU will see it's stores in source order. If another CPU is involved, then interrupt code (or any code really) running on that second CPU concurrently with the code doing the stores may see them out of order, depending on the hardware memory model.

    – BeeOnRope
    Nov 23 '18 at 15:16











  • @curiousguy - I'm not quite sure what you are referring to. If multiple threads are used and there is more than one CPU, and interrupts are not involved, then sure you can also see an inconsistent store order, depending on the hardware. Maybe you could clarify your question or create a separate one.

    – BeeOnRope
    Nov 27 '18 at 17:38











  • @curiousguy - I'm considering the case where an interrupt occurs as specified by the OP and show in their main() method. So I assume there are two execution contexts: the normal user context (single thread) running the stores, and the interrupt context, which may occur on the same CPU or a different CPU as the other context. When you ask about multiple threads, do you mean multiple threads running the store method? Multiple overlapping interrupts? It is not clear to me, since the original question doens't obviously involve threads.

    – BeeOnRope
    Nov 27 '18 at 17:49








  • 1





    @curiousguy - no, I'm not trying to say that (systems that I'm aware of will deliver the signal to the only thread if there is only one). In fact, I'm trying to more or less sidestep the whole issue of signal handling semantics, and answer the question as asked, with any necessary caveats. Note that the OP didn't even talk about signals, but simply "interrupts". I don't know what type of system they are using, or how these interrupts are delivered. Originally I assumed the interrupt would actually interrupt the code in question, I wrote my answer that way (as in "you'll be fine").

    – BeeOnRope
    Nov 27 '18 at 20:55



















  • I believe this is what I'm looking for "from within the interrupt handler, you'll never see the second store having completed, but the first not.". However, my limited understanding of architectures, I was thinking that second store could possibly happen first due to some hardware nuances. Maybe that isn't the case.

    – leo1
    Nov 23 '18 at 14:32






  • 1





    @leo - an interrupt that actually interrupts the code in question (running on the same CPU that the code in question was running on) will always see a consistent view of the stores, just like code running on the CPU will see it's stores in source order. If another CPU is involved, then interrupt code (or any code really) running on that second CPU concurrently with the code doing the stores may see them out of order, depending on the hardware memory model.

    – BeeOnRope
    Nov 23 '18 at 15:16











  • @curiousguy - I'm not quite sure what you are referring to. If multiple threads are used and there is more than one CPU, and interrupts are not involved, then sure you can also see an inconsistent store order, depending on the hardware. Maybe you could clarify your question or create a separate one.

    – BeeOnRope
    Nov 27 '18 at 17:38











  • @curiousguy - I'm considering the case where an interrupt occurs as specified by the OP and show in their main() method. So I assume there are two execution contexts: the normal user context (single thread) running the stores, and the interrupt context, which may occur on the same CPU or a different CPU as the other context. When you ask about multiple threads, do you mean multiple threads running the store method? Multiple overlapping interrupts? It is not clear to me, since the original question doens't obviously involve threads.

    – BeeOnRope
    Nov 27 '18 at 17:49








  • 1





    @curiousguy - no, I'm not trying to say that (systems that I'm aware of will deliver the signal to the only thread if there is only one). In fact, I'm trying to more or less sidestep the whole issue of signal handling semantics, and answer the question as asked, with any necessary caveats. Note that the OP didn't even talk about signals, but simply "interrupts". I don't know what type of system they are using, or how these interrupts are delivered. Originally I assumed the interrupt would actually interrupt the code in question, I wrote my answer that way (as in "you'll be fine").

    – BeeOnRope
    Nov 27 '18 at 20:55

















I believe this is what I'm looking for "from within the interrupt handler, you'll never see the second store having completed, but the first not.". However, my limited understanding of architectures, I was thinking that second store could possibly happen first due to some hardware nuances. Maybe that isn't the case.

– leo1
Nov 23 '18 at 14:32





I believe this is what I'm looking for "from within the interrupt handler, you'll never see the second store having completed, but the first not.". However, my limited understanding of architectures, I was thinking that second store could possibly happen first due to some hardware nuances. Maybe that isn't the case.

– leo1
Nov 23 '18 at 14:32




1




1





@leo - an interrupt that actually interrupts the code in question (running on the same CPU that the code in question was running on) will always see a consistent view of the stores, just like code running on the CPU will see it's stores in source order. If another CPU is involved, then interrupt code (or any code really) running on that second CPU concurrently with the code doing the stores may see them out of order, depending on the hardware memory model.

– BeeOnRope
Nov 23 '18 at 15:16





@leo - an interrupt that actually interrupts the code in question (running on the same CPU that the code in question was running on) will always see a consistent view of the stores, just like code running on the CPU will see it's stores in source order. If another CPU is involved, then interrupt code (or any code really) running on that second CPU concurrently with the code doing the stores may see them out of order, depending on the hardware memory model.

– BeeOnRope
Nov 23 '18 at 15:16













@curiousguy - I'm not quite sure what you are referring to. If multiple threads are used and there is more than one CPU, and interrupts are not involved, then sure you can also see an inconsistent store order, depending on the hardware. Maybe you could clarify your question or create a separate one.

– BeeOnRope
Nov 27 '18 at 17:38





@curiousguy - I'm not quite sure what you are referring to. If multiple threads are used and there is more than one CPU, and interrupts are not involved, then sure you can also see an inconsistent store order, depending on the hardware. Maybe you could clarify your question or create a separate one.

– BeeOnRope
Nov 27 '18 at 17:38













@curiousguy - I'm considering the case where an interrupt occurs as specified by the OP and show in their main() method. So I assume there are two execution contexts: the normal user context (single thread) running the stores, and the interrupt context, which may occur on the same CPU or a different CPU as the other context. When you ask about multiple threads, do you mean multiple threads running the store method? Multiple overlapping interrupts? It is not clear to me, since the original question doens't obviously involve threads.

– BeeOnRope
Nov 27 '18 at 17:49







@curiousguy - I'm considering the case where an interrupt occurs as specified by the OP and show in their main() method. So I assume there are two execution contexts: the normal user context (single thread) running the stores, and the interrupt context, which may occur on the same CPU or a different CPU as the other context. When you ask about multiple threads, do you mean multiple threads running the store method? Multiple overlapping interrupts? It is not clear to me, since the original question doens't obviously involve threads.

– BeeOnRope
Nov 27 '18 at 17:49






1




1





@curiousguy - no, I'm not trying to say that (systems that I'm aware of will deliver the signal to the only thread if there is only one). In fact, I'm trying to more or less sidestep the whole issue of signal handling semantics, and answer the question as asked, with any necessary caveats. Note that the OP didn't even talk about signals, but simply "interrupts". I don't know what type of system they are using, or how these interrupts are delivered. Originally I assumed the interrupt would actually interrupt the code in question, I wrote my answer that way (as in "you'll be fine").

– BeeOnRope
Nov 27 '18 at 20:55





@curiousguy - no, I'm not trying to say that (systems that I'm aware of will deliver the signal to the only thread if there is only one). In fact, I'm trying to more or less sidestep the whole issue of signal handling semantics, and answer the question as asked, with any necessary caveats. Note that the OP didn't even talk about signals, but simply "interrupts". I don't know what type of system they are using, or how these interrupts are delivered. Originally I assumed the interrupt would actually interrupt the code in question, I wrote my answer that way (as in "you'll be fine").

– BeeOnRope
Nov 27 '18 at 20:55













10














C doesn't run on hardware directly. It has to be compiled first.



The specifics of undefined behaviour (like unsynchronized reads of non-atomic variables) totally depend on the implementation (including compile-time reordering in the compiler, and depending on the target CPU architecture, the runtime reordering rules of the that ISA).



Reads/writes of non-atomic variables are not considered an observable side-effect in C or C++, so they can be optimized away and reordered up to the limit of preserving the behaviour of the program as a whole (except when the program has undefined behaviour- optimizations can do anything in that case even if the compiler can't "see" there will be UB when it's compiling.)



See also https://preshing.com/20120625/memory-ordering-at-compile-time/






share|improve this answer



















  • 2





    As I commented in the thread under your answer: C only guarantees that causality applies within a single thread. The OP wants to read vals[0] and vals[1] from an interrupt handler, which runs asynchronously from the main thread so C doesn't guarantee anything about what it will find if it reads vals[0..1] without synchronization, and without that array being _Atomic. The whole point of _Atomic is to guarantee causality in cases like this that aren't synchronous single-threaded execution. Your answer arguing based on causality for non-atomic C variables is misleading at best.

    – Peter Cordes
    Nov 19 '18 at 23:43













  • Fair point. Thanks for the clarification.

    – Edwin Buck
    Nov 19 '18 at 23:45











  • @EdwinBuck: Was about to reply in the thread under your answer- I think you missed that the OP really did say "such that an interrupt routine could ...". So yes, we are talking about a case that goes outside the bounds of what C's as-if rule requires any code-transformations to preserve. Since you deleted your answer, I'm guessing you noticed that in the question now :)

    – Peter Cordes
    Nov 19 '18 at 23:50













  • Peter, if we assume that the C is compiled and linked such that the machine code is not optimized, do you know of any hardware nuances that could have somehow reordered the loading/storing of those values, such that the interrupt sees the second assigned, but not the first?

    – leo1
    Nov 23 '18 at 14:36






  • 1





    @curiousguy: I assume he meant "basic blocks", or just "blocks"/chunks of asm, like the definition for a whole function. Note that Edwin's deleted his misleading answer after I replied (but not the comment), so I don't think we need to pick at it any farther.

    – Peter Cordes
    Nov 27 '18 at 20:19


















10














C doesn't run on hardware directly. It has to be compiled first.



The specifics of undefined behaviour (like unsynchronized reads of non-atomic variables) totally depend on the implementation (including compile-time reordering in the compiler, and depending on the target CPU architecture, the runtime reordering rules of the that ISA).



Reads/writes of non-atomic variables are not considered an observable side-effect in C or C++, so they can be optimized away and reordered up to the limit of preserving the behaviour of the program as a whole (except when the program has undefined behaviour- optimizations can do anything in that case even if the compiler can't "see" there will be UB when it's compiling.)



See also https://preshing.com/20120625/memory-ordering-at-compile-time/






share|improve this answer



















  • 2





    As I commented in the thread under your answer: C only guarantees that causality applies within a single thread. The OP wants to read vals[0] and vals[1] from an interrupt handler, which runs asynchronously from the main thread so C doesn't guarantee anything about what it will find if it reads vals[0..1] without synchronization, and without that array being _Atomic. The whole point of _Atomic is to guarantee causality in cases like this that aren't synchronous single-threaded execution. Your answer arguing based on causality for non-atomic C variables is misleading at best.

    – Peter Cordes
    Nov 19 '18 at 23:43













  • Fair point. Thanks for the clarification.

    – Edwin Buck
    Nov 19 '18 at 23:45











  • @EdwinBuck: Was about to reply in the thread under your answer- I think you missed that the OP really did say "such that an interrupt routine could ...". So yes, we are talking about a case that goes outside the bounds of what C's as-if rule requires any code-transformations to preserve. Since you deleted your answer, I'm guessing you noticed that in the question now :)

    – Peter Cordes
    Nov 19 '18 at 23:50













  • Peter, if we assume that the C is compiled and linked such that the machine code is not optimized, do you know of any hardware nuances that could have somehow reordered the loading/storing of those values, such that the interrupt sees the second assigned, but not the first?

    – leo1
    Nov 23 '18 at 14:36






  • 1





    @curiousguy: I assume he meant "basic blocks", or just "blocks"/chunks of asm, like the definition for a whole function. Note that Edwin's deleted his misleading answer after I replied (but not the comment), so I don't think we need to pick at it any farther.

    – Peter Cordes
    Nov 27 '18 at 20:19
















10












10








10







C doesn't run on hardware directly. It has to be compiled first.



The specifics of undefined behaviour (like unsynchronized reads of non-atomic variables) totally depend on the implementation (including compile-time reordering in the compiler, and depending on the target CPU architecture, the runtime reordering rules of the that ISA).



Reads/writes of non-atomic variables are not considered an observable side-effect in C or C++, so they can be optimized away and reordered up to the limit of preserving the behaviour of the program as a whole (except when the program has undefined behaviour- optimizations can do anything in that case even if the compiler can't "see" there will be UB when it's compiling.)



See also https://preshing.com/20120625/memory-ordering-at-compile-time/






share|improve this answer













C doesn't run on hardware directly. It has to be compiled first.



The specifics of undefined behaviour (like unsynchronized reads of non-atomic variables) totally depend on the implementation (including compile-time reordering in the compiler, and depending on the target CPU architecture, the runtime reordering rules of the that ISA).



Reads/writes of non-atomic variables are not considered an observable side-effect in C or C++, so they can be optimized away and reordered up to the limit of preserving the behaviour of the program as a whole (except when the program has undefined behaviour- optimizations can do anything in that case even if the compiler can't "see" there will be UB when it's compiling.)



See also https://preshing.com/20120625/memory-ordering-at-compile-time/







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 19 '18 at 23:07









Peter CordesPeter Cordes

121k17184312




121k17184312








  • 2





    As I commented in the thread under your answer: C only guarantees that causality applies within a single thread. The OP wants to read vals[0] and vals[1] from an interrupt handler, which runs asynchronously from the main thread so C doesn't guarantee anything about what it will find if it reads vals[0..1] without synchronization, and without that array being _Atomic. The whole point of _Atomic is to guarantee causality in cases like this that aren't synchronous single-threaded execution. Your answer arguing based on causality for non-atomic C variables is misleading at best.

    – Peter Cordes
    Nov 19 '18 at 23:43













  • Fair point. Thanks for the clarification.

    – Edwin Buck
    Nov 19 '18 at 23:45











  • @EdwinBuck: Was about to reply in the thread under your answer- I think you missed that the OP really did say "such that an interrupt routine could ...". So yes, we are talking about a case that goes outside the bounds of what C's as-if rule requires any code-transformations to preserve. Since you deleted your answer, I'm guessing you noticed that in the question now :)

    – Peter Cordes
    Nov 19 '18 at 23:50













  • Peter, if we assume that the C is compiled and linked such that the machine code is not optimized, do you know of any hardware nuances that could have somehow reordered the loading/storing of those values, such that the interrupt sees the second assigned, but not the first?

    – leo1
    Nov 23 '18 at 14:36






  • 1





    @curiousguy: I assume he meant "basic blocks", or just "blocks"/chunks of asm, like the definition for a whole function. Note that Edwin's deleted his misleading answer after I replied (but not the comment), so I don't think we need to pick at it any farther.

    – Peter Cordes
    Nov 27 '18 at 20:19
















  • 2





    As I commented in the thread under your answer: C only guarantees that causality applies within a single thread. The OP wants to read vals[0] and vals[1] from an interrupt handler, which runs asynchronously from the main thread so C doesn't guarantee anything about what it will find if it reads vals[0..1] without synchronization, and without that array being _Atomic. The whole point of _Atomic is to guarantee causality in cases like this that aren't synchronous single-threaded execution. Your answer arguing based on causality for non-atomic C variables is misleading at best.

    – Peter Cordes
    Nov 19 '18 at 23:43













  • Fair point. Thanks for the clarification.

    – Edwin Buck
    Nov 19 '18 at 23:45











  • @EdwinBuck: Was about to reply in the thread under your answer- I think you missed that the OP really did say "such that an interrupt routine could ...". So yes, we are talking about a case that goes outside the bounds of what C's as-if rule requires any code-transformations to preserve. Since you deleted your answer, I'm guessing you noticed that in the question now :)

    – Peter Cordes
    Nov 19 '18 at 23:50













  • Peter, if we assume that the C is compiled and linked such that the machine code is not optimized, do you know of any hardware nuances that could have somehow reordered the loading/storing of those values, such that the interrupt sees the second assigned, but not the first?

    – leo1
    Nov 23 '18 at 14:36






  • 1





    @curiousguy: I assume he meant "basic blocks", or just "blocks"/chunks of asm, like the definition for a whole function. Note that Edwin's deleted his misleading answer after I replied (but not the comment), so I don't think we need to pick at it any farther.

    – Peter Cordes
    Nov 27 '18 at 20:19










2




2





As I commented in the thread under your answer: C only guarantees that causality applies within a single thread. The OP wants to read vals[0] and vals[1] from an interrupt handler, which runs asynchronously from the main thread so C doesn't guarantee anything about what it will find if it reads vals[0..1] without synchronization, and without that array being _Atomic. The whole point of _Atomic is to guarantee causality in cases like this that aren't synchronous single-threaded execution. Your answer arguing based on causality for non-atomic C variables is misleading at best.

– Peter Cordes
Nov 19 '18 at 23:43







As I commented in the thread under your answer: C only guarantees that causality applies within a single thread. The OP wants to read vals[0] and vals[1] from an interrupt handler, which runs asynchronously from the main thread so C doesn't guarantee anything about what it will find if it reads vals[0..1] without synchronization, and without that array being _Atomic. The whole point of _Atomic is to guarantee causality in cases like this that aren't synchronous single-threaded execution. Your answer arguing based on causality for non-atomic C variables is misleading at best.

– Peter Cordes
Nov 19 '18 at 23:43















Fair point. Thanks for the clarification.

– Edwin Buck
Nov 19 '18 at 23:45





Fair point. Thanks for the clarification.

– Edwin Buck
Nov 19 '18 at 23:45













@EdwinBuck: Was about to reply in the thread under your answer- I think you missed that the OP really did say "such that an interrupt routine could ...". So yes, we are talking about a case that goes outside the bounds of what C's as-if rule requires any code-transformations to preserve. Since you deleted your answer, I'm guessing you noticed that in the question now :)

– Peter Cordes
Nov 19 '18 at 23:50







@EdwinBuck: Was about to reply in the thread under your answer- I think you missed that the OP really did say "such that an interrupt routine could ...". So yes, we are talking about a case that goes outside the bounds of what C's as-if rule requires any code-transformations to preserve. Since you deleted your answer, I'm guessing you noticed that in the question now :)

– Peter Cordes
Nov 19 '18 at 23:50















Peter, if we assume that the C is compiled and linked such that the machine code is not optimized, do you know of any hardware nuances that could have somehow reordered the loading/storing of those values, such that the interrupt sees the second assigned, but not the first?

– leo1
Nov 23 '18 at 14:36





Peter, if we assume that the C is compiled and linked such that the machine code is not optimized, do you know of any hardware nuances that could have somehow reordered the loading/storing of those values, such that the interrupt sees the second assigned, but not the first?

– leo1
Nov 23 '18 at 14:36




1




1





@curiousguy: I assume he meant "basic blocks", or just "blocks"/chunks of asm, like the definition for a whole function. Note that Edwin's deleted his misleading answer after I replied (but not the comment), so I don't think we need to pick at it any farther.

– Peter Cordes
Nov 27 '18 at 20:19







@curiousguy: I assume he meant "basic blocks", or just "blocks"/chunks of asm, like the definition for a whole function. Note that Edwin's deleted his misleading answer after I replied (but not the comment), so I don't think we need to pick at it any farther.

– Peter Cordes
Nov 27 '18 at 20:19




















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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53383781%2fcan-two-sequential-assignment-statements-in-c-be-executed-on-hardware-out-of-ord%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

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

Npm cannot find a required file even through it is in the searched directory