   multithreading & volatile
  I have a hashmap thats being read and written by multiple threads, that is protected by critical sections.  Are critical sections enough, or do I also have to specify the instance of the hashmap to be volatile?eg. volatile CHashMap myHashmap;I mean, suppose you have code something like this:EnterCriticalSection(&csHashmap);void * a = myHashmap.get("key_string");LeaveCriticalSection(&csHashmap);and then at some later point, either in the same function, or several function calls later I have something like this:EnterCriticalSection(&csHashmap);void * b = myHashmap.get("key_string");LeaveCriticalSection(&csHashmap);isn''t it possible, if myHashmap isn''t declared volatile, that the compiler might optimize the code so that its just storing the variable in a register? 
  The critical section should be enough -- the point of them is to do exactly what you are describing. ;  What if the compiler is smart enough that decides to store the result for ''a'' in a register and then also return that register for ''b''?  If as soon as it exits the first critical section, another thread modifies the value stored in the hashmap and the first thread then enters the second critial section, it would return the wrong value for ''b'', yes?It is conceivable this would happen? ;  You need volatile.  The critical sections will ensure they don''t access the data at the same time.  Volatile ensures you don''t keep a copy of old data in a register as it might be changed by somewhere else. ;  If I need volatile, that leads to the next question... what about for STL containers?  I guess I should also be declaring them volatile when I am accessing them from separate thread also... but their methods aren''t declared to be volatile, yes?  So I can''t call them from a volatile object, therefore I can''t use STL containers in a multithreaded app, unless the all container access is confined to a single thread.Does crossing function call boundaries affect the answer in any way?  eg. suppose i had this code in a function f():EnterCriticalSection(&csHashmap);void * a = myHashmap.get("key_string");LeaveCriticalSection(&csHashmap);and then this code in a function g():EnterCriticalSection(&csHashmap);void * b = myHashmap.get("key_string");LeaveCriticalSection(&csHashmap);and then I called:f();g();would I still need to make the hashmap volatile?  Does inlining matter in this case? ;  I''d hope that because you''re going through a volatile variable it would treat any access to items inside as volatile.  To be honest though, I''ve never looked into volatile in C++, just C.  STL searches like get(string) are probably fine as it''s not looking at a variable directly, it''s searching for an entry... the compiler doesn''t have something to just directly cache away in a register. ;  There could be some kind of pathological case though, that might cause problems, yes?  Like if I was searching for the same constant string twice in a row, as in my example?  The compiler might recognize this and optimize away the whole second myHashmap.get("key_string") call.In theory one expects these pathological cases to be easy to detect, but after reading through More Effective C++, I realized there are some pathological cases in code that can be really well disguised.  I not sure that it is a good idea to trust the programmer to recognize these? ;  Searched with google again and eventually found this in a tip of the day:quote:VOLATILE CONTAINER OBJECTS Volatile objects are used in multithreaded applications and applications that map hardware devices into registers. Although you can declare an STL container object with the volatile qualifier, you can''t use any of its member functions safely. The problem is that STL containers don''t have any volatile member functions. Calling a nonvolatile member function on a volatile object is ill formed: volatile vector < int > vi; vi.push_back(1); /* trouble; push_back isn''t volatile*/ Because of the attempt to call a nonvolatile member function, some compilers compile this code with warnings; others issue an error message. Calling a nonvolatile member function from a volatile object yields unpredictable results, because the state of the object might be changed by another thread in between.  Is there a way to get around this? No, there isn''t. By design, STL containers don''t include volatile member functions because of the performance penalty and implementation complexity associated with volatile semantics.    ----------------------------------------------    Danny Kalev is a system analyst and software engineer with more than ten years of experience, specializing in C++ and object-oriented analysis and design. He is a member of the ANSI C++ standardization committee and the author of The ANSI/ISO C++ Professional Programmer''s Handbook (Que,1999). Original link here:http://www.mulvey.ws/c++tips/c++tips.txtThis seems to be saying that the STL isn''t really fully thread safe because you can''t declare the containers as volatile, which would be necessary to prevent the certain class of bugs I''m worrying about.Am i missing something here? ;quote:Original post by Z01  This seems to be saying that the STL isn''t really fully thread safe because you can''t declare the containers as volatile, which would be necessary to prevent the certain class of bugs I''m worrying about.That does seem to be what it''s saying, yes.  As I''ve said, I don''t know the full semantics of volatile with C++.  Perhaps someone with better C++ knowledge can answer you.  On the other hand, I think you''ve found a flaw in using STL that all the "STL is perfection" people around here never knew.  Definately something to keep in mind when designing for multithreading.;quote:On the other hand, I think you've found a flaw in using STL that all the "STL is perfection" people around here never knew. Definately something to keep in mind when designing for multithreading.And if it did, you'd be able to complain that for the large majority of time STL containers are slower because they are safe for multithreading. In a single threaded app you'd spend far more time entering and leaving the critical section than actually working on the data structure. And that would rile up MORE of GameDev than the "STL is perfection" crowd, because the nano-optimization crowd is far more vehement and noisy.Besides, C++ itself knows nothing of multithreading for the most part, why should the standard library?See also:Google Groups Thread: Is it possible to make containers volatile?Volatile-Correctness or How to Have Your Compiler Detect Race Conditions for You [edited by - antareus on February 13, 2004 11:40:14 PM]