This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Atomic operations



I am wondering how I can determine which operations I can assume to be atomic.  I am unsure of the role the compiler (TI 7.4.5), architecture (C6657), and OS (SYS/BIOS).  Assuming I am working on a C++ project, when would I use constructs of the C++ language vs instrinsics vs OS constructs.

A simple example might be assignment to an int.

class Foo

{

  public:

    void far();

    int myX;

};

void Foo::bar()
{

    myX = 3;  // how can I make this atomic?
}

I believe I understand how _disable_interrupts and _restore_interrupts intrinsics could be used for arbitrary code blocks, but are there occasions when these are not necessary, or some other mechanism may be a better option?  Which documents might help me determine this?

  • Hello!

    1970135 said:

    I believe I understand how _disable_interrupts and _restore_interrupts intrinsics could be used for arbitrary code blocks

    At least UG of 7.4 (spru187U, p.225) doesn't offer nothing but  _disable_interrupts and _restore_interrupts intrinsics. Why would not you to use it?

    Regards,

    Igor

  • Thank you for your reply Mr. Gorbachev.

    The reason I would like to understand my options beyond _disable_interrupts and _restore_interrupts is for efficiency sake.

    An analogy of my thinking might be double vs float.  In theory, most computations that you can do with a float you can also do with a double.  However for some types of computations, float will yield you an acceptable answer, and for some applications, there might be efficiency (time or space) considersations that make float a more appealing choice than a double.

    An example might be if the architecture guarantees that writing a 32-bit value in memory is an atomic action.  In that case, if the problem at hand dealt with assigning a value to an int32_t, it might be sufficient to do a C++ assignement, and wrapping said assignment with _disable_interrupts/_restore_interrupts may be unecessary.

    I realize that this is a compiler forum, and some of what I ask may be beyond the scope of this forum (because it deals with architecture and OS).  In such cases, if someone could advice me the proper place to seek information, that would be appreciated.

    For my particular application, portability is not a concern.

  • Hi 1970135.

    1970135 said:

    An example might be if the architecture guarantees that writing a 32-bit value in memory is an atomic action.  In that case, if the problem at hand dealt with assigning a value to an int32_t, it might be sufficient to do a C++ assignement, and wrapping said assignment with _disable_interrupts/_restore_interrupts may be unecessary.

    Well. But if you have a background task and at least one ISR with some shared memory resource, then architecture does not guarantee something and in this case it is necessary to take care about access atomicity to this memory resource by yourself.

    Regards,

    Igor 

  • 1970135 said:
    The reason I would like to understand my options beyond _disable_interrupts and _restore_interrupts is for efficiency sake.

    You aren't going to improve much on those intrinsics.  In most cases, _disable_interrupts takes two instructions and _restore_interrupts takes one.

    Thanks and regards,

    -George

  • Igor Gorbachev said:

    then architecture does not guarantee something

    How do I know the architecture does or does not guarantee something?

    For instance, if I was programming on an Intel and I could look up in e.g. their  "The Intel® 64 and IA-32 Architectures Software Developer’s Manual" Volume 3A, and learn that:

    8.1.1 Guaranteed Atomic Operations

    The Intel486 processor (and newer processors since) guarantees that the following   basic memory operations will always be carried out atomically:

    • Reading or writing a byte
    • Reading or writing a word aligned on a 16-bit boundary
    • Reading or writing a doubleword aligned on a 32-bit boundary
    • ...

    Does TI have such a guide?  I see no such advice in the compiler guide (spru187u) nor the instruction set architecture guide (sprugh7).

    Are there no operations which can be considered atomic?  Even reading an aligned word or byte?

    I have seen some related questions elsewhere in e2e, but no answer with the info I need; e.g.

    http://e2e.ti.com/support/embedded/bios/f/355/p/151858/549541.aspx#549541

    suggests a C level assignment to int is "probably" atomic, but I don't feel good about relying on things to probably happen.  Are there conditions when I am guaranteed that it is atomic?

    If not, then perhaps I will have to use _disable_interrupts(), etc.  At least until the compiler supports C++11's <atomic> functionality.

  • Hi 1970135.

    1970135 said:

    Are there conditions when I am guaranteed that it is atomic?

    Unfortunately I din't find some useful info for your case still. I agree that when the portability of the code doesn't matter then it makes sense to think about using the atomicity of some operations provided by the architecture. But in my opinion, anyway if you wish to have a full guarantee, then there are only two ways to avoid problems:

    - do not use the shared variables;

    - disable interrupts when modifying these variables in a background task, ie to provide atomicity of these  modifications.

    Regards,

    Igor

  • Thanks everyone for your help.

    In case you are interested, I had a follow up thread in the C6000 Multicore DSP forum:

    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/296965.aspx

     

  • Thanks 1970135 for very useful link.

    Good luck,

    Igor