473,385 Members | 1,645 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Volatile classes

I am using placement new to locate a shared data structure at a
particular location in shared memory. The problem is that when I access
the data on one of the two processors sharing it, I don't get the same
values seen by the other processor (which uses a cache-less access
method, unlike what follows). Here's a reduced example:

struct SharedData
{
enum Item { A=0, B=1 };

// Note volatile:
int Get( Item i ) const volatile { return data_[ i ]; }
// ...
private:
int data_[ 2 ];
};

void Foo()
{
void *const addr = reinterpret_cast<void*>( 0x8000 );
volatile SharedData *const data = new( addr ) SharedData;

const int a1 = data->Get( SharedData::A );
const int a2 = data->Get( SharedData::A );
// ...
}

The problem is that a1 and a2 may not be the same because the second
processor may modify the value - a classic case for the volatile
qualifier. The C way to handle this would be something like:

volatile int* const a = reinterpret_cast<volatile int*>( 0x8000 );
volatile int* const b = reinterpret_cast<volatile int*>( 0x8004 );

I thought, however, that applying volatile to the pointer-type in Foo()
and the appropriate member functions in SharedData would do basically
the same thing - namely, force all the data members of SharedData to be
volatile. Am I mistaken?

Cheers! --M

Nov 30 '05 #1
9 3064

mlimber wrote:
I am using placement new to locate a shared data structure at a
particular location in shared memory. The problem is that when I access
the data on one of the two processors sharing it, I don't get the same
values seen by the other processor (which uses a cache-less access
method, unlike what follows). Here's a reduced example:

struct SharedData
{
enum Item { A=0, B=1 };

// Note volatile:
int Get( Item i ) const volatile { return data_[ i ]; }
// ...
private:
int data_[ 2 ];
};

void Foo()
{
void *const addr = reinterpret_cast<void*>( 0x8000 );
volatile SharedData *const data = new( addr ) SharedData;

const int a1 = data->Get( SharedData::A );
const int a2 = data->Get( SharedData::A );
// ...
}

The problem is that a1 and a2 may not be the same because the second
processor may modify the value - a classic case for the volatile
qualifier. The C way to handle this would be something like:

volatile int* const a = reinterpret_cast<volatile int*>( 0x8000 );
volatile int* const b = reinterpret_cast<volatile int*>( 0x8004 );

I thought, however, that applying volatile to the pointer-type in Foo()
and the appropriate member functions in SharedData would do basically
the same thing - namely, force all the data members of SharedData to be
volatile. Am I mistaken?


i don't have the standard at hand, but according to the following link,
a fantastic article about this topic by alexandrescu, it does.

http://www.cuj.com/documents/s=7998/...p1902alexandr/

to me this looks like either your memory is modified by other effects
or this is a compiler bug.

-- peter

Nov 30 '05 #2
mlimber wrote:
....
The problem is that a1 and a2 may not be the same because the second
processor may modify the value - a classic case for the volatile
qualifier. The C way to handle this would be something like:

volatile int* const a = reinterpret_cast<volatile int*>( 0x8000 );
volatile int* const b = reinterpret_cast<volatile int*>( 0x8004 );

I thought, however, that applying volatile to the pointer-type in Foo()
and the appropriate member functions in SharedData would do basically
the same thing - namely, force all the data members of SharedData to be
volatile. Am I mistaken?


What do you think volatile means ?

I don't understand what the "problem" is.
Nov 30 '05 #3
Gianni Mariani wrote:
mlimber wrote:
...
The problem is that a1 and a2 may not be the same because the second
processor may modify the value - a classic case for the volatile
qualifier. The C way to handle this would be something like:

volatile int* const a = reinterpret_cast<volatile int*>( 0x8000 );
volatile int* const b = reinterpret_cast<volatile int*>( 0x8004 );

I thought, however, that applying volatile to the pointer-type in Foo()
and the appropriate member functions in SharedData would do basically
the same thing - namely, force all the data members of SharedData to be
volatile. Am I mistaken?
What do you think volatile means ?


It is compiler specific, but it means that the compiler should not do
any fancy optimizations to the data at hand. That means, for instance,
not caching a variable in a register even though the code doesn't
appear to change it. By using volatile, the programmer is indicating
that the value could change due to something outside the program (e.g.
another thread or process or a hardware device).
I don't understand what the "problem" is.


It appears that my volatile data is not read fresh at each access.
Consequently, one processor incorrectly reads 0 while the other
correctly reads 1. (Correctness is determined by what the memory
actually holds.)

Cheers! --M

Nov 30 '05 #4
mlimber wrote:
I am using placement new to locate a shared data structure at a
particular location in shared memory. The problem is that when I access
the data on one of the two processors sharing it, I don't get the same
values seen by the other processor (which uses a cache-less access
method, unlike what follows).
There is nothing in the C++ language that can help you. The C++
standard doesn't require any support for multiprocessing.
The problem is that a1 and a2 may not be the same because the second
processor may modify the value - a classic case for the volatile
qualifier.
That is not what volatile is intended for.

The intent of volatile is to suppress the /language implementation's/
caching optimizations. Not those of the entire data processor. Caching
optimizations are deviations from the abstract machine, whereby objects
that are modified are not actually updated at the next sequence point.

There is always /some/ caching going on. If you load a value into
processor, and do something with it, then compute a new value, for a
brief time, the computed value is out of sync with the storage object
that it's destined for.

