Monday, July 5, 2010

Volatile: You are forcing your compier not to be smart

http://www.drdobbs.com/article/printableArticle.jhtml;jsessionid=VK14LV3GMGCD3QE1GHOSKH4ATMY32JVN?articleId=184403766&dept_url=/

class Gadget{
public:
void Wait() {
while (!flag_){
Sleep(1000); // sleeps for 1000 milliseconds
}
}
void Wakeup() {
flag_ = true;
}
private:
bool flag_;
};
Your compiler is so smart that he will find that nobody in this class could update flag_, so dont read flag_ from memory again and again, put it in register.
Oh shit!!!!!
It hang when I asked for wait..

Solution is to use 'volatile bool flag_'. So now if you will share this gadget object between multiple threads, it will hurt you ...

2) Other than optimization volatile works as const, even const cast works on it.


Summary

When writing multithreaded programs, you can use volatile to your advantage. You must stick to the following rules:

* Define all shared objects as volatile.
* Don't use volatile directly with primitive types.
* When defining shared classes, use volatile member functions to express thread safety.

If you do this, and if you use the simple generic component LockingPtr, you can write thread-safe code and worry much less about race conditions, because the compiler will worry for you and will diligently point out the spots where you are wrong.

A couple of projects I've been involved with use volatile and LockingPtr to great effect. The code is clean and understandable. I recall a couple of deadlocks, but I prefer deadlocks to race conditions because they are so much easier to debug. There were virtually no problems related to race conditions. But then you never know.

Mutex vs. Semaphore

Mutex vs. Semaphore, what is the difference?
The Toilet Example (c) Copyright 2005, Niclas Winquist ;)

Mutex:

Is a key to a toilet. One person can have the key - occupy the toilet - at the time. When finished, the person gives (frees) the key to the next person in the queue.

Officially: "Mutexes are typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section."
Ref: Symbian Developer Library

(A mutex is really a semaphore with value 1.)

Semaphore:

Is the number of free identical toilet keys. Example, say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue.

Officially: "A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore)."
Ref: Symbian Developer Library

Does it mean binary semaphore are mutexes?
Ideally yes. but binary semaphore is something more to it...

The mutex is similar to the principles of the binary semaphore with one significant difference:
the principle of ownership. Ownership is the simple concept that when a task locks (acquires) a mutex only it can unlock (release) it. If a task tries to unlock a mutex it hasn’t locked (thus doesn’t own) then an error condition is encountered and, most importantly, the mutex is not unlocked. If the mutual exclusion object doesn't have ownership then, irrelevant of what it is called, it is not a mutex.

So it means that in case of  binary semaphore toilet can be signaled to open by the owner.


Please comment if my understanding is wrong. I will update the post.-Rhaul

Friday, July 2, 2010

C++: Mutable vs. constness

C++'s mutable and conceptual constness
http://www.highprogrammer.com/alan/rants/mutable.html

Most of time mutable is described as a type which breeches the constness of the object. But it is actually to help constness for many purposes. eg.

1) Reference count of a the objects users.
2) Use it in the for storing the mutex object in the object so that you can apply lock when reading something from const object.
3) You can use it for a lazy evaluation of an expression object..
i.e.
class PI{
public:
pi():pi(0.0), evaluated(false) {}
double getValue(){
if(evaluated) return _pi;
for(int i=0; i< 1000000000000; i++){
//....
}
evaluated=true;
return _pi;
}
private:
mutable double _pi;
mutable bool evaluated;
};

In that case you can create and pass object of PI to any function as const, and it will be evaluated on use only.
How mutable will benefit you is design of the function which takes PI as input.
void PrintCircleAreaWithRadius(double radius, const PI& pi); //If _pi in PI class is not declared as mutable compiler will not allow you ..