Solved

Is a simple POD assignment atomic?

Posted on 2006-11-16
5
761 Views
Last Modified: 2012-06-27
Is a simple POD assignment an atomic operation?

What about if the POD is a struct data member?


0
Comment
Question by:chsalvia
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
5 Comments
 
LVL 16

Assisted Solution

by:PaulCaswell
PaulCaswell earned 75 total points
ID: 17955964
What do you mean by a POD assignment?

C was never designed for a multithreaded environment. As a result, very few mechanisms are atomic.

Direct assignments to basic typed variables are probably atomic. Floats may not be but integers/characters should be.

Structure assignments will almost certainly not be.

Increment/decrement/etc functions will almost certainly not be.

You are safer to assume not in all cases.

Paul
0
 

Author Comment

by:chsalvia
ID: 17957025
>>What do you mean by a POD assignment?

Just assignment of basic data types.  Basically any data type that would fit in a single register, like int, char, or a pointer.

>> You are safer to assume not in all cases.

That seems reasonable.  I was wondering if POD assignment was naturally atomic, because the gcc library declares an "atomic assign" macro, which doesn't seem to actually do anything special.  It just does a normal assignment

#define atomic_set(v,i)            (((v)->counter) = (i))

But you need to use a special atomic_t struct which contains a volatile int.

typedef struct { volatile int counter; } atomic_t;

This macro doesn't look like it does anything special.  It just sets the value of the volatile int to any value using a normal = operator.  I was wondering if this works on all POD data types, or if there is some reason that setting a volatile int in a struct would be atomic, whereas setting a normal auto int would not.

0
 
LVL 6

Expert Comment

by:GnarOlak
ID: 17957413
As a test I wrote this test C program:

void f(void);
int main()
{
        f();
        return 0;
}

void f()
{
        int x = 11;
}

I then compiled it into INTEL assembly using the -S gcc switch.  This is what the function f compiles to:

.globl _f
        .def    _f;     .scl    2;      .type   32;     .endef
_f:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $4, %esp
        movl    $11, -4(%ebp)
        leave
        ret
        .def    _f;     .scl    3;      .type   32;     .endef

The first two lines adjust the stack frame and the subl move the stack pointer to make room for the variable x.  The assignment of the 11 to x happens in a single machine instruction on this particular platform.  I can't imagine something being any more atomic than that.
0
 
LVL 22

Assisted Solution

by:grg99
grg99 earned 75 total points
ID: 17959749
You can't depend on assignments being atomic.

 They probably are for short datatypes that fit into one register.

 But for instance if you have a "long int", it often has to span two registers and it takes two instructions to load and store it.

For example if you try to peek at the "long int" tick count at address $40:$6C on a DOS PC, you'll USUALLY get the right number, but sometimes you'll get an old low word and a new incremented high word, or vice versa.  It can really muck up your real-time program when time jumps forward or backward by an hour!



0
 
LVL 6

Accepted Solution

by:
GnarOlak earned 100 total points
ID: 17960013
I adjusted my test program to be:

double x = 11.11;

The result is that it takes two instructions to do that:

        fldl    LC0
        fstpl   -8(%ebp)

So the answer seems to be "Some might be.  Some might not be."  And this is only applicable for assignment of hard coded values.  Assignment of a variable to another variable would almost certainly not be atomic.

Modifying f() again to:

void f()
{
        int y;
        int x = 11;
        y = x;
}

And compiling yeilds:

        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp

        movl    $11, -8(%ebp)

        movl    -8(%ebp), %eax
        movl    %eax, -4(%ebp)

        leave
        ret

One instruction to move the value of x into the eax register and and one instruction to move the value in the eax register to the location on the stack allocated for y.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question