The volatile qualifier comes from ANSI C. According to ANSI C, an
asynchronous signal handler may write a value to a static object of
type volatile sig_atomic_t. The idea is that mainline code which checks
that value will see the modification, rather than keep referring to a
cached copy. This example doesn't even involve multiple threads, never
mind processors. You see, the caching optimizations performed by
compilers can affect the interaction between single-threaded code and
its asynchronous interrupts, or threads that are scheduled on just one
processor that has a single, coherent view of its memory.

Other than making this case work (volatile sig_atomic_t and signal
handler), a compiler can ignore volatile (provided that it emits a
diagnostic about any diagnosable rule violation related to the use of
the keyword).

At best, if your compiler properly supports the spirit of the intended
meaning of volatile, its use will ensure that when you store to the
object, the value is actually written to memory no later than the next
sequence point, and when you read from the object, the latest value is
retrieved.

If you need further synchronization at the hardware level, you have to
insert the machine instructions yourself: memory barriers, cache
flushes, whatever.
I thought, however, that applying volatile to the pointer-type in Foo()
and the appropriate member functions in SharedData would do basically
the same thing - namely, force all the data members of SharedData to be
volatile. Am I mistaken?


Nope. The qualifier on a member function is essentially inherited by
the this pointer. If the function is const, the this pointer refers to
a const-qualified object, etc. This part is right.

Nov 30 '05 #5
mlimber wrote:
Gianni Mariani wrote:
What do you think volatile means ?


It is compiler specific, but it means that the compiler should not do
any fancy optimizations to the data at hand.


Multiprocessor coherency problems are not caused by optimizations that
the compiler does.

Nov 30 '05 #6
mlimber wrote:
It is compiler specific, but it means that the compiler should not do
any fancy optimizations to the data at hand. That means, for instance,
not caching a variable in a register even though the code doesn't
appear to change it. By using volatile, the programmer is indicating
that the value could change due to something outside the program (e.g.
another thread or process or a hardware device).
I don't understand what the "problem" is.


It appears that my volatile data is not read fresh at each access.
Consequently, one processor incorrectly reads 0 while the other
correctly reads 1. (Correctness is determined by what the memory
actually holds.)


Have you tried adding volatile to the actual array rather than the
function call?

Nov 30 '05 #7
mlimber wrote:
Gianni Mariani wrote:
I don't understand what the "problem" is.

It appears that my volatile data is not read fresh at each access.
Consequently, one processor incorrectly reads 0 while the other
correctly reads 1. (Correctness is determined by what the memory
actually holds.)


OK - This one is easy to check to see - look at the compiled
instructions and see if the generated code is actually performing the reads.

If I read it correctly, then yes, the _data array should be volatile in
this case.

Which compiler ?
Dec 1 '05 #8
Gianni Mariani wrote:
mlimber wrote:
Gianni Mariani wrote:

I don't understand what the "problem" is.

It appears that my volatile data is not read fresh at each access.
Consequently, one processor incorrectly reads 0 while the other
correctly reads 1. (Correctness is determined by what the memory
actually holds.)


OK - This one is easy to check to see - look at the compiled
instructions and see if the generated code is actually performing the reads.

If I read it correctly, then yes, the _data array should be volatile in
this case.

Which compiler ?


Texas Instruments 5.1.0, which I think uses the EDG front-end.

More to come when I try the suggestions given here...

Cheers! --M

Dec 1 '05 #9
Gianni Mariani wrote:
mlimber wrote:
Gianni Mariani wrote:

I don't understand what the "problem" is.

It appears that my volatile data is not read fresh at each access.
Consequently, one processor incorrectly reads 0 while the other
correctly reads 1. (Correctness is determined by what the memory
actually holds.)


OK - This one is easy to check to see - look at the compiled
instructions and see if the generated code is actually performing the reads.

If I read it correctly, then yes, the _data array should be volatile in
this case.

Which compiler ?


Upon further testing, the compiler seems to be doing its job correctly
and my code works as expected if I disable the user-configurable
hardware cache. Since I want to use the cache in the production code,
however, I'll need to look into the platform-specific details of making
things work with the cache enabled.

Cheers! --M

Dec 1 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: spammy | last post by:
hi all, im trying to establish whether i have a race condition or critical section in the following. i have a dataaccess class that continually retireves a table from a sqlserver (which may be...
8
by: Tim Rentsch | last post by:
Here's another question related to 'volatile'. Consider the following: int x; void foo(){ int y; y = (volatile int) x;
5
by: ben | last post by:
Hello All, I am trying to make sense of a bit of syntax, is there a guru out there that can clear this up for me. I have a buffer declared as static volatile u8 buffer; and I have a...
14
by: google-newsgroups | last post by:
Hello, even (or because?) reading the standard (ISO/IEC 9899/1999) I do not understand some issues with volatile. The background is embedded programming where data is exchanged between main...
2
by: Nick | last post by:
I am right in thinking that if I have a class that can be accessed by more than one thread in my application then I should mark *all* instance variables within that class with the volatile keyword....
6
by: titan nyquist | last post by:
Can you make volatile structures in C#? I have a static class, to have "global" variables. This allows the whole program to see them. I make them "volatile" to avoid multi- threading accessing...
94
by: Samuel R. Neff | last post by:
When is it appropriate to use "volatile" keyword? The docs simply state: " The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock...
3
by: Rakesh Kumar | last post by:
Hi - I am actually trying to get my feet in multi-threaded C++ programming. While I am aware that the C++ standard does not talk about threads (at least, for now - in C++03) - my question is more...
2
by: sumsin | last post by:
are 'mutable' and 'volatile' a Storage Classes in C++?
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.