Solved

Is a simple POD assignment atomic?

Posted on 2006-11-16
5
744 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
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

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
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 for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

760 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now