tags:

views:

44

answers:

2

More specifically, I have (simplified) the following:

union foo
    {
    volatile int bits;
    char data[sizeof(int)*CHAR_BIT];
    }

If I never access the first sizeof(int) items of data, can i rely on bits working as expected?

+1  A: 

Basically marking one of the field of the structure as volatile is correct. But you have to remember what volatile keyword does. It tells the compiler to not optimize access to a variable. Value is always read from memory, not from its copy in register.

As you write in comment, you are trying to make memory allocation thread safe. Unfortunately volatile doesn't guarantee that you can access it from multiple threads. If you are using 8bit CPU, access to integer value is not atomic operation so your program will not work correctly.

mack369
I'm also using atomic memory access builtins (gcc's `__sync_*stuff*` specifically), which should be the other half of making access threadsafe (right?). (I also assume the CPU has a large enough word size that `int` will be one word.)
David X
I haven't used this way of making memory access atomic. I prefer to do it manually - it is more portable way.
mack369
@mack369, any reference/tutorial on manual atomic memory access?
David X
it is similar to accessing a variable from ISR.See http://stackoverflow.com/questions/3297302/access-to-two-variables-safely-when-an-interrupt-might-occur-between-them/Basically you need to lock one thread when the second one is using the common memory. You can use one volatile uint8_t variable (access is always atomic) and check it before you access the common structure, wait if 1. If 0, first set its value to one and then access the memory. It may not by enough depending on what system you use.The most secure way is to disable interrupts(thread switching) before every check of the variable.
mack369
A: 

volatile is in no way useful for implementing locks. I'm not speaking just theoretically; it will fail and you will have race conditions, even on single-cpu/single-core environments. The only way to make real atomic locking primitives is to write assembly using the cpu's locking primitives (for x86, the lock prefix).

Actually, there may be a way to get by with just volatile but the only such locking mechanism I know takes O(n) space where n is the number of threads, which makes it pretty useless if the number of possible threads is not known in advance.

R..
Where did i say that i was writing locks? I was trying to write a lockless memory allocator. (I gave up and added locks, but not in any manner to which this question is relevant.)
David X
Sorry. Out of curiosity what was your idea for a lockless implementation?
R..
I was trying to keep the memory cache in a consistant state throughout the malloc/free operations. Doing so with the individual blocks is obviously trivial, but i couldnt figure out how to keep the free list sane. I might come back to it if i get any new ideas.
David X