Do I need a fence or barrier or something when mutex locks / unlocks are deeply hidden in function calls?

I recently learned that compilers optimize your code by rearranging instructions, and that this can be controlled with barriers.

IIRC, locking the mutex makes the barrier, and unlocking the mutex also makes the barrier so that the code inside the critical section does not exit.

Thus, pthread_mutex_lock and pthread_mutex_unlock must implicitly be these β€œbarriers”. What if I have a class like this that wraps my mutexes?

class IMutex { public: virtual void lock() = 0; virtual void unlock() = 0; }; 

It seems to me that the compiler does not know that I call pthread_mutex_lock () inside lock () and pthread_mutex_unlock () inside unlock (), because it is all virtual.

Will this lead to errors? Do I need to manually specify barriers in some way?

+6
source share
1 answer

Reordering instructions are performed at different levels. The compiler is most obvious, and the processor (which is on the go) is less obvious. However, the synchronization functions almost always constitute a fence that prevents reordering of instructions before and after the fence.

So, if your virtual lock calls pthread_mutex_*() , then your virtual functions contain a fence.

So the short answer is: No, this will not lead to errors.

There is also the volatile keyword, which, depending on the platform, can also create a fence. However, using volatile keywords makes it a lot harder to detect these barriers, because every time you use a function or variable that is volatile, you enter a fence. Therefore, the tip is that you use the platform synchronization features.

The only time you need to know about the fence is when you are not using concurrency objects to perform synchronization (for example, instead of bool instead of mutex).

+6
source

All Articles